스프링프레임워크 & 마이바티스
(SpringFramework, MyBatis)
6-12. Flash Attribute(RedirectAttributes, FlashMap)
MVC기반의 일반 웹 어플리케이션에서 서버 측으로 POST형태로 데이터를 전송하게 되면 스
프링 컨트롟러 에서는 사용자 요청에서 데이터를 꺼내 데이터베이스에 저장하는 등의 일을
한다.
그런 다음 사용자에게 성공한 상태정보를 보여주기 위해 JSP 페이지 등을 포워딩 하게 되
고 이 경우 사용자가 F5키 등을 눌러 POST 방식의 요청을 여러 번 보내게 되면 문제가 발생
할 수 있다.
이러한 문제점을 보완하기 위해 Spring MVC3.1 이상에서 RedirectAttributes, FlashMap을 이
용하여 POST/Redirect/GET 패턴을 보완하기 위한 방법이 나왔는데 이 패턴을 이용하게 되면
F5 키를 눌러 리로드(multiple form submit)하는 경우 POST로 서버 측으로 서브밋을 하는 것
이 아니라 GET방식 형태로 뜬 JSP만 다시 리로드 되도록 할 수 있다.
물롞 이때 RedirectAttributes를 사용하여 데이터를 저장한다면 Redirect된 후 즉시 사라지게
되고 사용자가 F5등을 눌러 리로드 하더라도 다시 서버로 다시 submit되어 저장되지 않는다.
FlashMap, RedirectAttributes등을 이용하면 리다이렉트시 값의 전달을 쿼리스트링을 이용하
지 않고 임시 플래시 메모리를 이용하여 보이지 않게 저장하고, 사용 후 삭제되도록 할 수 있
으므로 리다이렉트시 데이터 숨겨 넘기는 방법을 제공한다.
FlashMap은 flash attribute등을 저장 할 수 있고, FlashMapManager를 이용하여 FlashMap
인스턴스등을 저장, 삭제할 수 있다.
Spring MVC에서 FlashAttribute를 사용하기 위해서는 스프링3.1 이상에서만 가능하고
<mvc:annotation-driven /> 태그를 설정 파일에 기술해야 한다.
STS에서
File New Spring Legacy Project
Project Name : flashattr
Spring MVC Project 선택
다음 화면의 top level package에서 a.b.flashattr 입력
2.
[pom.xml]
Spring Framework 버전이4.X 아래라면 수정하자.
<properties>
……
<org.springframework-version>4.2.4.RELEASE</org.springframework-version>
……
</properties>
[모델 클래스]
package a.b.flashattr;
public class Emp {
String name;
String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
[컨트롤러]
package a.b.flashattr;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
3.
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
@Controller
public classHomeController {
//입력화면을 띄운다.
@RequestMapping(value="addform", method=RequestMethod.GET)
public String showForm(@ModelAttribute("emp") Emp emp) {
return "addemp";
}
//입력화면에서 "Add Emp"버튼 클릭시 호출됨
@RequestMapping(value="add", method=RequestMethod.POST)
public String add(@ModelAttribute("emp") Emp emp,
final RedirectAttributes rAttr) {
//리다이렉트로 보내는 경우 Flash영역에 임시로 emp, msg를 저장한다.
rAttr.addFlashAttribute("emp", emp);
rAttr.addFlashAttribute("msg", "added success!");
return "redirect:showemp.html";
}
@RequestMapping(value="showemp", method=RequestMethod.GET)
public String showCustomer(@ModelAttribute("emp") Emp emp) {
//페이지를 리로드하는 경우 emp.getName, emp.getAge모두 NULL이 넘어온
다.
System.out.println("emp:" + emp.getName() + ":" + emp.getAge());
return "show";
}
}
6. /WEB-INF/views/addemp.jsp
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
http://localhost:8080/flashattr/addform
F5키로 리로드 한경우
6-12. @XmlRootElement, @XmlElement를 이용 스프링 응답을 XML
로
Spring3의 <mvc:annotation-driven/>는 JAXB 라이브러리를 사용할 수 있다면, 객체를 XML
형태로 변환하는 것을 지원한다. JAXB는 JDK에 포함되어 있으므로 별도로 라이브러리에 추가
6.
할 필요는 없다.
모델 쪽에 있는 객체 중 XML로 변환할 객체에 대해서는 JAXB annotation을 사용하면 되고
컨트롟러의 메소드에는 @Response 어노테이션이 추가되어 있어야 한다.
(@XmlRootElement, @XmlElement)
STS에서
File New Spring Legacy Project
Project Name : mvcxml
Spring MVC Project 선택
다음 화면의 top level package에서 edu.mvc.xml 입력
2. pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>edu.mvc </groupId>
<artifactId>xml</artifactId>
<name>mvcxml</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<java-version>1.6</java-version>
<org.springframework-version>4.2.4.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>