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>