programing

Spring 및 Jackson의 완전한 데이터 바인딩을 통한 REST

showcode 2023. 3. 11. 09:39
반응형

Spring 및 Jackson의 완전한 데이터 바인딩을 통한 REST

JSON POST 요청 처리에 Spring MVC를 사용하고 있습니다.아래에서는 Jackson JSON 프로세서에 내장된 MappingJacksonHttpMessageConverter를 사용하고 있으며 mvc:annotation-drived를 사용할 때 활성화되어 있습니다.

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

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

잭슨이 requestBody를 java.util 목록에 매핑하고 있는 것을 발견했습니다.LinkedHashMap 항목(단순 데이터 바인딩).대신 요청을 유형 개체 목록(이 경우 "ActionImpl")에 바인딩하고 싶습니다.

Jackson의 Object Mapper를 직접 사용하면 이 작업을 쉽게 수행할 수 있습니다.

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

Spring MVC와 MappingJacksonHttpMessageConverter를 사용할 때 어떻게 하면 가장 좋은지 궁금했습니다.힌트 있나요?

감사해요.

컬렉션 대신 어레이를 @RequestBody로 사용하여 유형 삭제 문제를 해결할 수도 있습니다.예를 들어, 다음과 같이 동작합니다.

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

이 문제는 타입 삭제에 의한 것으로 생각됩니다.즉, 범용 파라미터 타입을 전달하는 것이 아니라 actions.getClass()만이 전달되어 List<?>와 동등한 타입이 됩니다.

이 경우 다음과 같은 중간 서브클래스를 사용할 수 있습니다.

public class ActionImplList extends ArrayList<ActionImpl> { }

이렇게 하면 클래스만 통과해도 유형 정보가 유지되기 때문입니다.그럼, 다음과 같이 해 주세요.

public @ResponseBody String executeActions(@RequestBody ActionImplList actions)

효과가 있을 거야최적은 아니지만 작동해야 합니다.

Spring MVC에 대한 지식이 있는 사람이 왜 파라미터 타입이 전달되지 않는지(아마 버그인가) 밝혀주셨으면 합니다만, 적어도 해결 방법이 있습니다.

참고로 이 기능은 Spring 3.2에서 사용할 수 있습니다(https://jira.springsource.org/browse/SPR-9570) 참조).

현재 M2에서 테스트한 지 얼마 되지 않아 바로 사용할 수 있습니다(파라미터화된 타입을 제공하기 위해 추가 주석을 제공할 필요가 없습니다.새로운 Message Converter에 의해 자동으로 해결됩니다).

이 질문은 이미 오래되었지만, 어쨌든 제가 조금 기여할 수 있을 것 같습니다.

StaxMan이 지적한 것처럼, 이것은 활자 삭제에 의한 것입니다.메서드 정의에서 리플렉션을 통해 일반 인수를 얻을 수 있기 때문에 가능한 일입니다.단, Http Message Converter의 API에 문제가 있습니다.

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

여기서는 List.class만 메서드에 전달됩니다.따라서 메서드 파라미터 유형을 참조하여 실제 유형을 계산하는Http Message Converter는 사용할 수 없기 때문에 구현할 수 없습니다.

다만, 독자적인 회피책을 코드화할 수 있습니다.Http Message Converter를 사용하지 않을 뿐입니다.Spring MVC를 사용하면 표준 해결 방식보다 먼저 시작하는 자체 WebArgument Resolver를 작성할 수 있습니다.예를 들어 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는 더 적합한 메서드를 제공하지 않습니다.

메서드를 다음과 같이 선언해 보셨습니까?

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

먹어본 적은 없지만, 당신의 질문에 따르면 제가 제일 먼저 시도해 보겠습니다.

언급URL : https://stackoverflow.com/questions/4441557/rest-with-spring-and-jackson-full-data-binding

반응형