본문 바로가기

History

[MongoDB] Spring JSON 응답처리 설정 방법 정리

DispatcherServlet 클래스를 상속 받아 유동적인 VIEW 맵핑

Spring MVC JSON Response 처리하기

사전 정의 사항

  • 1. Controller는 ModelAndView 객체를 리턴한다
  • 2. 이때 View Name 이 successView 일경우에는 JSON으로 응답을 주도록한다.

Step #1 . DispatcherServlet을 Override하여 랜더링 되기 직전에 뷰 네임을 검사하여 위에 정의한 successView 라는 이름을 가질경우 JacksonJsonView를 리턴하도록 한다.

MyDispatcherSerlvet.java
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.ModelAndView;
 
@SuppressWarnings("serial")
public class MyDispatcherServlet extends DispatcherServlet {
    @Override
    protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
        //return 되는 view name 이 successView 일때 JacksonJsonView 로 처리
        if (mv.getViewName().equals("successView")) {
            mv.addObject("successFlag"true);
            mv.setView(new MappingJacksonJsonView());
             
            super.render(mv, request, response);
        else {
            // TODO Auto-generated method stub
            super.render(mv, request, response);
        }
    }
}

Step #2 . web.xml을 수정하여 servlet class를 위에서 생성한 MyDispatcherServlet으로 변경한다.
Change

<servlet>
    <servlet-name>daum-servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/daum-servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>daum-servlet</servlet-name>
    <url-pattern>*.daum</url-pattern>
</servlet-mapping>

To

<servlet>
    <servlet-name>daum-servlet</servlet-name>
    <servlet-class>net.daum.MyDispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/daum-servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>daum-servlet</servlet-name>
    <url-pattern>*.daum</url-pattern>
</servlet-mapping>

MappingJacksonJsonView 클래스를 상속 받아 JSON VIEW 를 컨트롤

JSONP 응답 처리하기

사전 정의 사항

  • 1. jQuery ajax jsonp 요청시 jsonp 항목은 callback 으로 통일한다.
    $.ajax({
        ~ 생략 ~
        dataType : 'jsonp'
        , jsonp : 'callback'
        ~ 생략 ~
    });
  • 2. callback이라는 파라메터명칭은 어떠한 경우에도 사용하지 않는다.
    단 json 리턴이 아닌(뷰 네임이 successView가 아니라면) 사용해도 무방하다
  • 3. 파라메터로 넘어온 callback 항목을 callback 이라는 키 그대로 model에 셋팅하도록 한다.

Step #3. MappingJacksonJsonView 를 override 한다

MyMappingJacksonJsonView.java
 
import java.util.Map;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.web.servlet.view.json.MappingJacksonJsonView;
 
public class MyMappingJacksonJsonView extends MappingJacksonJsonView {
    /**
     * jquery ajax jsonp 요청에 대한 응답 처리를 위하여 해당 메서드 오버라이딩 (일반 json 요청일때는 기존 방식 그대로 사용)
     */
    @Override
    protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
        if (model.get("callback") != null && StringUtils.isNotEmpty(String.valueOf(model.get("callback")))) {
            String callback = String.valueOf(model.get("callback"));
                        //컨트롤러에서 모델에 셋팅한 파라메터로 넘온 callback function 명을 모델에서 제거한다 (응답 json data에 포함되지 않도록 하기위해)
            model.remove("callback");
             
            Object value = filterModel(model);
            ObjectMapper objectMapper =  new ObjectMapper();
             
            String jsonpResult = callback + "(" + objectMapper.writeValueAsString(value) + ")";
             
            response.getOutputStream().write(jsonpResult.getBytes("UTF-8"));
            response.getOutputStream().flush();
            response.getOutputStream().close();
        else {
            // TODO Auto-generated method stub
            super.renderMergedOutputModel(model, request, response);
        }
    }
}

Step #4. 위의 Step #2 항목에 ModelAndView에 MappingJacksonJsonView 객체를 생성하여 셋팅하던 것을 Override한 MyMappingJacksonJsonView 를 생성하여 셋팅하도록 수정한다.