[Spring] - 요청 처리(@Request/Get/PostMapping)

2020. 9. 8. 21:19개발공부/Spring

#요청 처리방식 #@RequestMapping, @GetMapping, @PostMapping

1. RequestController를 만들어 클라이언트 요청 처리

 

 1) Request 이동 경로

  클라이언트의 요청이 들어오면 DispatcherServlet으로 도착한다. Handler Mapping이 컨트롤러를 검색하고, 찾은 Controller의 해당되는 메서드를 Handler Adapter가 URI를 기준으로 찾는다. Controller는 Service, DAO(개발자 작성)를 거쳐 DB에 접근해서 데이터를 가져오고 View까지 인도해준다. 

 2) RequestController 생성

  Java 클래스는 src/main/java에 생성된다. 패키지명 com.spring.web GroupId와 ArtifactId의 조합 아래에 RequestController를 생성해준다. class 명 윗부분에 @Controller 아노테이션을 추가한다. 그 이유는 이 클래스가 Controller임을 알려주기위해 빈을 주입하기 위해서다.

servlet-config.xml 파일 내 <context:component-scan base-package="com.spring.web" /> syntax가 아노테이션을 사용해 자동으로 bean을 등록해주며 [Beans Graph] 탭에 들어가면 생성됐음을 볼 수 있다.

 

그리고 한 가지 더. @RequestMapping을 class에 적용시키면 value 공통 경로를 생략할 수 있다. RequestController URI를 /request/.. 로 잡아준다면 class 위에 @RequestMapping("/request") 를 입력하면 된다.

@RequestMapping@GetMapping, @PostMapping의 차이는 방식 설정이다. value와 method를 매개변수로 설정해줘야하는 @RequestMapping, 경로만 써주면 되는 @Get/PostMapping

 3) 클라이언트 요청 처리방법 

  ① HttpServletRequest 객체 활용

//1. HttpServletRequest 객체 사용방법
@Controller
@RequestMapping("/request")
public class RequestController {

	//Controller를 생성할 때 생성자는 만들어준다.
	public RequestController() {

		System.out.println("requestcon 작동!");
	}
    
   @PostMapping("/join") 
   //메서드가 void로 만들어질 경우 URI경로와 이름이 같은 파일을 찾는다(join)
   public String register(HttpServletRequest request) {
	
	System.out.println("/request/join 요청이 들어왔습니다!: POST");
	System.out.println("ID: " + request.getParameter("userId"));
	System.out.println("PW: " + request.getParameter("userPw"));
	System.out.println("NAME: " + request.getParameter("userName"));
	System.out.println("HOBBY: " +
		Arrays.toString(request.getParameterValues("hobby")));
	 
	 return "request/join"; 
     
     }
    
    }

 ② @RequestParam 아노테이션을 활용

 - 형 변환이 쉽다는 장점있다. 단지 체크박스를 언체크 했을 때 value, required, defaultValue를 설정해줘야 한다는 점이 번거롭다.  ** Eclipse 팁 : 아노테이션 클래스에 커서 두고 F3 치면 정보 보여줌.

//2. @RequestParam 아노테이션 활용
@Controller
@RequestMapping("/request")
public class RequestController {

	//Controller를 생성할 때 생성자는 만들어준다.
	public RequestController() {

		System.out.println("requestcon 작동!");
	}
    
   @PostMapping("/join") 
   //메서드가 void로 만들어질 경우 URI경로와 이름이 같은 파일을 찾는다(join)
   //오버로딩 : 메서드 이름이 같아도 매겨변수나 매개변수 개수가 다르면 사용가능
	@PostMapping("/join") 
	public void register(@RequestParam("userId") String id
	  , @RequestParam("userPw") String pw , @RequestParam("userName") String name
	  , @RequestParam(value="hobby", required=false,
	  defaultValue="no hobby person") List<String> hobbys) {
	  
	  System.out.println("ID: " + id); System.out.println("PW: " + pw);
	  System.out.println("NAME: " + name); System.out.println("HOBBY: " +
	  hobbys.toString()); }
    
    }

 ③ VO를 활용해 get으로 받는 유형

 - Java 클래스 UserVO 생성한다.  VO 클래스는 생성자와 Getter, Setter를 함께 생성해준다. 전역 변수는 private으로 꼭 생성해줘야 하는게 규약이다. 변수명은 UI에 나타낼 name과 합치해야 한다. DB entity와 Java 컬럼 1:1 매칭시켜줘야 되기 때문이다. 

메서드 매개변수엔 VO 객체를 입력하고 get 방식으로 parameter들을 처리한다.

public class UserVO {

	//필드명과 UI 상 form name과 합치시켜 줘야한다.
	//DB entity와 자바 컬럼 1:1 매칭, 기본 생성자 생성, getter setter 생성
	private String userId;
	private String userPw;
	private String userName;
	private List<String> hobby;
	
	public UserVO() {
		// TODO Auto-generated constructor stub
	}
	
	public String getUserId() {
		return userId;
	}
	public void setUserId(String userId) {
		this.userId = userId;
	}
	public String getUserPw() {
		return userPw;
	}
	public void setUserPw(String userPw) {
		this.userPw = userPw;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public List<String> getHobby() {
		return hobby;
	}
	public void setHobby(List<String> hobby) {
		this.hobby = hobby;
	}
	
	
}
	@PostMapping("/join")
	public void register(UserVO user) {

		System.out.println("ID: " + user.getUserId());
		System.out.println("PW: " + user.getUserPw());
		System.out.println("NAME: " + user.getUserName());
		System.out.println("HOBBY: " + user.getHobby());
	}

 4) GET, POST 차이

 같은 Controller 내 메서드도 같으면서 요청 처리방식만 GET, POST로 나타내기가 가능하다. 게시판을 예로 들면 GET은 게시판을 클라이언트에게 노출시키는 처리 담당, POST는 작성된 게시글을 DB에 저장하는 역할을 한다.

2. Context root path 변경

Context root path는 /web2로 톰캣 server 파일에 설정되어 있다. JSP action에 경로를 설정할 때 변수를 지정해서 사용하면 편하기 때문에 그 방법을 서술한다.  

 1) set JSTL로 변수 생성

 taglib을 JSP 파일에 입력해준다. 

 2) url JSTL 사용

url JSTL을 사용해 바로 action주소로 사용한다. 편리하다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!-- 
	#컨텍스트 루트 경로가 변경될 경우 처리방법(/web2)
	1. 컨텍스트 루트 경로를 변수로 지정함.
	2. <c url /> 태그를 사용 (훨씬 편리함) 알아서 contextPath를 찾아줌
 -->
<%-- 1번 방식 : 
	<c:set var="path" value="<%= request.getContextPath() %>" scope="application"/>
 --%>
 <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

	<h2>요청 파라미터값 테스트!</h2>
	
	<!-- post 방식이기 때문에 상관없다. 방식이 다름. DB에 넣을거임 -->
	<!-- 1번 방식 : 
    <form action = "${path }/request/join" method="post">
    -->
    <!-- 2번 방식 -->
	<form action = "<c:url value='/request/join'/>" method="post">

 

3. POST 방식 처리 시 한글 인코딩

톰캣 설정하는 web.xml 내 아래 코드를 넣어준다.

	<!-- 한글 인코딩 필터 설정(톰캣 내부의 한글처리) -->
	<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>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<!-- 위에 지정한 encodingFilter이름을 모든 패턴에 적용 -->
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>