복붙노트

[SPRING] Spring과 Jackson 전체 데이터 바인딩을 사용하는 REST

SPRING

Spring과 Jackson 전체 데이터 바인딩을 사용하는 REST

JSON POST 요청을 처리하기 위해 Spring MVC를 사용하고있다. 커버 아래에 Jackson JSON 프로세서를 기반으로 MappingJacksonHttpMessageConverter를 사용하고 mvc : annotation-driven을 사용할 때 활성화됩니다.

내 서비스 중 하나가 작업 목록을 수신합니다.

@RequestMapping(value="/executeActions", method=RequestMethod.POST)
    public @ResponseBody String executeActions(@RequestBody List<ActionImpl> actions) {
        logger.info("executeActions");
        return "ACK";
    }

Jackson이 requestBody를 java.util.LinkedHashMap 항목 목록 (단순 데이터 바인딩)에 매핑하는 것으로 나타났습니다. 대신 요청을 유형이 지정된 객체 목록 (이 경우 "ActionImpl")에 바인딩하고 싶습니다.

잭슨의 ObjectMapper를 직접 사용하면 쉽게 할 수 있습니다.

List<ActionImpl> result = mapper.readValue(src, new TypeReference<List<ActionImpl>>() { }); 

그러나 나는 Spring MVC와 MappingJacksonHttpMessageConverter를 사용할 때 이것을 달성하는 가장 좋은 방법이 무엇인지 궁금해했다. 어떤 힌트?

감사

해결법

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

    1.문제가 유형 삭제로 인한 것, 즉 일반 매개 변수 유형을 전달하는 대신 action.getClass () 만 전달 된 것일 수 있습니다. 이것은 List 에 해당하는 유형을 제공합니다.

    문제가 유형 삭제로 인한 것, 즉 일반 매개 변수 유형을 전달하는 대신 action.getClass () 만 전달 된 것일 수 있습니다. 이것은 List 에 해당하는 유형을 제공합니다.

    이것이 사실이라면 다음과 같은 중간 하위 클래스를 사용하는 것이 좋습니다.

    public class ActionImplList extends ArrayList<ActionImpl> { }
    

    이는 클래스가 전달 되더라도 보유 유형 정보가 될 것이기 때문입니다. 그럼:

    public @ResponseBody String executeActions(@RequestBody ActionImplList actions)
    

    속임수를 쓸거야. 최적은 아니지만 작동해야합니다.

    Spring MVC 지식을 가진 사람이 매개 변수 유형이 전달되지 않는 이유 (아마도 버그 일까?)에 대해 알려줄 수 있기를 바랍니다.하지만 적어도 해결 방법이 있습니다.

  2. ==============================

    2.배열 대신 @RequestBody를 사용하여 형식 지우기 문제를 해결할 수도 있습니다. 예를 들어 다음과 같이 작동합니다.

    배열 대신 @RequestBody를 사용하여 형식 지우기 문제를 해결할 수도 있습니다. 예를 들어 다음과 같이 작동합니다.

    public @ResponseBody String executeActions(@RequestBody ActionImpl[] actions) { //... }
    
  3. ==============================

    3.자세한 내용은 Spring 3.2 (https://jira.springsource.org/browse/SPR-9570 참고)에서 사용할 수 있습니다.

    자세한 내용은 Spring 3.2 (https://jira.springsource.org/browse/SPR-9570 참고)에서 사용할 수 있습니다.

    난 그냥 현재의 M2에 그것을 테스트하고 상자의 매력처럼 작동합니다 (additionalnal 주석을 매개 변수화 된 유형을 제공 할 필요가 없다, 그것은 자동으로 새로운 MessageConverter에 의해 해결됩니다)

  4. ==============================

    4.이 질문은 이미 오래되었지만 어쨌든 조금 기여할 수 있다고 생각합니다.

    이 질문은 이미 오래되었지만 어쨌든 조금 기여할 수 있다고 생각합니다.

    StaxMan이 지적한 것처럼, 이것은 유형 삭제 때문입니다. 메서드 정의에서 반사를 통해 일반 인수를 얻을 수 있으므로 확실히 가능해야합니다. 그러나 문제는 HttpMessageConverter의 API입니다.

    T read(Class<? extends T> clazz, HttpInputMessage inputMessage);
    

    여기에서는 List.class 만 메서드에 전달됩니다. 보시다시피 메소드 매개 변수 유형을 살펴봄으로써 실제 유형을 계산하는 HttpMessageConverter를 구현하는 것은 불가능합니다.

    그럼에도 불구하고 자신 만의 해결 방법을 코딩 할 수 있습니다. HttpMessageConverter를 사용하지 않을 것입니다. Spring MVC를 사용하면 표준 해결 방법 이전에 시작된 WebArgumentResolver를 작성할 수 있습니다. 예를 들어 ObjectMapper를 직접 사용하여 값을 구문 분석하는 고유 한 사용자 정의 주석 (@JsonRequestBody?)을 사용할 수 있습니다. 메서드에서 매개 변수 유형을 제공 할 수 있습니다.

    final Type parameterType= method.getParameterTypes()[index];
    List<ActionImpl> result = mapper.readValue(src, new TypeReference<Object>>() {
        @Override
        public Type getType() {
            return parameterType;
        }
    });
    

    TypeReference가 실제로 의도 된 방식이 아니지만, ObjectMapper는 더 적합한 메소드를 제공하지 않습니다.

  5. ==============================

    5.이 메소드를 다음과 같이 선언 해 보았습니다 :

    이 메소드를 다음과 같이 선언 해 보았습니다 :

    executeActions(@RequestBody TypeReference<List<ActionImpl>> actions)
    

    나는 그것을 시도하지는 않았지만 귀하의 질문에 기초하여 시도 할 첫 번째 것이 었습니다.

  6. from https://stackoverflow.com/questions/4441557/rest-with-spring-and-jackson-full-data-binding by cc-by-sa and MIT license