복붙노트

[SPRING] Spring 3.2 @ResponseBody가 Model 반환 값으로 작동하지 않습니다.

SPRING

Spring 3.2 @ResponseBody가 Model 반환 값으로 작동하지 않습니다.

다음 매핑은 Spring 3.1에서 작동했지만 Spring 3.2에서는 작동하지 않습니다. table.jsp 파일이 없다는 설명과 함께 404 오류가 발생합니다. 대신 "모델"을 json으로 serialize해야합니다.

    @RequestMapping(value = {"/table"}, method = RequestMethod.GET, produces="application/json")
    public @ResponseBody Model table(Model model, @RequestParam(defaultValue = "1") Integer pg) {
        fillListModel(model, pg);
        return model;
    }

기존 코드에 아무런 영향을 미치지 않고이 문제를 해결할 수있는 방법이 있습니까?

다음 코드는 잘 작동합니다.

    @RequestMapping(value = {"/table"}, method = RequestMethod.GET, produces="application/json")
    public @ResponseBody Model table(Model model, @RequestParam(defaultValue = "1") Integer pg) {
        return new User();
    }

그래서 Spring은 뷰에서 렌더링되기보다는 모델이 json으로 변환 될 목적으로 반환된다는 것을 인식하지 못합니다.

해결법

  1. ==============================

    1.이것은 Spring 3.2+ (3.1에서 어떻게 동작하는지 기억이 안남)가 @RequestMapping 메소드의 반환 값을 처리하는 방법의 결과입니다. Spring은 HandlerMethodReturnValueHandler 타입의 인스턴스를 사용하여 리턴 값을 처리하는 방법을 결정한다. javadoc을 통해서도 다른 유형을 살펴보십시오.

    이것은 Spring 3.2+ (3.1에서 어떻게 동작하는지 기억이 안남)가 @RequestMapping 메소드의 반환 값을 처리하는 방법의 결과입니다. Spring은 HandlerMethodReturnValueHandler 타입의 인스턴스를 사용하여 리턴 값을 처리하는 방법을 결정한다. javadoc을 통해서도 다른 유형을 살펴보십시오.

    MVC 환경을 구성 할 때 기본 @EnableWebMVC 또는 을 사용하면 Spring은 이러한 인스턴스를 특정 순서로 등록합니다. 이것은 아래와 같이 RequestMappingHandlerAdapter # getDefaultReturnValueHandlers () 메소드에서 발생합니다.

    private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {
        List<HandlerMethodReturnValueHandler> handlers = new ArrayList<HandlerMethodReturnValueHandler>();
    
        // Single-purpose return value types
        handlers.add(new ModelAndViewMethodReturnValueHandler());
        handlers.add(new ModelMethodProcessor());
        handlers.add(new ViewMethodReturnValueHandler());
        handlers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.contentNegotiationManager));
        handlers.add(new CallableMethodReturnValueHandler());
        handlers.add(new DeferredResultMethodReturnValueHandler());
        handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory));
    
        // Annotation-based return value types
        handlers.add(new ModelAttributeMethodProcessor(false));
        handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.contentNegotiationManager));
    
        // Multi-purpose return value types
        handlers.add(new ViewNameMethodReturnValueHandler());
        handlers.add(new MapMethodProcessor());
    
        // Custom return value types
        if (getCustomReturnValueHandlers() != null) {
            handlers.addAll(getCustomReturnValueHandlers());
        }
    
        // Catch-all
        if (!CollectionUtils.isEmpty(getModelAndViewResolvers())) {
            handlers.add(new ModelAndViewResolverMethodReturnValueHandler(getModelAndViewResolvers()));
        }
        else {
            handlers.add(new ModelAttributeMethodProcessor(true));
        }
    
        return handlers;
    }
    

    메소드가 값을 반환하면 Spring은 supportsReturnType () 메소드를 호출하고 true를 반환하는 첫 번째 항목을 선택하여 이러한 핸들러를 반복합니다.

    이 경우 Model 반환 값을 처리하는 ModelMethodProcessor는 @ResponseBody를 처리하는 RequestResponseBodyMethodProcessor보다 우선 순위가 높습니다.

    따라서 모델을 반환하고 @ResponseBody를 통해 JSON으로 변환 할 수 없습니다. 내 의견으로는, 당신은 전혀 이것을해서는 안됩니다. 모델은 DispatcherServlet 스택의 대부분 부분에 액세스 할 수 있으므로 최종 JSON에서는 원치 않는 속성을 추가 / 제거 할 수 있습니다.

    두 번째 예제에서와 같이 DTO를 사용하십시오.

  2. from https://stackoverflow.com/questions/20828834/spring-3-2-responsebody-not-working-with-a-model-return-value by cc-by-sa and MIT license