Java EE 정리 33
12 Apr 2019
Reading time ~6 minutes
Java EE 정리 33 - Spring 버전 설정, 버전 설정, 요청방식에 따른 처리, 여러 웹 파라미터 처리, Controller에서 JSP로 값 전달(1)
Spring MVC(복습)
- model2에서는 요청별 컨트롤러 클래스를 만들어 패키지 단위로 일을 묶었는데 Spring MVC에선 요청별 메소드를 만들어 클래스 단위로 묶을 수 있게 됨
Controller
- 요청 URL을 method로 처리
- Spring MVC의 기본적인 페이지 이동은 forward로 URL이 변경되지 않음
-
작성법
- Handler Mapper가 찾을 수 있도록 클래스 위에 @Controller를 설정
- URL을 처리하는 method 위에 @RequestMapping을 설정
-
메소드는 Spring Framework에서 호출
-
Web parameter를 메소드의 Parameter로 받고 보여줄 JSP명을 반환
- HttpServletRequest를 파라미터로 받을 수 있다.(비권장)
-
Web parameter를 메소드의 Parameter로 받고 보여줄 JSP명을 반환
@Controller
public class 클래스명{
@RequestMapping(value="/요청이름.do" method=RequestMethod.GET)
public String method명(매개변수, ...) { // 반환형은 반드시 String
...
return "응답할페이지명";
}
}
Spring 버전 설정
- Spring Legacy Project 생성, Spring MVC 프로젝트 생성
- pom.xml에서 사용할 Java와 Spring framework의 버전 변경
- Maven 옵션에서 Update Project(Alt + F5)로 새 Dependencies 다운
<!-- pom.xml -->
...
<properties>
<java-version>1.8</java-version>
<org.springframework-version>4.3.9.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
...
-
진입점 설정
- .do로 끝나는 요청이 오면 DispatcherServlet에서 처리하도록 ServletMapping, 진입점 설정 ```html …
appServlet *.do
- .do로 끝나는 요청이 오면 DispatcherServlet에서 처리하도록 ServletMapping, 진입점 설정 ```html …
</web-app>
* **index.html을 WebContent에 만들고 진입점으로 리다이렉션 처리**
```html
...
<script type="text/javascript">
location.href="index.do";
</script>
...
-
component-scan이 존재하여 src 하위 패키지에 있는 Controller어노테이션이 붙은 클래스를 찾는다.
- HandlerMapper가 RequestMapping된 method를 찾고, 해당 method 호출
<!-- servlet-context.xml -->
...
<context:component-scan base-package="kr.co.sist" />
</beans:beans>
-
index.do란 요청이 오면 indexPage 메소드가 호출되어 보여줄 jsp 반환
- InternalResourceViewResolver로 객체로 받은 jsp명에 prefix, suffix 붙은 경로의 jsp를 찾음
- 존재하면 Controller 처리결과를 갖고 JSP 응답
@Controller
public class MainController {
@RequestMapping(value="/index.do",method=RequestMethod.GET)
public String indexPage() {
return "index";
}
}
<!-- index.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<h1>Hello Spring Framework!</h1>
요청 방식에 따른 처리
- static import를 사용해서 RequestMethod 필드 사용코드를 줄일 수 있다.
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;
- 기존에 쓰던 메뉴 그대로 사용
<!-- main_menu.jsp -->
...
<li><a href="#void">Spring MVC 사용</a>
<ul>
<li><a href="request_get.do">GET방식 요청</a></li>
<li><a href="request_post.do">POST방식 요청</a></li>
<li><a href="request_all.do">모든방식 요청</a></li>
</ul>
</li>
...
@Controller
public class MainController {
@RequestMapping(value="/index.do",method=GET)
public String indexPage() {
return "index";
}
@RequestMapping(value="/request_get.do",method=GET)
public String requestGet() {
return "get";
}
}
<!-- get.jsp -->
...
<h1>GET 방식으로 요청된 페이지</h1>
<p>
요청방식 : <%= request.getMethod() %>
</p>
...
- POST 방식으로 요청하기 위해선 form태그가 필요하다.
// MainController
...
@RequestMapping(value="/request_post.do",method=POST)
public String requestPost() {
return "post";
}
}
<!-- post.jsp -->
...
<h1>POST 방식으로 요청된 페이지</h1>
<p>
요청방식 : <%= request.getMethod() %>
</p>
...
- POST 요청을 보내기 위해 hidden form을 사용한다.
<!-- main_menu.jsp -->
...
<script type="text/javascript">
...
function sendPost() {
$("#hidFrm").submit();
}
</script>
...
<li><a href="#void" onclick="sendPost()">POST방식 요청</a></li>
...
<!-- index.jsp -->
...
<!-- main_menu.jsp는 JSTL을 사용해서 import 되어 있음 -->
...
<form action="request_post.do" method="post" name="hidFrm" id="hidFrm">
</form>
<h1>Hello Spring Framework!</h1>
...
-
하나의 요청(method)처리
- method가 GET/POST 방식을 모두 처리해야할 때 method값을 배열로 처리한다.
// MainController
...
@RequestMapping(value="/request_all.do",method={ GET, POST })
public String requestAll() {
return "all";
}
}
<!-- main_menu.jsp -->
<script type="text/javascript">
...
function requestAll() {
var method="";
if(confirm("GET방식으로 요청 하시겠습니까?")) {
method="GET";
} else {
alert("POST 방식으로 요청합니다.");
method="POST";
}
document.hidFrm.method=method;
document.hidFrm.action="request_all.do";
document.hidFrm.submit();
}
</script>
...
<!-- POST이동이 가능하도록 menu가 hidFrm을 갖는다 -->
<form action="request_post.do" name="hidFrm" method="post" id="hidFrm">
<input type="hidden" />
</form>
...
<li><a href="#void" onclick="requestAll()">GET/POST 모두 요청</a></li>
...
<!-- all.jsp -->
...
<h1>모든 요청 방식을 처리하는 페이지</h1>
<p>
요청방식 : <%= request.getMethod() %>
</p>
...
Web Parameter 처리
- HttpServletRequest 사용하는 방법
- 권장 하지 않음
- Java EE의 기능
- 단위 테스트 시 반드시 Container가 필요
// 비권장, HttpServletRequest 객체를 매개변수로 받아 사용
@RequestParam(...)
public String method명(HttpServletRequest request) {
request.getParameter("이름");
request.getParameterValues("이름");
}
-
web parameter가 하나일 때 - 자바 데이터형
- 매개변수명과 web parameter명이 동일해야 한다
@RequestParam(...)
public String method명(String name) { // web parameter가 하나일 때
// form태그의 name이 name인게 submit되거나
// a태그의 href속성값으로 쿼리스트링에 파람으로 name을 갖고 이동 시
// web parameter에 name값이 매개변수로 들어오게 된다
...
-
web parameter가 여러개일 때 - VO
- VO의 instance 변수명과 web parameter명이 동일해야 한다
-
Web Parameter를 여러개 처리할 때 사용하는 VO는 POJO 형식 클래스
- Plain Old Java Object
- 순수하게 자바 형식(Java SE)으로 이루어진 클래스
public class VO {
private String name;
private int age;
// setter, getter 생성
<a href="ooo.do?name=이재현&age=27"><!-- 파람 갖고 이동! -->
@RequestMapping(...)
public String method명(VO vo) { // Web Parameter가 여럿일 때
// Web Parameter를 VO로 자동으로 받는다
vo.getName();
vo.getAge();
}
-
Web에서 전달되는 값들은 모두 String
- 프레임워크가 파라미터로 전달되는 값을 VO에 담을 때 int형이면 알아서 Integer.parseInt처리
Web Parameter 처리 예 - HttpServletRequest객체 사용 시
-
Apache Tomcat에
servlet-api.jar
가 있기 때문에 HttpServletRequest를 사용할 수 있다
<!-- main_menu.jsp -->
...
<li><a href="request_form.do">HttpServletRequest로 파마리터 처리</a></li>
...
-
GET방식으로 요청을 처히라 때에는 URL만 넣어도 된다.
- 비권장(가독성이 떨어진다.)
@Controller
public class ParamController {
// GET방식으로 요청을 처리할 때에는 URL만 넣어도 된다.
@RequestMapping("/request_form.do")
public String requestForm(HttpServletRequest request) {
return "param/request_form";
}
}
<!-- /param/request_form.jsp -->
...
<form action="use_request_process.do">
<label>이름</label>
<input type="text" name="name" class="inputBox"/><br/>
<label>나이</label>
<input type="text" name="age" class="inputBox"/><br/>
<label>관심언어</label>
<input type="checkbox" name="lang" value="go"/>GO
<input type="checkbox" name="lang" value="python"/>Python
<input type="checkbox" name="lang" value="javascript"/>JavaScript
<input type="checkbox" name="lang" value="java"/>Java
<input type="submit" value="전송" class="btn"/>
</form>
...
//ParamController
...
import static org.springframework.web.bind.annotation.RequestMethod.GET;
...
@RequestMapping(value="/use_request_process.do",method=GET)
public String requestFormProcess(HttpServletRequest request) {
String name = request.getParameter("name");
String age = request.getParameter("age");
String[] lang = request.getParameterValues("lang");
// EL로 배열인 Web Parameter를 처리를 못하므로 request객체에 넣어 전달
request.setAttribute("lang",lang);
return "param/request_process";
}
}
...
<!-- param/request_process.jsp -->
...
<ul>
<li>${ param.name }님 안녕하세요.</li>
<li>${ param.age }살</li>
<li>
<c:if test="${ empty param.lang }">
관심 언어가 없습니다.
</c:if>
<c:forEach var="lang" items="${ requestScope.lang }">
<c:out value="${ lang }"/>
</c:forEach>
</li>
<li>
<a href="#void" onclick="history.back();">다시입력</a>
<a href="#void" onclick="location.href='request_form.do';">다시입력</a>
</li>
</ul>
Controller에서 JSP로 값 전달
-
서비스를 이용해 얻은 값을 JSP에 전달할 때 사용하는 방법
- 어쩔수 없는 경우 아니면 HttpServletRequest를 사용하지 않음
-
Model(Interface)
- Model 사용을 가장 권장
-
객체화를 Spring Framework이 하여 Arguments로 입력해준다
- Scope객체(request, session) 일을 한다
@Controller
public class Controller {
@RequestMapping(...)
public String method명(Model m) { // 1. Model을 Parameter로 선언
// Model, VO 파라미터 순서는 상관없음
...
// 2. Service에서 업무처리한 결과값 추가
m.addAttribute("이름", 값);
// 모델에 추가되면 JSP에서 '${ requestScope.이름 }' 으로 사용가능!
// requestScope는 생략 가능하나 가독성을 위해 명시
...
}
}
-
ModelAndView(Class)
- Model과 다르게 개발자가 직접 객체화
- Framework를 사용할 땐 직접 객체화를 하는 건 지양해야 하므로 사용을 비권장
Web Parameter 처리 예 - VO로 여러 파마리터 처리
<!-- main_menu.jsp -->
...
<li><a href="vo_form.do">VO 파마리터 처리</a></li>
...
// ParamController
...
@RequestMapping(value="/vo_form.do",method=GET)
public String voForm() {
return "param/vo_form";
}
...
<!-- param/vo_form.jsp -->
...
<form action="vo_process.do">
<label>이름</label>
<input type="text" name="name" class="inputBox"/><br/>
<label>나이</label>
<input type="text" name="age" class="inputBox"/><br/>
<label>관심언어</label>
<input type="checkbox" name="lang" value="go"/>GO
<input type="checkbox" name="lang" value="python"/>Python
<input type="checkbox" name="lang" value="javascript"/>JavaScript
<input type="checkbox" name="lang" value="java"/>Java
<input type="submit" value="전송" class="btn"/>
</form>
...
public class ParamVO {
private String name;
private int age;
private String[] lang;
// getter, setter 생성, VO의 객체화는 Spring에서 해준다
...
// ParamController
// ParamController
...
@RequestMapping(value="/vo_process.do",method=GET)
public String voProcess(ParamVO pv, Model m) {
// Model객체에 추가한 값은 JSP로 전달된다.
m.addAttribute("langData", pv.getLang());
m.addAttribute("nameData", pv.getName());
m.addAttribute("ageData",pv.getAge());
return "param/vo_process";
}
}
<!-- param/vo_process.jsp -->
...
<ul>
<li> VO로 값 처리</li>
<li>${ param.name }(${ nameData })님 안녕하세요.</li>
<li>${ param.age }(${ ageData })살</li>
<li>
<c:if test="${ empty langData }">
관심 언어가 없습니다.
</c:if>
<c:forEach var="lang" items="${ requestScope.langData }">
<c:out value="${ lang }"/>
</c:forEach>
</li>
<li>
<a href="#void" onclick="history.back();">다시입력</a>
<a href="#void" onclick="location.href='request_form.do';">다시입력</a>
</li>
</ul>
...