programing

스프링레스트 컨트롤러에서 일반 json 본체에 액세스하는 방법은 무엇입니까?

javaba 2023. 8. 17. 23:44
반응형

스프링레스트 컨트롤러에서 일반 json 본체에 액세스하는 방법은 무엇입니까?

다음 코드를 갖는 경우:

@RequestMapping(value = "/greeting", method = POST, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE)
@ResponseBody
public String greetingJson(@RequestBody String json) {
    System.out.println("json = " + json); // TODO json is null... how to retrieve plain json body?
    return "Hello World!";
}

String json 인수는 json이 본문으로 전송되더라도 항상 null입니다.

참고로 자동 타입 변환을 원하는 것이 아니라 그냥 평범한 json 결과를 원합니다.

이것은 예를 들어 작동합니다.

@RequestMapping(value = "/greeting", method = POST, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE)
@ResponseBody
public String greetingJson(@RequestBody User user) {
    return String.format("Hello %s!", user);
}

아마도 서블릿 요청 또는 입력 스트림을 인수로 사용하여 실제 본문을 검색할 수 있습니다. 하지만 더 쉬운 방법이 있는지 궁금합니다.

지금까지 찾은 최선의 방법은 다음과 같습니다.

@RequestMapping(value = "/greeting", method = POST, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE)
@ResponseBody
public String greetingJson(HttpEntity<String> httpEntity) {
    String json = httpEntity.getBody();
    // json contains the plain json string

다른 대안이 있다면 제게 알려주세요.

그냥 사용할 수 있습니다.

@RequestBody String pBody

HttpServletRequest만 작동했습니다.HttpEntity에 null 문자열이 지정되었습니다.

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.IOUtils;

@RequestMapping(value = "/greeting", method = POST, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE)
@ResponseBody
public String greetingJson(HttpServletRequest request) throws IOException {
    final String json = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
    System.out.println("json = " + json);
    return "Hello World!";
}

나에게 가장 간단한 방법은

@RequestMapping(value = "/greeting", method = POST, consumes = MediaType.ALL_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String greetingJson(String raw) {
    System.out.println("json = " + raw);
    return "OK";
}

HTTP 본문을 JSON으로 가져와 사용자 지정 데이터 유형으로 변환해야 하는 수십 가지 메소드가 있는 경우 프레임워크에서 지원을 구현하는 더 나은 방법입니다.

public static class Data {
    private String foo;
    private String bar;
}

//convert http body to Data object.
//you can also use String parameter type to get the raw json text.
@RequestMapping(value = "/greeting")
@ResponseBody
public String greetingJson(@JsonBody Data data) {
    System.out.println(data);
    return "OK";
}

사용자 정의 주석을 사용합니다.@JsonBody.

// define custom annotation
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface JsonBody {
    String encoding() default "utf-8";
}

//annotation processor for JsonBody 
@Slf4j
public class JsonBodyArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterAnnotation(JsonBody.class) != null;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
                              WebDataBinderFactory binderFactory) throws Exception {
        JsonBody annotation = parameter.getParameterAnnotation(JsonBody.class);
        assert annotation != null;
        ServletRequest servletRequest = webRequest.getNativeRequest(ServletRequest.class);
        if (servletRequest == null) {
            throw new Exception("can not get ServletRequest from NativeWebRequest");
        }
        String copy = StreamUtils.copyToString(servletRequest.getInputStream(), Charset.forName(annotation.encoding()));
        return new Gson().fromJson(copy, parameter.getGenericParameterType());
    }
}

// register the annotation processor
@Component
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new JsonBodyArgumentResolver());
    }
}

4.1 기준으로 이제 사용할 수 있습니다.RequestEntity<String> requestEntity그리고 시체에 접근하는 것은requestEntity.getBody()

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/RequestEntity.html

언급URL : https://stackoverflow.com/questions/17866996/how-to-access-plain-json-body-in-spring-rest-controller

반응형