복붙노트

[SPRING] POST에서 빈 문자열을 제공하는 Spring @RequestBody

SPRING

POST에서 빈 문자열을 제공하는 Spring @RequestBody

@RequestBody를 사용하여 게시물의 전체 내용을 가져 오려고하는 Spring 3.0.5.RELEASE가있는 응용 프로그램이 있습니다. 메서드가 호출되었지만 전달 된 문자열은 항상 비어 있습니다. 중단 점을 배치하여 StringHttpMessageConverter가 호출되었지만 내부 HttpInputMessage가 비어 있는지 확인했습니다.

Jetty와 Tomcat 모두에서이 문제를 보았습니다. 따라서 컨테이너와 관련된 문제는 폐기합니다.

다음은 샘플 컨트롤러입니다.

@Controller
@RequestMapping("/")
public class SubscriptionController {
    @RequestMapping(value = "/requestbody", method = RequestMethod.POST)
    public ModelAndView mycustomAction(@RequestBody String body) {

        // body is always empty
        Logger.getLogger(this.getClass()).debug("REQUEST BODY '" + body + "'");
        return new ModelAndView("empty");
    }
}

내 응용 프로그램 컨텍스트는 다음과 같이 정의됩니다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <!-- Enable auto detection of controllers -->
    <context:component-scan base-package="com.big.viajerotelcel.controller" />

    <!--
        use annotation driven mvc and one single validator with JSR-303
        standard
    -->
    <mvc:annotation-driven />

    <!--
        Message source for this context, loaded from localized "messages_xx"
        files
    -->

    <bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames" value="classpath:i18n/messages" />
        <property name="defaultEncoding" value="UTF-8" />
    </bean>

    <!-- Declare the Interceptor -->
    <mvc:interceptors>
        <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"
            p:paramName="locale" />
    </mvc:interceptors>

    <!-- Declare the Resolver -->
    <bean id="localeResolver"
        class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />

    <!-- will load Tiles definitions! -->
    <bean id="tilesConfigurer"
        class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/general.xml</value>
            </list>
        </property>
    </bean>

    <!-- Tiles view resolver -->
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.tiles2.TilesView" />
    </bean>

    <!-- Configure the multipart resolver -->
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--
            one of the properties available; the maximum file size in bytes (5MB)
        -->
        <property name="maxUploadSize" value="5120000" />
    </bean>

    <!-- Adding these lines has no effect, the StringHttpMessageConverter is called either way -->
<!--    <bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter"/>-->
<!--           -->
<!--    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">-->
<!--        <property name="messageConverters">-->
<!--          <list>-->
<!--            <ref bean="stringHttpMessageConverter"/>-->
<!--          </list>-->
<!--        </property>-->
<!--    </bean>-->
</beans>

curl을 사용하여 다음과 같이 테스트합니다.

어떤 아이디어 나 도움이 환영받는 것 이상입니다!

해결법

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

    1.ServletServerHttpRequest의 코드 스 니펫은 HttpInputMessage를 확장 한 것입니다. 나는 이것이 당신이 당신의 코드에서 사용하고있는 구현 인 것을 매우 긍정적이다 :

    ServletServerHttpRequest의 코드 스 니펫은 HttpInputMessage를 확장 한 것입니다. 나는 이것이 당신이 당신의 코드에서 사용하고있는 구현 인 것을 매우 긍정적이다 :

    public InputStream getBody() throws IOException {
        return this.servletRequest.getInputStream();
    }
    

    즉, 요청 본문은 HttpServletRequest 객체의 입력 스트림으로 읽혀지기위한 것입니다.

    요청의 입력 스트림은 여러 상황에서 유효하지 않지만 현재로서는 올바른 설명서를 찾을 수 없습니다. 예를 들어 post 요청에서 request.getParameter ()를 호출하면 매개 변수를 해석하기 위해 입력 스트림을 읽어야하므로 입력 스트림을 읽은 후 이미 끝까지 도달했기 때문에 비어 있습니다.

    아마도 당신은 interceptor 어딘가에서 getParameter를 호출하거나 아마도 web.xml에 정의 된 필터를 호출하고있을 것입니다. 또 다른 옵션은 Spring이 당신을 위해 그렇게하고 있다는 것입니다. 예를 들어, 컨트롤러가 복잡한 @RequestMappings (param 값 또는 헤더 값 읽기)과 같은 다른 메소드를 가지고있는 경우입니다.

    두 가지 제안이 있습니다.

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

    2.어떻게이 URL에 메시지를 게시하고 있습니까? HTTP 요청에 사용자가 생각하는 내용이 포함되어 있다고 긍정적입니까? 그림에서 웹 브라우저를 제거하고 꼬집음 같이 낮은 수준의 항목으로 드롭하여 모든 유형의 HTTP 메시지를 직접 보낼 수 있도록하는 것이 좋습니다.

    어떻게이 URL에 메시지를 게시하고 있습니까? HTTP 요청에 사용자가 생각하는 내용이 포함되어 있다고 긍정적입니까? 그림에서 웹 브라우저를 제거하고 꼬집음 같이 낮은 수준의 항목으로 드롭하여 모든 유형의 HTTP 메시지를 직접 보낼 수 있도록하는 것이 좋습니다.

  3. ==============================

    3.비슷한 문제가있었습니다 - 스프링 컨트롤러가받은 문자열이 항상 비어있었습니다. 내 봄 설정으로 땜질 받았지만 아무런 결과도 없었습니다. 마침내 문제는 클라이언트가 실제로 아무것도 몸을 보내지 않고 있었다라는 것이었다! (나의 약간의 오타 때문에)

    비슷한 문제가있었습니다 - 스프링 컨트롤러가받은 문자열이 항상 비어있었습니다. 내 봄 설정으로 땜질 받았지만 아무런 결과도 없었습니다. 마침내 문제는 클라이언트가 실제로 아무것도 몸을 보내지 않고 있었다라는 것이었다! (나의 약간의 오타 때문에)

    비슷한 오류가 발견되면 클라이언트의 페이로드가 실제로 비어 있지 않은지 한 번 확인해 볼 가치가 있습니다.

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

    4.XML이 JAXB 객체에 정렬되지 않는 또 다른 이유는 XML의 네임 스페이스와 관련이 있습니다.

    XML이 JAXB 객체에 정렬되지 않는 또 다른 이유는 XML의 네임 스페이스와 관련이 있습니다.

    1.8.101 이후의 Java 버전은 네임 스페이스가 적용된 XML을 구문 분석하는 데 더욱 엄격합니다. Java를 1.8.0_77에서 1.8.0_121로 업데이트 한 후 JAXB가 언 마샬링하지 않음을 참조하십시오.

    내 경우 엔 모든 null과 XML 파싱이 실패했음을 나타 내기 위해 예외가 발생하지 않는 요청 본문을보고있었습니다.

  5. from https://stackoverflow.com/questions/5806724/springs-requestbody-providing-empty-string-on-post by cc-by-sa and MIT license