Spring MVC 예제 - 1
HTML 파일로부터 쿼리문자열 전달 -> 매핑 컨트롤러가 처리 -> 처리 결과를 JSP로 포워드
- case 1 : 전달받을 쿼리 문자열이 적을 때
- case 2 : 전달받을 쿼리 문자열이 여러 개일 때(VO 객체 사용)
- case 3 : 세션 객체를 사용할 때
case1 : 전달받을 쿼리 문자열이 적을 때
HTML
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> </head> <body> <div> <h2>연산할 2개의 숫자를 입력하고 연산자를 선택하시오</h2> <hr> <form method="get" action="/springedu/calc"> <input type="number" name="n1"> <select name="calc"> <option value="+">+</option> <option value="-">-</option> <option value="*">*</option> <option value="/">/</option> </select> <input type="number" name="n2"> <button type="submit">계산하기</button> </form> </div> </body> </html>
컨트롤러
package my.spring.springedu; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.view.RedirectView; @Controller public class CalcController { @RequestMapping("/calc") public ModelAndView calc(String calc, int n1, int n2) { int answer; ModelAndView mav = new ModelAndView(); try { if(calc.equals("+")) answer = n1 + n2; else if(calc.equals("-")) answer = n1 - n2; else if(calc.equals("*")) answer = n1 * n2; else answer = n1/n2; mav.addObject("result", answer); mav.setViewName("calcResult"); } catch(Exception e) { mav.setViewName("errorResult"); } return mav; } }
jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> </head> <body> <h1>연산 요청 결과</h1> <hr> 결과 : <span>${result}</span> <br> </body> </html>
스프링 mvc를 쓰면서 편리하다고 생각한 점은, html 또는 jsp에서 name속성으로 쿼리를 받아올 때에 서블릿에서 사용했던 getParameter과 같은 메서드를 쓰지 않아도 된다는 것이다.
그냥 name 속성으로 준 이름을 그대로 컨트롤러 메서드의 패러미터로 주면 알아서 받아온다! (
@RequestParam
을 꼭 안써도 됨)그 다음 jsp로 전달하고자 하는 데이터가 있을 때에는
ModelAndView
객체의addObject
메서드를 사용해서 저장해주기만 하면 된다.포워드할 주소도
ModelAndView
에setViewName
으로 지정해주기만 하면 된다.. 간단..
case2 : 전달받을 쿼리 문자열이 여러 개일 때(VO 객체 사용)
- HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Get the Query String as a Model object(VO)</h1>
<hr>
<!--a 태그로 전달-->
<a href="/springedu/querystring5?testName=aaa&testAge=10&testAddr=bbb">querystring5-Request(Include query)</a>
<!--form 태그 get방식-->
<form method="get" action="/springedu/querystring5">
<input type="text" name="testName" required><br>
<input type="number" name="testAge" required><br>
<input type="text" name="testAddr" required><br>
<input type="submit" value="querystring5-Request">
</form>
<!--form 태그 post방식(1)-->
<form method="post" action="/springedu/querystring6">
<input type="text" name="testName" required><br>
<input type="number" name="testAge" required><br>
<input type="text" name="testAddr" required><br>
<input type="submit" value="querystring6-Request">
</form>
<!--form 태그 post방식(2)-->
<form method="post" action="/springedu/querystring7">
<input type="text" name="testName" required><br>
<input type="number" name="testAge" required><br>
<input type="text" name="testAddr" required><br>
<input type="submit" value="querystring7-Request">
</form>
</body>
</html>
- 컨트롤러
package my.spring.springedu;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import vo.QueryVO;
@Controller
public class QueryStringController2 {
@RequestMapping("/querystring5")
public ModelAndView proc(QueryVO vo) {
ModelAndView mav = new ModelAndView();
String name = vo.getTestName();
int age = vo.getTestAge();
String addr = vo.getTestAddr();
mav.addObject("spring", name + "-" + age + "-" + addr);
mav.setViewName("queryView3");
return mav;
}
@RequestMapping(value = "/querystring6",
method = RequestMethod.POST)
public ModelAndView procPost(QueryVO vo) {
ModelAndView mav = new ModelAndView();
String name = vo.getTestName();
int age = vo.getTestAge();
String addr = vo.getTestAddr();
mav.addObject("spring", name + "@" + age + "@" + addr);
mav.setViewName("queryView3");
return mav;
}
@RequestMapping("/querystring7")
public ModelAndView proc(HttpServletRequest request) {
ModelAndView mav = new ModelAndView();
String name =request.getParameter("testName");
int age = Integer.parseInt(request.getParameter("testAge"));
String addr = request.getParameter("testAddr");
mav.addObject("spring", name + "#" + age + "#" + addr);
mav.setViewName("queryView3");
return mav;
}
}
- vo
package vo;
public class QueryVO {
private String testName;
private int testAge;
private String testAddr;
public String getTestName() {
return testName;
}
public void setTestName(String testName) {
this.testName = testName;
}
public int getTestAge() {
return testAge;
}
public void setTestAge(int testAge) {
this.testAge = testAge;
}
public String getTestAddr() {
return testAddr;
}
public void setTestAddr(String testAddr) {
this.testAddr = testAddr;
}
}
- jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>응답용JSP</title>
</head>
<body>
<h2>Forward from QueryStringController2 to queryView3.jsp</h2>
<hr>
<c:if test="${!empty queryVO}" >
<ul>
<li>${ queryVO.testName }</li> <!-- 전달된 vo객체의 앞글자를 소문자로 바꿔서 자동으로 가져온다 -->
<li>${ queryVO.testAge }</li>
<li>${ queryVO.testAddr }</li>
</ul>
</c:if>
<%-- <h3>Total Query String : ${ spring }</h3> --%>
</body>
</html>
만약 전달할 쿼리가 여러개인 경우 일일이 패러미터로 받기 번거로울 수 있는데, 이 경우 VO 클래스를 하나 생성하여 두면 편리하다.
VO 클래스를 생성하여 getter, setter을 만들어 놓은 뒤, 컨트롤러 메서드에서 이 VO를 패러미터로 넣게 되면 알아서 값을 set해준다! 서블릿에서는 VO 클래스의 인스턴스를 생성한다음, setter 메서드를 호출하여 일일이 값을 저장해주어야 했는데 그 과정이 생략되는 것이다.(스프링의 DispatcherServlet이 알아서 해준다) 물론 name 속성명을 VO클래스에 똑같은 변수명으로 설정해주어야 자동으로 해준다. 위 예시에서 컨트롤러 메서드에서 getter로 꺼내서 저장한 것은 별도로 spring이라는 문자열을 전달해주려고 한 것이다.
그리고 jsp에서도 VO 인스턴스를 생성할 필요도 getter 메서드로 꺼낼 필요도 없다. 그냥 VO 클래스명의 앞글자를 소문자로 바꾼 이름에, 멤버 변수를 바로 호출하면 된다.
case 3 : 세션 객체를 사용할 때
- 컨트롤러
package my.spring.springedu;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import vo.CountVO;
@Controller
public class CountController2 {
@RequestMapping(value="/count2")
public void handle(int num1, int num2, HttpSession s) {
if(s.getAttribute("count3") == null )
s.setAttribute("count3", new CountVO());
if(s.getAttribute("count4") == null )
s.setAttribute("count4", new CountVO());
CountVO vo3 = (CountVO)s.getAttribute("count3");
CountVO vo4 = (CountVO)s.getAttribute("count4");
vo3.setCountNum(num1);
vo4.setCountNum(num2);
System.out.println("handle() : "+
vo3.getCountNum() + " : " + vo4.getCountNum());
System.out.println("=============================");
}
@RequestMapping(value="/countdel2")
public void handle(HttpSession s, String who) {
if(who != null) {
s.removeAttribute(who);
System.out.println(who + " deleted!");
}
System.out.println("=============================");
}
}
- vo
package vo;
public class CountVO {
private int countNum;
public CountVO() {
System.out.println("CountVO 객체 생성!!");
}
public int getCountNum() {
return countNum;
}
public void setCountNum(int countNum) {
this.countNum += countNum;
}
}
- jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSP test example</title>
</head>
<body>
<h1>Counting Result</h1>
<hr>
<h2>count3 : ${ sessionScope.count3.countNum }</h2>
<h2>count4 : ${ sessionScope.count4.countNum }</h2>
</body>
</html>