📁 Spring MVC
Spring Framework 에서는 클라이언트의 화면을 표현하기 위한 View와
서비스를 수행하기 위한 개발 로직 부분을 나누는 MVC2 패턴을 지원한다.
Model, View, Controller 사이의 의존 관계를 DI 컨테이너에서 관리하여
유연한 웹 애플리케이션을 쉽게 구현 및 개발할 수 있다.
📕 구성요소
구성 요소 | 설명 |
DispatcherServlet | 클라이언트의 요청(Request)을 전달 받고, 요청에 맞는 컨트롤러가 리턴 한 결과 값을 View에 전달하여 알맞은 응답(Response)을 생성 |
HandlerMapping | 클라이언트의요청 URL을 어떤 컨트롤러가처리할지결정 |
Controller | 클라이언트의요청을처리한 뒤, 결과를 DispatcherServlet에게 리턴 |
ModelAndView | 컨트롤러가처리한 결과 정보 및 뷰 선택에 필요한정보를 담음 |
ViewResolver | 컨트롤러의처리 결과를 생성할View를 결정 |
View | 컨트롤러의처리 결과 화면을 생성,JSP나Velocity 템플릿 파일 등을 View로사용 |
📕 Spring MVC 요청 처리 과정
➰DispatcherServlet(발송자 서블릿 [ 중앙처리 시스템 ] )
: 요청을 컨트롤러로 전달 + 응답
(ㄴ spring에서 자동으로 만들어져있다.)
➰ HandlerMapping(매핑 처리)
: 어떤 요청을 어떤 클래스/ 메소드로 연결하는지 제어하는 객체
➰ ViewResolver (뷰 해결사)
: Controller 에서 반환된 문자열 ("common/main")
앞, 뒤에 경로 (/WEB-INF/ views), 확장자(.jsp)를 붙여 jsp 파일의 경로를 저장한 후 forword(요청위임)을 하는 객체
📕 @Annotation
: XML 파일에는 구동시킬 필수 요소만 작성하고 소스코드에 Annotation으로 표시하여 구동하는 방식
📖 @Annotation 종류 – Bean 등록 시 사용
📖 @Annotation 종류 – 의존성 주입 시 사용
📖 @RequestMapping 작성방법
: 요청 주소에 맞는 클래스 또는 메소드 연결
- @RequestMapping("요청 주소")
GET / POST 구분 X(모두 받음, 주소만 맞으면 연결) - @RequestMapping(value="요청 주소", method=RequestMethod.GET/POST)
GET / POST 방식을 구분
이때 요청 주소는 공통된 주소 앞부분을 작성한다.
요청 주소로 시작하는 요청은 해당 컨트롤러에서 처리하게 된다.
💡 서버를 켤때 작동되는 순서 💡
서버 실행 ➡ web.xml 해석 ➡ root-context.xml , servlet-context.xml 해석 ➡
➰ web.xml(배포 서술자/설명서)
서버가 켜질 때(배포가 시작 될 때) 가장 먼저 읽어들이는 설정 파일
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="4.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://JAVA.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_4_0.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets
and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- Processes application requests -->
<!--
DispatcherServlet(Spring에서 제공) 객체 생성 시
servlet-context.xml 파일을 이용해서 만든다.
-->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/appServlet/servlet-context.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 한글 깨짐 방지를 위한 Filter 추가 -->
<!-- 별도의 filter 클래스를 만들지 않고 스프링에서 제공하는 filter를 사용 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
➰ root-context.xml
서버가 켜질 때 web.xml 가장 먼저 읽어들이는 설정 파일
프로젝트 전반적으로 사용될 설정, 객체(Bean)를 생성하는 용도의 파일 작성
DB 연결 관련 내용 (JDBC,MyBatis,DBCP),AOP,트랜잭션 처리, 파일 업로드 등을 작성'
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
</beans>
➰ servelt-context.xml
(DispatcherServlet(Spring에서 제공) 객체 생성 시 servelt-context.xml 파일을 이용해서 만든다.)
DispatcherServlet 생성 시 필요한 내용을 정의하는 파일
HandlerMapping, ViewResolver , component-scan, 트랜잭션 관리자, 웹소켓, 인터셉터, 스케쥴러
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!--
DispatcherServlet 생성 시 필요한 내용을 정의하는 파일
HandlerMapping : 어떤 요청을 어떤 클래스/메소드로 연결하는지 제어하는 객체
<annotation-driven />이
@requestMapping, @GetMapping, @PostMapping을 활성화해서
HandlerMapping을 대체
ViewResolver : controller에서 반환된 문자열("common/main")
앞, 뒤에 경로 (/WEB-INF.views), 확장자(jsp)붙여
jsp 경로를 지정한 후 forward하는 객체
component-scan : @Component와 자식 어노테이션을 Bean으로 등록하는 태그
트랜잭션 관리자, 웹 소켓, 인터셉터, 스케줄러
-->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- webapp/resources 폴더를 HTTP GET 방식 요청으로 접근할 수 있다. -->
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- ViewResolver -->
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<!--
base-package 이하에 작성된
@Component와
자식 어노테이션(@Controller, @Servive, @Repository)이 붙은
클래스를 찾아서 Bean(Spring이 관리하는 객체)으로 등록
-->
<context:component-scan base-package="edu.kh.project" />
</beans:beans>
이전 이전 포스팅에는 설치하는 방법에 대해서 작성하였다.
이 포스팅부터 본격적으로 그 편하다고 하는 Spring 직접 실습해보자 !
만약, 아직 설치를 못했다면 이전 포스팅을 보고 오세요!
[Spring] 설치 진행하기
현재 폴더 상태는 이렇다. framwork에 jdk에 bin에 들어와서 경로 복사를 한다. (C:\tools\framework\jdk-11.0.2\bin 경로 저장하기 !) 맨 마지막에 있는 STS을 켜서 아래와 같이 내용 작성하기 ! - vm - 아까 저장
jnaa.tistory.com
🌝 메인 화면 ( MainController) 생성하기
첫 실행 화면인 MainController 만들어서 뿌려줄 main.jsp 위치까지 리턴해주기
package edu.kh.project.main.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
// @Controller : 현재 클래스가 컨트롤러임을 명시
// -> 요청, 응답 처리
// + bean 등록
// instance : 클래스 -> 객체
// --> new 클래스명(); 객체 생성을 개발자가 직접함
// IOC(Inversion Of Control, 제어의 역전)
// -> 프레임워크(Spring Container)가 객체를 생성하고 관리
// --> 이 때 생성된 객체 == Bean
@Controller
public class MainController {
// tip : spring에서 controller 메소드 작성 시
// 반환 값을 모르겠으면 일단 String으로 작성!
// @RequestMapping("/") : 요청 주소가 "/"인 경우 해당 메소드와 연결
@RequestMapping("/")
public String mainForward() {
// main.jsp로 화면 전환
// <beans:property name="prefix" value="/WEB-INF/views/" />
// <beans:property name="suffix" value=".jsp" />
// Spring에서 forward 하는 방법!!
// -> webapp 폴더를 기준으로
// 요청 위임할 JSP 파일 경로를 리턴하면 된다!
// 단, servlet-context.xml에 작성된
// prefix, suffix 부분을 제외하고 작성!!!
// -> prefix + 리턴 값 + suffix로 경로 완성!
// ** View Resolver **
return "common/main";
}
}
첫 실행화면이 왜 main.jsp 일까 ?
우리가 세팅해줄때, context root를 "/"로 설정해주었고,
RequestMapping 주소를 ("/") 로 연결해줬고, return 값을 main.jsp 가 있는 곳으로 리턴 해주었기 때문이다.
🌝 Member 만들기 (@ModelAttribute 이용하기 위해 Member클래스)
package edu.kh.project.member.model.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
@NoArgsConstructor
public class Member {
private int memberNo;
private String memberEmail;
private String memberPw;
private String memberNickname;
private String memberTel;
private String memberAddress;
private String profileImage;
private String enrollDate;
private String memberDeleteFlag;
private int authority;
}
🌝 MemberController 만들기 (로그인시 파라미터 값 가져오기)
🌚 redirect 방법 "redirect: 요청주소" 동일
① 파라미터 전달 방법
: HttpServletRequest를 이용하는 방법 (Controller 메소드에 매개변수로 HttpServletRequest 작성)
ㄴ 매개변수에 적으면 Spring Framework가 제공하는 Argument Resolver(매개변수 해결사)가 해결해줘서 사용 가능하다.
@RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(HttpServletRequest req) {
String inputEmail = req.getParameter("inputEmail");
System.out.println("inputEmail : " + inputEmail);
return "redirect:/";
}
② 파라미터 전달 방법
: @ RequestParam 어노테이션 이용(+생략 방법)
- request 객체를 이용한 파라미터 전달
- 어노테이션 매개변수 앞에 해당 어노테이션을 작성하면, 매개변수 값이 주입됨
** 파라미터의 name 속성 값과 매개변수명이 같으면 @RequestParam 생략 가능 !! **
: @PostMapping : @RequestMapping의 자식으로 POST 방식 요청을 연결하는 어노테이션
@PostMapping("/login")
public String login(/*@RequestParam("inputEmail")*/ String inputEmail,
/*@RequestParam("inputPw")*/ String inputPw) {
return "redirect:/";
}
@RequestParam(value="name", required="fasle", defaultValue="1") [속성] value : 전달 받은 input 태그의 name 속성값 required : 입력된 name 속성값 파라미터 필수 여부 지정(기본값 true) -> required = true인 파라미터가 존재하지 않는다면 400 Bad Request 에러 발생 -> required = true인 파라미터가 null인 경우에도 400 Bad Request defaultValue : 파라미터 중 일치하는 name 속성 값이 없을 경우에 대입할 값 지정. -> required = false인 경우 사용 |
③ 파라미터 전달 방법
: @ModelAttribute를 이용한 방법 (DTO(또는 VO)와 같이 사용하는 어노테이션)
@PostMapping("/login")
public String login(/*@ModelAttribute*/ Member inputMember) {
return "redirect:/";
}
- 전달받은 파라미터의 name 속성 값 같이 사용되는 DTO의 필드명과 같다면 자동으로 setter를 호출해 필드에 값을 세팅 *** @ModelAttribute 사용 시 주의사항 *** - DTO에 기본 생성자가 필수로 존재해야 한다 - DTO에 setter가 필수로 존재해야 한다. *** @ModelAttribute 어노테이션은 생략이 가능하다! *** @ModelAttribute를 이용해 값이 필드에 세팅된 객체를 "커맨드 객체"라고 한다. *** |
🔑
@Controller : 현재 클래스가 컨트롤러임을 명시 (요청 / 응답 처리 + bean 등록)
IOC(Inversion Of Control, 제어의 역전)
ㄴ 프레임워크(Spring Container)가 객체를 생성하고 관리 -> 이때 생성된 객체 == Bean
@RequestMapping : 요청 주소에 맞는 클래스/메소드 연결
@RequestMapping("요청 주소")
-> GET / POST 구분 X(모두 받음, 주소만 맞으면 연결)
@RequestMapping(value="요청주소", method = RequestMethod.GET/POST)
-> GET / POST 방식 구분
'ON > spring' 카테고리의 다른 글
[Spring] 드롭다운 메뉴 | 회원정보 수정 ③ (0) | 2023.08.14 |
---|---|
[Spring] 회원가입 | 주소 API 활용 ② (0) | 2023.08.11 |
[Spring] MyBatis 로그인 | 로그아웃 | 아이디 저장 | 암호화하기 | 예외페이지 만들기 세팅하기 ① (0) | 2023.08.11 |
[Spring] 설치 진행하기 (0) | 2023.08.10 |
[Spring] Framework | Library | Spring Framework 이란? (0) | 2023.08.10 |