원본 본문으로 이동하기

[Sprin] RESTful API를 위한 HTTP Method Filter와 Multipart Filter

쿠에 - Spring을 처음 접한건 학교과목에서 DI의존성을 배우고 만게 고작입니다. 그 후론 현장실습에서 바로 실무에 적용하였고 그것마저 스프링을 잘 사용하지 못하는 것 같은 느낌이 듭니다. 기존 JSP를 배울 때 MVC 패턴으로 짜는건 배웠습니다. DAO방식에서 지저분하게 짜여지는게 싫었고 DB와 통신하고 Transactional하게 처리할 수 있는 MyBatis를 처음 접하였을 때 충격이었습니다. 그리고 어노테이션이란 자바 문법도 처음 접하게 되었습니다. 어노테이션을 직접 구현하진 못하지만 잘 활용하는게 중요하다고 생각하였습니다. 다른 문법이나 Spring에서 지원하는 여러 의존성라이브러리 등 직접 찾아보고 독학하면서 개발에 몰두하게 되어 지금까지 왔군요. Spring을 누군가에게 당당하게 가르친다거나 설명할 자신은 없지만 실무에 직접 적용하면서 힘들었던 점을 같이 공유하고자 글을 쓰게 되었습니다. 이 중 제가 모르고 있거나 잘못알고 있을 수도 있고 어설프게 알아서 올바른 설명이 아닐 수도 있습니다. 참고 하실 수 있으면 바랄 것 없고 잘못된건 지적해주시면 감사히 수정하도록 하겠습니다. 서론은 이만하고 본론으로 들어가겠습니다. RESTful API중 HTTP Method = GET, POST이외에 DELETE, PUT 같은 메서드를 이용하기 위해선 Spring MVC에선 필터를 따로 설정해서 컨트롤러까지 전달해주어야 합니다. @RequestMapping(value = "/post", method = RequestMethod.POST) public String savePost(BoardDTO post, Locale locale, Model model, HttpServletRequest request, HttpServletResponse response, HttpSession session) { 위와 같이 RequestMapping어노테이션을 이용해 컨텍스트로 맵핑시켜주고 method의 값을 정해 Request로 들어오는 방식을 정하고 통제할 수 있습니다. 메서드를 지원하지 않거나 맵핑을 안 해놓은 컨텍스트로 연결되면 405 http response를 반환하게 됩니다. RestfulAPI 중 같은 맥락(컨텍스트)이라도 GET, POST, PUT, DELETE를 구별해서 써야 하는데 PUT과 DELETE는 기존 메서드에 포함되지 않습니다. 그러면 메서드에 등록해주어야하는데 필터를 거치면 쓸 수 있습니다. 필터는 WEB-INF/web.xml에서 설정할 수 있습니다. <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <!-- 서블릿 필터 (custom) --> <filter> <filter-name>servletFilter</filter-name> <filter-class>com.package.name.ServletFilter</filter-class> </filter> <filter-mapping> <filter-name>servletFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 인코딩 필터 --> 생략 <!-- spring appServlet, root -context --> 생략 <!-- Multipart Method Filter --> <filter> <display-name>springMultipartFilter</display-name> <filter-name>springMultipartFilter</filter-name> <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class> </filter> <filter-mapping> <filter-name>springMultipartFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- HTTP Method Filter --> <filter> <filter-name>httpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>httpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 세션타임 --> 생략 <!-- 에러처리 --> 생략 </web-app> 위와 같이 먼저 적용할 서블릿 필터 > 인코딩 필터 > context 를 거쳐서 멀티파트 필터를 해주어야 합니다. 파일 업로드시 spring폴더에 있는 appServlet/servlet-context에 multipartResolver를 설정해주면 되었지만 multipartResolver를 root-context로 옮기고 아래와 같이 <bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="UTF-8" /> <property name="maxUploadSize" value="1000000000" /> <property name="maxInMemorySize" value="1000000000" /> </bean> 처럼 주면 다중 업로드를 처리 할 수 있습니다. 원래 ajax나 폼으로 파일을 전송할 때 type이 multipart/form-data형식인데 이건 POST로 전송하지만 type이 HTTP Method Filter로는되지 않아 필터링을 해주어야 합니다. 적용을 하고 나면 @ResponseBody @RequestMapping(value = "/uploadAttach", method = RequestMethod.POST) public Map<String, String> attach(MultipartHttpServletRequest request, HttpSession session, @RequestParam(value="writeNum", required=false) String writeNum, Model model) { 같이 Controller에서 받을 수 있습니다. Controller에서 Parameter를 받는 방법은 전명님의 글 스프링 컨트롤러와 파라미터 : 1. 컨트롤러에서 파라미터를 받는 방법 https://gs.saro.me/#!m=elec&jn=878 를 참조 해주세요. 이렇게 해서 HttpMethod설정과 파일업로드를 할 수 있었습니다. 도움이 되었으면 댓글! 남겨주세요~ - JSP 서블릿 XML/XSL/XSLT HTTP 스프링 자바