@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
logger.info("===== preHandle 호출");
return super.preHandle(request, response, handler);
}
preHandle()의 return값 의미
true
: 원래 실행하려고했던 컨트롤러 메소드를 실행한다false
: 컨트롤러 메소드를 실행하지 않는다
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
logger.info("===== postHandle 호출");
super.postHandle(request, response, handler, modelAndView);
}
ModelAndView 객체
- intercept된 경로에 있는 model과 view 정보를 가져온다
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
logger.info("===== afterCompletion 호출");
super.afterCompletion(request, response, handler, ex);
}
<beans:bean id="sample1" class="edu.spring.ex04.interceptor.SampleInterceptor1">
</beans:bean>
<interceptors>
<interceptor>
<mapping path="/" />
<beans:ref bean="sample1" />
</interceptor>
</interceptors>
ref의 bean을 설정한 bean의 path경로로 가서 가로챈다
데이터 송수신과정에서도 interceptor가 데이터를 가로챌 수 있다.
@GetMapping("/test1")
public String test1() {
logger.info("test1() 호출");
return "test";
}
@GetMapping("/test2")
public String test2(Model model) {
logger.info("test2() 호출");
model.addAttribute("data", "test2");
return "test";
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
logger.info("===== preHandle 호출");
HandlerMethod handlerMethod=(HandlerMethod) handler;
Method method=handlerMethod.getMethod();
//url 경로에 있는 bean 객체
logger.info("Bean : "+handlerMethod.getBean());
//url 경로에 있는 메소드 이름
logger.info("method : "+method.getName());
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
logger.info("===== postHandle 호출");
String data=(String)modelAndView.getModel().get("data");
logger.info("data : "+data);
if(data==null) {
HttpSession session=request.getSession();
session.setAttribute("data", "DUMMY DATA");
}
super.postHandle(request, response, handler, modelAndView);
}
서버가 데이터를 view로 보낼때 실행되는 메소드. 서버에서 데이터가 넘어오고 view에 도착하기 전에 interceptor해서 데이터에 간섭할 수 있음.
만약 model에 데이터가 없으면 세션을 생성해서 데이터를 바꾸고 데이터가 있으면 기존 데이터 그대로 보내기
그림으로 그리자면 이런식으로 interceptor가 일어나는 것이다
로그인 세션 생성 및 체크가 필요한 순간마다 interceptor를 사용하면 공통된 작업을 한번에 처리할 수 있음. 단점은 코드의 흐름파악이 어려울 수 있다
interceptor에서 로그인 세션을 체크하는데
세션이 있으면 컨트롤러 메소드 실행 후 진행(interceptor 활동 없음)
로그인 세션이 없으면 로그인 페이지로 이동시키고 이동하려던 url을 저장
로그인이 되어있는지 아닌지 확인하는건 controller가 실행되기 전에만 체크하면되기 때문에 preHandle()
만 사용한다.
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
logger.info("===== preHandle 호출");
HttpSession session=request.getSession();
String userid=(String)session.getAttribute("userid");
if(userid!=null) {
logger.info("로그인 상태 -> controller method 실행");
return true;
} else {
logger.info("로그아웃 상태 -> controller method 실행 안됨");
//전체 요청 주소에서 쿼리 스트링을 제외한 부분
String uri=request.getRequestURI();
logger.info("요청 uri : "+uri);
String contextRoot=request.getContextPath();
logger.info("contextRoot : "+contextRoot);
uri=uri.replace(contextRoot, "");
//전체 요청 주소에서 쿼리 스트링만 추출
String queryString=request.getQueryString();
logger.info("쿼리 스트링 : "+queryString);
String targetURL="";
if(queryString==null) {
targetURL=uri;
}else {
targetURL=uri+"?"+queryString;
}
request.getSession().setAttribute("targetURL", targetURL);
response.sendRedirect("/ex04/member/login");
return false;
}
}
request가 없는 controller에서 request가 필요한 일을 하고자하면 그냥 매개변수로 request를 받아오면 됨
@PostMapping("/login")
public String loginPost(String userid, String password, HttpServletRequest request) throws Exception{
logger.info("loginPost() 호출");
if(userid.equals("test") && password.equals("1234")) {
logger.info("로그인 성공");
HttpSession session=request.getSession();
session.setAttribute("userid", userid);
//세션에서 targetURL 가져오기
String targetURL=(String)session.getAttribute("targetURL");
logger.info("목표 url : "+targetURL);
if(targetURL!=null) {
session.removeAttribute("targetURL");
return "redirect:"+targetURL;
}else {
return "redirect:/board/list";
}
}else {
logger.info("로그인 실패");
return "redirect:/member/login";
}
}
<dependency>
<groupId>org.imgscalr</groupId>
<artifactId>imgscalr-lib</artifactId>
<version>4.2</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<beans:bean id="uploadPath" class="java.lang.String">
<beans:constructor-arg value="C:\\Study\\FileUploadTest">
</beans:constructor-arg>
</beans:bean>
java에서 그냥
String uploadPath=new String("경로");
로 가능하긴함.
다만 인스턴스를 계속 만들기도하고 목적에 따라 구분짓기위해서 bean으로 추가함
<beans:bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="10485760"></beans:property>
</beans:bean>
<form action="upload" method="post" enctype="multipart/form-data">
<input type="file" name="file"><br>
<input type="submit" value="업로드">
</form>
@Resource(name ="uploadPath")
private String uploadPath;
@PostMapping("/upload")
public void uploadPost(MultipartFile file, Model model) {
logger.info("uploadPost() 호출");
logger.info("파일 이름 : "+file.getOriginalFilename());
logger.info("파일 크기 : "+file.getSize());
String savedFile=saveUploadFile(file);
logger.info("저장된 파일 이름 : "+savedFile);
}
private String saveUploadFile(MultipartFile file) {
UUID uuid=UUID.randomUUID();
String savedName=uuid+"_"+file.getOriginalFilename();
File target=new File(uploadPath, savedName);
try {
FileCopyUtils.copy(file.getBytes(), target);
logger.info("파일 저장 성공");
return savedName;
} catch (IOException e) {
logger.error("파일 저장 실패");
return null;
}
}
<form action="upload2" method="post" enctype="multipart/form-data">
<input type="file" name="files" multiple><br>
<input type="submit" value="업로드">
</form>
@PostMapping("/upload2")
public String uploadPost2(MultipartFile[] files, Model model) {
String result="";
for (MultipartFile f : files) {
result += saveUploadFile(f)+" ";
}
logger.info("result = "+result);
return "upload";
}