program story

406을받는 Spring JSON 요청 (허용되지 않음)

inputbox 2020. 10. 4. 11:00
반응형

406을받는 Spring JSON 요청 (허용되지 않음)


이것은 내 자바 스크립트입니다.

    function getWeather() {
        $.getJSON('getTemperature/' + $('.data option:selected').val(), null, function(data) {
            alert('Success');                               
        });
    }

이것은 내 컨트롤러입니다.

@RequestMapping(value="/getTemperature/{id}", headers="Accept=*/*", method = RequestMethod.GET)
@ResponseBody
public Weather getTemparature(@PathVariable("id") Integer id){
    Weather weather = weatherService.getCurrentWeather(id);
        return weather;
}

spring-servlet.xml

<context:annotation-config />
<tx:annotation-driven />

이 오류가 발생합니다.

GET http://localhost:8080/web/getTemperature/2 406 (Not Acceptable)

헤더 :

응답 헤더

Server  Apache-Coyote/1.1
Content-Type    text/html;charset=utf-8
Content-Length  1070
Date    Sun, 18 Sep 2011 17:00:35 GMT

요청 헤더

Host    localhost:8080
User-Agent  Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
Accept  application/json, text/javascript, */*; q=0.01
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip, deflate
Accept-Charset  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection  keep-alive
X-Requested-With    XMLHttpRequest
Referer http://localhost:8080/web/weather
Cookie  JSESSIONID=7D27FAC18050ED84B58DAFB0A51CB7E4

흥미로운 메모 :

406 오류가 발생하지만 동시에 최대 절전 모드 쿼리가 작동합니다. 드롭 박스에서 선택 항목을 변경할 때마다 Tomcat 로그에 다음과 같이 표시됩니다.

 select weather0_.ID as ID0_0_, weather0_.CITY_ID as CITY2_0_0_, weather0_.DATE as DATE0_0_, weather0_.TEMP as TEMP0_0_ from WEATHER weather0_ where weather0_.ID=?

문제가 무엇일까요? 이전에 두 개의 유사한 질문이 있었는데 거기에서 받아 들인 모든 힌트를 시도했지만 작동하지 않았습니다 ...

어떤 제안? 언제든지 질문하십시오 ...


406 허용되지 않음

요청에 의해 식별 된 리소스는 요청에서 전송 된 수락 헤더에 따라 허용되지 않는 콘텐츠 특성을 가진 응답 엔티티 만 생성 할 수 있습니다.

따라서 요청 수락 헤더는 application / json이고 컨트롤러는이를 반환 할 수 없습니다. 이는 @ResponseBody 주석이 달린 반환 값을 만족시키는 올바른 HTTPMessageConverter를 찾을 수 없을 때 발생합니다. HTTPMessageConverter는 <mvc:annotation-driven>클래스 경로의 특정 3D 파티 라이브러리 를 사용할 때 자동으로 등록됩니다 .

클래스 경로에 올바른 Jackson 라이브러리가 없거나 <mvc:annotation-driven>지시문을 사용하지 않았습니다 .

시나리오를 성공적으로 복제했으며이 두 라이브러리를 사용하고 headers="Accept=*/*"지시문을 사용하지 않고 정상적으로 작동했습니다 .

  • jackson-core-asl-1.7.4.jar
  • jackson-mapper-asl-1.7.4.jar

최신 Spring 4.1.1부터 pom.xml에 다음 항아리를 추가 해야하는 동일한 문제가 발생했습니다.

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.4.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.4.1.1</version>
</dependency>

또한 다음 병이 있는지 확인하십시오.

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.13</version>
</dependency>

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

406 Spring MVC Json, 요청 "accept"헤더에 따라 허용되지 않음


이 상태가 반환되는 또 다른 경우가 있습니다. Jackson 매퍼가 Bean을 직렬화하는 방법을 알아낼 수없는 경우입니다. 예를 들어 동일한 부울 속성에 대해 두 개의 접근 자 메서드가있는 경우 isFoo()getFoo().

무슨 일이 일어나고 있는지 Spring의 MappingJackson2HttpMessageConverter 가 Jackson의 StdSerializerProvider호출 하여 객체를 변환 할 수 있는지 확인합니다. 호출 체인의 맨 아래에 StdSerializerProvider._createAndCacheUntypedSerializer을 던졌습니다 JsonMappingException유익한 메시지와 함께. 그러나이 예외는 StdSerializerProvider._createAndCacheUntypedSerializer객체를 변환 할 수 없음을 Spring에 알리는에 의해 삼켜집니다 . 변환기가 부족한 Spring Accept은 사용할 수 있는 헤더 가 제공되지 않는다고보고합니다 . 이는 물론 */*.

이 동작에 대한 버그 가 있지만 "재현 할 수 없음"으로 닫혔습니다. 호출되는 메서드가 throw 할 수 있다고 선언하지 않았으므로 예외를 삼키는 것이 적절한 해결책입니다 (예, 풍자였습니다). 불행히도 Jackson은 로깅이 없습니다. 그리고 코드베이스에 많은 코멘트가 있습니다. 그래서 이것이 유일한 숨겨진 문제는 아니라고 생각합니다.


나는 나의 컨트롤러 방법이 실행을 같은 문제를했지만, 응답 오류 (406) I 디버그이며 AbstractMessageConverterMethodProcessor#writeWithMessageConverters그 방법을 발견 ContentNegotiationManager#resolveMediaTypes항상 반환 text/html을 지원하지 않습니다 MappingJacksonHttpMessageConverter. 문제는 org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy이전 작업이 수행 org.springframework.web.accept.HeaderContentNegotiationStrategy되었으며 요청의 확장이 /get-clients.html오류 406 문제의 원인이라는 것 /get-clients입니다. 요청 URL을 .


다음 2 jar가 클래스 경로에 있는지 확인하십시오 .

하나 또는 둘 다 누락 된 경우이 오류가 발생합니다.

jackson-core-asl-1.9.X.jar jackson-mapper-asl-1.9.X.jar

마지막으로 여기에서 답변을 찾았습니다.

편안한 아약스 요청을 스프링에 매핑

나는 인용한다 :

@ RequestBody / @ ResponseBody 주석은 일반 뷰 리졸버를 사용하지 않고 자체 HttpMessageConverters를 사용합니다. 이러한 주석을 사용하려면 참조에 설명 된대로 AnnotationMethodHandlerAdapter에서 이러한 변환기를 구성해야합니다 (MappingJacksonHttpMessageConverter가 필요할 수 있음).


<mvc:annotation-driven />dispatcherservlet.xml을 추가하지 않은 경우 체크인하십시오 . 그리고 추가

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.13</version>
</dependency>

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

pom.xml의 이러한 종속성


<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-base</artifactId>
    <version>2.6.3</version>
</dependency>

컨트롤러에서 응답 본문 주석이 반환 유형에 있어야하고 메소드가 아니어야합니다.

@RequestMapping(value="/getTemperature/{id}", headers="Accept=*/*", method = RequestMethod.GET)
public @ResponseBody Weather getTemparature(@PathVariable("id") Integer id){
    Weather weather = weatherService.getCurrentWeather(id);
        return weather;
}

또한 원시 jquery.ajax 함수를 사용하고 contentType 및 dataType이 올바르게 설정되었는지 확인합니다.

다른 메모에서 json의 스프링 처리가 다소 문제가 있음을 발견했습니다. 문자열과 GSON을 사용하여 모든 작업을 수행했을 때 더 쉬웠습니다.


@atott가 언급했듯이 .

pom.xml에 최신 버전의 Jackson을 추가하고 Spring 4.0 이상을 사용 @ResponseBody하여 작업 방법을 사용하고으로 @RequestMapping구성한 경우 produces="application/json;charset=utf-8"에도 여전히 406 (Not Acceptable)이 표시됩니다. MVC DispatcherServlet 컨텍스트 구성 :

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />

<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false" />
</bean>

그것이 내가 마침내 내 문제를 해결 한 방법입니다.


Spring 4.3.10 : 아래 설정을 사용하여 문제를 해결했습니다.

1 단계 : 아래 종속성 추가

    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.6.7</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.6.7</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.13</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

2 단계 : MVC DispatcherServlet 컨텍스트 구성에 아래를 추가합니다.

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>

<bean id="contentNegotiationManager"
    class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false"/>
    <property name="favorParameter" value="true"/>
    <property name="ignoreAcceptHeader" value="false" />
</bean>

스프링 3.2 이후, 기본 구성에 따라 favorPathExtension은 true로 설정됩니다.이 때문에 요청 uri에 .htmspring 과 같은 적절한 확장이 있으면 확장에 우선 순위를 부여합니다. 2 단계에서이를 재정의하기 위해 contentNegotiationManager 빈을 추가했습니다.


아마도 아무도 여기까지 스크롤하지 않지만 위의 솔루션 중 어느 것도 나를 위해 수정 public하지 않았지만 모든 getter 메서드를 만들었습니다.

나는 getter 가시성을 package-private로 남겨 두었습니다. Jackson은 그들을 찾을 수 없다고 결정하고 폭발했습니다. ( @JsonAutoDetect(getterVisibility=NON_PRIVATE)일부 고정 만 사용 합니다.


전송 된 객체 (이 경우 날씨)에 getter / setter가 포함되어 있는지 확인하십시오.


@EnableWebMvc 주석이 없기 때문에 동일한 문제가 발생했습니다. (내 모든 스프링 구성은 주석 기반이며 XML에 해당하는 것은 mvc : annotation-driven입니다)


클래스 경로에 올바른 jackson 버전이 있는지 확인하십시오.


@joyfun이 jackson의 올바른 버전을 확인했지만 헤더도 확인하십시오 ... 수락 / 클라이언트가 전송하지 않을 수 있습니다 ... 방화 버그 또는 동등한 것을 사용하여 get 요청이 실제로 보내는 것을 확인하십시오. 내가 100 % 확실하지는 않지만 주석 / may /의 headers 속성이 리터럴을 검사하고 있다고 생각합니다.


Other then the obvious problems I had another one that I couldn't fix regardless of including all possible JARs, dependancies and annotations in Spring servlet. Eventually I found that I have wrong file extension by that I mean I had two separate servlet running in same container and I needed to map to different file extensions where one was ".do" and the other as used for subscriptions was randomly named ".sub". All good but SUB is valid file extension normally used for films subtitle files and thus Tomcat was overriding the header and returning something like "text/x-dvd.sub..." so all was fine but the application was expecting JSON but getting Subtitles thus all I had to do is change the mapping in my web.xml file I've added:

<mime-mapping>
    <extension>sub</extension>
    <mime-type>application/json</mime-type>
</mime-mapping>

I had the same problem unfortunately non of the solution here solved my problem as my problem was something in a different class.

I first checked that all dependencies are in place as suggested by @bekur then I checked the request/response that travels from clients to the server all headers was in place an properly set by Jquery. I then checked the RequestMappingHandlerAdapter MessageConverters and all 7 of them were in place, I really started to hate Spring ! I then updated to from Spring 4.0.6.RELEASE to 4.2.0.RELEASE I have got another response rather than the above. It was Request processing failed; nested exception is java.lang.IllegalArgumentException: No converter found for return value of type

Here is my controller method

  @RequestMapping(value = "/upload", method = RequestMethod.POST,produces = "application/json")
    public ResponseEntity<UploadPictureResult> pictureUpload(FirewalledRequest initialRequest) {

        DefaultMultipartHttpServletRequest request = (DefaultMultipartHttpServletRequest) initialRequest.getRequest();

        try {
            Iterator<String> iterator = request.getFileNames();

            while (iterator.hasNext()) {
                MultipartFile file = request.getFile(iterator.next());
                session.save(toImage(file));
            }
        } catch (Exception e) {
            return new ResponseEntity<UploadPictureResult>(new UploadPictureResult(),HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity<UploadPictureResult>(new UploadPictureResult(), HttpStatus.OK);
    } 




    public class UploadPictureResult extends WebResponse{

    private List<Image> images;

    public void setImages(List<Image> images) {
        this.images = images;
    }
}






    public class WebResponse implements Serializable {


    protected String message;

    public WebResponse() {
    }

    public WebResponse(String message) {

        this.message = message;
    }


    public void setMessage(String message) {
        this.message = message;
    }
}

The solution was to make UploadPictureResult not to extend WebResponse

For some reason spring was not able to determine the how to convert UploadPictureReslt when it extended WebResponse


<dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.8.0</version>
    </dependency>

i don't use ssl authentication and this jackson-databind contain jackson-core.jar and jackson-databind.jar, and then change the RequestMapping content like this:

@RequestMapping(value = "/id/{number}", produces = "application/json; charset=UTF-8", method = RequestMethod.GET)
public @ResponseBody Customer findCustomer(@PathVariable int number){
    Customer result = customerService.findById(number);
    return result;
}

attention: if your produces is not "application/json" type and i had not noticed this and got an 406 error, help this can help you out.


check this thread. spring mvc restcontroller return json string p/s: you should add jack son mapping config to your WebMvcConfig class

@Override protected void configureMessageConverters( List<HttpMessageConverter<?>> converters) { // put the jackson converter to the front of the list so that application/json content-type strings will be treated as JSON converters.add(new MappingJackson2HttpMessageConverter()); // and probably needs a string converter too for text/plain content-type strings to be properly handled converters.add(new StringHttpMessageConverter()); }


This is update answer for springVersion=5.0.3.RELEASE.

Those above answers will be only worked older springVersion < 4.1 version. for latest spring you have to add following dependencies in gradle file:

compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: fasterxmljackson
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: fasterxmljackson

fasterxmljackson=2.9.4

I hope this will be helpful for who using latest spring version.


Can you remove the headers element in @RequestMapping and try..

Like


@RequestMapping(value="/getTemperature/{id}", method = RequestMethod.GET)

I guess spring does an 'contains check' rather than exact match for accept headers. But still, worth a try to remove the headers element and check.

참고URL : https://stackoverflow.com/questions/7462202/spring-json-request-getting-406-not-acceptable

반응형