스프링(Spring) #2

jjinny_0609·2023년 3월 28일
0

Spring

목록 보기
2/6

MVC(Model-View-Controller)

대부분의 서블릿 기반 프레임워크들이 사용하는 방식
데이터와 처리, 화면을 분리하는 방식
웹에서는 Model2 방식으로 표현

MVC 중에서 모델을 사용해야 하는 이유

접근제어자, 메모리 사용량의 차이

데이터 관리: Model은 애플리케이션에서 사용되는 데이터를 관리하고, 데이터에 대한 적절한 유효성 검사 및 처리를 수행합니다. 이를 통해 데이터 일관성과 안정성을 보장할 수 있습니다.

비즈니스 로직 처리: Model은 비즈니스 로직을 처리하고 데이터 처리를 위한 알고리즘을 구현합니다. 이를 통해 데이터 처리에 대한 일관성과 안정성을 유지할 수 있으며, 애플리케이션의 기능을 확장하기 쉽습니다.

뷰와 분리: Model은 뷰와 분리되어 있기 때문에, 데이터의 변경이나 비즈니스 로직의 변경에 대해 뷰와 컨트롤러의 변경이 필요하지 않습니다. 이를 통해 애플리케이션의 유지보수성과 확장성을 높일 수 있습니다.

재사용성: Model은 다른 컨트롤러와 뷰에서도 사용할 수 있습니다. 이를 통해 코드의 재사용성이 높아지며, 코드의 중복을 피할 수 있습니다.

따라서 Model을 사용하는 것은 애플리케이션의 유지보수성, 확장성, 일관성, 안정성 등을 보장하는데 큰 역할을 합니다.


스프링 MVC의 기본 흐름

스프링 MVC의 기본 흐름은 다음과 같습니다.

1.클라이언트의 요청: 클라이언트가 HTTP 요청을 보냅니다.

  1. DispatcherServlet: 요청이 DispatcherServlet에 도착합니다. DispatcherServlet은 요청을 처리하기 위해 HandlerMapping을 사용하여 요청에 대한 적절한 컨트롤러를 찾습니다.

  2. 컨트롤러: 적절한 컨트롤러가 선택되면, 해당 컨트롤러는 요청을 처리합니다. 컨트롤러는 모델을 생성하고, 모델에 데이터를 추가합니다.

  3. ViewResolver: 컨트롤러는 뷰 이름을 반환합니다. 이 뷰 이름은 ViewResolver를 사용하여 실제 뷰 객체와 매핑됩니다.

  4. View: 뷰는 모델 데이터를 사용하여 응답을 생성합니다. 뷰는 보통 JSP, Thymeleaf, Freemarker 등의 템플릿 엔진을 사용하여 HTML을 생성합니다.

  5. 응답: 뷰가 생성한 응답은 DispatcherServlet에 반환됩니다. DispatcherServlet은 응답을 클라이언트에게 보내기 전에 필터 체인을 통해 추가적인 처리를 수행합니다.

  6. 클라이언트 응답: DispatcherServlet이 클라이언트에게 응답을 반환합니다.

이러한 기본적인 흐름을 따르면서, 스프링 MVC는 다양한 기능과 설정을 제공하여 유연한 웹 애플리케이션 개발을 지원합니다.


Controller

  • HttpServletRequest, HttpServletResponse를 거의 사용할 필요 없이 필요
    한 기능 구현
  • 다양한 타입의 파라미터 처리, 다양한 타입의 리턴 타입 사용 가능
  • GET 방식, POST 방식 등 전송 방식에 대한 처리를 어노테이션으로 처리
    가능
  • 상속/인터페이스 방식 대신에 어노테이션만으로도 필요한 설정 가능

어노테이션(@)

스프링 프레임워크에서 사용되는 어노테이션은 크게 세 가지로 구분할 수 있습니다.

  • 스프링 프레임워크 어노테이션: 스프링 프레임워크에서 기본적으로 제공되는 어노테이션입니다. 대표적으로 @Autowired, @Component, @Controller, @Service, @Repository 등이 있습니다.

  • 자바 표준 어노테이션: 자바에서 제공하는 어노테이션으로, 스프링 프레임워크에서도 사용할 수 있습니다. 대표적으로 @Override, @Deprecated, @SuppressWarnings 등이 있습니다.

  • JPA 어노테이션: JPA(Java Persistence API)에서 사용하는 어노테이션입니다. 스프링에서는 데이터베이스 연동을 위해 JPA를 사용하는 경우가 많기 때문에, 이러한 어노테이션을 함께 사용합니다. 대표적으로 @Entity, @Id, @GeneratedValue, @Column 등이 있습니다.

이러한 어노테이션을 사용하여 스프링 프레임워크에서는 빠르고 쉽게 빈 객체를 생성하고 의존성을 관리할 수 있습니다. 이 외에도 스프링부트에서는 다양한 어노테이션을 제공하여 개발자의 생산성을 높이는데 기여하고 있습니다.


@Controller, @RequestMapping

• @Controller – 해당 클래스의 인스턴스를 스프링의 빈으로 등록하고 컨트롤러로 사용

<component-scan> 과 같이 활용

• @RequestMapping – 특정한 URI에 대한 처리를 해당 컨트롤러나 메서드에서 처리

package org.hj.controller

@Controller
@RuquestMapping(value ="sample")
public class A{	// 클래스 - controller역할을 하는 클래스
		
		@RuquestMapping(value ="aaa", method = RequestMethod.Get)
		public String home(Locale locale, Model model){
			return "home";	// /WEB-INF/views/home.jsp
		}
}

@Controller
public class A{	// 클래스 - controller역할을 하는 클래스
		
		@RuquestMapping(value ="sample/aaa", method = RequestMethod.Get)
		public String home(Locale locale, Model model){
			return "home";	// /WEB-INF/views/home.jsp
		}
}

RequestMapping의 변화

• 스프링 4.3 전까지는 @RequestMapping( method =‘get’) 방식으로 사용
• 스프링 4.3이후에는 @GetMapping, @PostMapping등으로 간단히 표현 가능

@Controller
public class A{	// 클래스 - controller역할을 하는 클래스
		// @RuquestMapping(value ="sample/aaa", method = RequestMethod.POST)
		@POSTMapping(value="aaa")
		public String home(Locale locale, Model model){
			return "home";	// /WEB-INF/views/home.jsp
		}
}

컨트롤러의 파라미터 수집

  • 스프링 MVC의 컨트롤러는 메서드의 파라미터를 자동 으로 수집, 변환하는 편리한 기능을 제공
  • Java Beans 규칙에 맞게 작성되어야 한다.
    • 생성자가 없거나 빈 생성자
    • 올바른 규칙으로 만들어진 Getter/Setter

메서드를 통해 간접적으로 불러와 사용

리스트/배열을 사용

자바 배열의 종류

  • 고정배별
    int[] score = new int[5];
    단점 : 메모리의 낭비, 데이터를 추가하려면 값을 변경해주어야한다.

  • 가변배열
    defalut로 10칸을 만들어준다.
    장점 : 메모리 낭비를 줄여줌. (3칸을 사용하면 나머지는 버려준다)
    새로운 값이 들어오더라도 배열의 크기를 알아서 바꿔주기 때문에 편함.
    단점 : 자동정렬이기 때문에 검색에 이용하기엔 적합하지 않다.

ArrayList<Integer> score = new ArrayList<Integer>

Model이라는 데이터전달자

• Model 객체는 JSP에 컨트롤러에서 생성된 데이터를 담아서 전달하는 역할을 하는 존재
• 모델 2 방식에서 사용하는 equest.setAttribute( )와 유사한 역할

[클래스를 이용해 전달]

@ModelAttribute

• 컨트롤러에서 메서드의 파라미터는 기본자료형을 제외한 객체형 타입은 다시 화면으로 전달
• @ModelAttribute는 명시적으로 화면에 전달되도록 지정

[어노테이션을 이용해 전달]

SampleDTO에 대한 정보는 위의 스크린샷에 선언해둔걸 참고.

RedirectAttribute

• 화면에 한번만 전달되는 파라미터를 처리하는 용도
• 내부적으로 HttpSession객체에 담아서 한번만 사용되고, 폐기

  • RedirectAttributes를 이용한 Redirect: RedirectAttributes 객체를 이용하여 Redirect할 URL과 함께 필요한 데이터를 전달합니다. 이후 스프링은 해당 URL로 Redirect합니다. 이 방법은 ModelAndView 객체를 반환하는 방법보다 간결하고 편리합니다.
@RequestMapping(value = "/redirect", method = RequestMethod.POST)
public String redirectExample(@ModelAttribute("exampleForm") ExampleForm exampleForm, RedirectAttributes redirectAttributes) {
    redirectAttributes.addFlashAttribute("message", "Redirect Example");
    return "redirect:/redirected";
}

위의 예시 코드에서는 /redirect 경로에 POST 요청이 들어오면, redirectAttributes 객체를 이용하여 "message"라는 이름의 속성을 추가합니다. 이후 "redirect:/redirected" URL로 Redirect합니다. Redirect 된 이후, /redirected 경로에 대한 처리가 이루어지며, 해당 경로에서는 edirectAttributes 객체를 이용하여 추가한 속성을 사용할 수 있습니다.

Redirect

서버가 클라이언트에게 새로운 URL로 요청을 재전송하도록 요청을 만들어 전송하는 것을 의미합니다. Redirect는 사용자가 다른 페이지로 이동할 때 주로 사용되며, 주로 POST 요청을 받았을 때 다른 페이지로 Redirect 하는 경우가 많습니다.

스프링에서 Redirect를 사용하기 위해서는 다음과 같은 방법을 사용합니다.

  • ModelAndView 객체를 이용한 Redirect: ModelAndView 객체를 생성하고 setViewName() 메서드를 사용하여 Redirect할 URL을 설정한 후, ModelAndView 객체를 반환합니다. 이후 스프링은 해당 URL로 Redirect합니다.
@RequestMapping(value = "/redirect", method = RequestMethod.POST)
public ModelAndView redirectExample(@ModelAttribute("exampleForm") ExampleForm exampleForm, RedirectAttributes redirectAttributes) {
    redirectAttributes.addFlashAttribute("message", "Redirect Example");
    ModelAndView mav = new ModelAndView();
    mav.setViewName("redirect:/redirected");
    return mav;
}

forward

Forward는 클라이언트의 요청을 그대로 유지한 채, 서버에서 페이지를 처리하고 결과를 클라이언트에게 반환하는 방식입니다. 즉, 서버는 클라이언트에게 새로운 요청을 보내지 않고, 현재 요청에 대한 처리 결과를 바로 반환합니다. 따라서 Forward는 URL이 변경되지 않으며, 클라이언트는 기존의 요청 정보를 그대로 유지하게 됩니다.

Forward는 사용자의 요청에 대한 추가적인 처리가 필요한 경우에 유용합니다. 예를 들어, 로그인 정보를 체크한 후 로그인 처리를 하는 경우에는 Forward 방식으로 다음 페이지로 이동할 수 있습니다.

다음은 Redirect와 Forward의 차이점을 요약한 내용입니다.


Controller의 리턴타입

• String: jsp를 이용하는 경우에는 jsp 파일의 경로와 파일이름을 나타내기 위해서 사용
• void: 호출하는 URL과 동일한 이름의 jsp를 의미
• VO, DTO 타입: 주로 JSON 타입의 데이터를 만들어서 반환하는 용도로 사용 (추가적인 라이브러리 필요).
• ResponseEntity 타입: response할 때 Http 헤더 정보와 내용을 가공하는 용도로 사용 (추가적인 라이브러리 필요).
• Model, ModelAndView: Model로 데이터를 반환하거나 화면까지 같이 지정하는 경우에 사용 (최근에는 많이 사용하지 않습니다.).
• HttpHeaders: 응답에 내용 없이 Http 헤더 메시지만 전달하는 용도로 사용


Void 타입

• 호출하는 URL과 동일한 이름의 jsp타입

@GetMappin("/ex05")
public void ex05(){
 log.info("/ex05..........");
}


String 타입

  • 상황에 따라 다른 화면을 보여줄 필요가 있을 경우에 유용하게
    사용
  • String 타입에는 다음과 같은 특별한 키워드를 붙여서 사용할 수 있음
    • redirect: 리다이렉트 방식으로 처리하는 경우
    • forward: 포워드 방식으로 처리하는 경우

객체 타입

  • XML이나 JSON으로 처리
  • @RepsoneBody어노테이션과 같이 사용

ResponseEntity

  • 통신 상태 확인할때 사용
  • HTTP헤더 정보와 추가적인 데이터를 전달할 때 사용

파일업로드 처리

• Servlet 3.0이후(Tomcat 7.0)에는 기본적으로 업로드 되는 파일을 처리할 수 있는 기능이 추가
• 별도로 commons-fileupload 라이브러리 등을 사용


파일 업로드를 위한 servlet-context.xml

• multipartResolver라는 이름으로 스프링 빈 설정


파일업로드를 위한 HTML

<form>태그내 enctype=‘multipart


업로드되는 파일의 처리

• MultipartFile을 이용해서 처리


SpringEx 예제파일

HomeController.java

MemberController.java


서버를 실행시키고 주소창에 localhost:8080/member를 치면 MemberController.java에서 아래와 같이 파일을 불러와서 화면을 출력하게 된다.

화면이 출력 된 모습

값이 똑같더라도 Method값이 다르면 상관없다.

회원가입을 눌러보면

form action의 method값이 ="post"이므로 가입하기(submit)를 누르면 board/list로 이동한다. 즉 파란색 상자에 있는 method = RequestMethod.POST값과 일치해서 board/list로 이동하게 되는 것이다.

값들은 LoginVo로 받아와서 값을 저장하게 된다.


Console창에서 값을 받아온것을 확인할 수 있다.


Object 클래스의 toString 메서드

모든 클래스는 Object 클래스를 상속하므로, 모든 객체는 toString 메서드를 사용할 수 있습니다. 하지만 Object 클래스의 toString 메서드는 단순히 객체의 클래스 이름과 객체의 해시 코드를 문자열로 반환하기 때문에, 실제 사용에 적합하지 않을 수 있습니다.

따라서, 보다 구체적인 문자열 표현이 필요한 경우, toString 메서드를 오버라이딩하여 사용할 수 있습니다. 이 때, toString 메서드는 객체의 속성들을 적절한 포맷으로 문자열로 변환하여 반환합니다.

예를 들어, 다음과 같이 Person 클래스가 있다고 가정해 봅시다.

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

위 코드에서는 toString 메서드를 오버라이딩하여 Person 객체의 이름과 나이를 문자열로 반환하도록 구현했습니다. 이제, Person 객체를 생성하고 해당 객체의 toString 메서드를 호출하면 다음과 같은 결과를 얻을 수 있습니다.

Person person = new Person("John", 30);
System.out.println(person.toString());
// 출력 결과: Person{name='John', age=30}

toString 메서드를 오버라이딩하면, 객체의 디버깅이나 로깅 등에서 유용하게 사용할 수 있습니다.

// 새로고침 할때마다 값이 계속 뜨는 이유는 상속에 대해서 정의를 안하면 오브젝트 클래스를 상속받게 되어있음
// 지금 상속을 받지 않아서 해당되는 toString은 객체의 주소값을 출력하라고 되어있음


로그인 / 회원가입 구조


SpringEx 예제 회원가입 해보기

해당하는 폴더에 코드 값을 수정해주고 실행

아이디와 비밀번호를 별명을 입력하고 회원가입을 누르면 아래와 같이 나오면 정상적으로 회원가입 된것이다.

profile
뉴비 개발자 입니다. velog 주소 : https://velog.io/@jjinny_0609 Github 주소 :

0개의 댓글