복붙노트

[SPRING] 봄 MVC - HttpMediaTypeNotAcceptableException

SPRING

봄 MVC - HttpMediaTypeNotAcceptableException

Spring MVC와 JSON을 사용할 때 AJAX 요청에 대해이 HttpMediaTypeNotAcceptableException 오류가 계속 발생합니다 .. 오류의 전체 스택 추적은 ..

 org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.writeWithMessageConverters(AnnotationMethodHandlerAdapter.java:1032)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.handleResponseBody(AnnotationMethodHandlerAdapter.java:972)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.getModelAndView(AnnotationMethodHandlerAdapter.java:921)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:438)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:424)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:863)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:792)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:851)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:756)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

작은 인터넷 검색 요청에 "accept : application / json"과 같은 내용이 포함되어야한다는 것을 보여줍니다. 여기에는 firebug의 요청 헤더가 있습니다.

Response Headers
Server  Apache-Coyote/1.1
Content-Type    text/html;charset=utf-8
Content-Length  2503
Date    Thu, 25 Aug 2011 21:00:05 GMT
Connection  close

Request Headers
Host    localhost:8080
User-Agent  Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.20) Gecko/20110803 Firefox/3.6.20 (.NET CLR 3.5.30729)
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
Keep-Alive  115
Connection  keep-alive
X-Requested-With    XMLHttpRequest
Referer http://localhost:8080/legaldirectory/index.html
Cookie  JSESSIONID=5C97DA19AED4D5FA17F4A58470FAA93B

이제 여기서 일어나는 일에서 완전히 길을 잃었습니다. 그 밖의 무엇이 잘못되어이 오류를 얻을 수 있습니까?

해결법

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

    1.Spring XML 파일에 다음 내용이 있는지 확인하십시오.

    Spring XML 파일에 다음 내용이 있는지 확인하십시오.

    <context:annotation-config/> 
    
    <bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
     <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
      <list>
        <ref bean="jacksonMessageConverter"/>
      </list>
    </property>
    </bean>
    

    POJO의 모든 항목에는 getters / setter가 있어야합니다. 희망이 도움이된다.

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

    2.에서: http://georgovassilis.blogspot.ca/2015/10/spring-mvc-rest-controller-says-406.html

    에서: http://georgovassilis.blogspot.ca/2015/10/spring-mvc-rest-controller-says-406.html

    이 Spring @RestController가 있고 URL 경로의 일부로 전자 메일을 포함하는 URL을 매핑했습니다. 당신은 교활한 점 줄무늬 문제 [1] 주위에서 교활하게 작업했고 당신은 굴릴 준비가되었습니다. 그리고 갑자기 일부 URL에서 Spring은 브라우저가 특정 내용 유형을 요청했으며 Spring이 해당 내용 유형에 대한 응답을 직렬화 할 수 없다는 406 [2]를 반환합니다. 중요한 것은 스프링 애플리케이션을 몇 년 동안 해왔고 모든 MVC 선언을 올바로 수행했고 Jackson을 포함 시켰습니다. 기본적으로 당신은 붙어 있습니다. 더 나쁜 것은 URL 경로의 일부 전자 메일, 특히 ".com"도메인으로 끝나는 전자 메일에만 오류가 발생합니다.

    @RequestMapping(value = "/agenda/{email:.+}", method = RequestMethod.GET)
    public List<AgendaEntryDTO> checkAgenda(@PathVariable("email") String email)
    

    응용 프로그램 서버는 일부 콘텐츠 협상을 수행하고 브라우저가 실제로 제출 한 요청에 아무런 문제가 발생하지 않았지만 브라우저가 "응용 프로그램 / x-msdownload"콘텐츠를 요청했음을 확신시킵니다. [3] 문제는 매우 까다 롭습니다.

    해결책은 웹 응용 프로그램 컨텍스트에 대한 컨텐트 협상 관리자를 지정하는 것입니다.

    <mvc:annotation-driven enable-matrix-variables="true"
        content-negotiation-manager="contentNegotiationManager" />
    <bean id="contentNegotiationManager"
        class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
        <property name="defaultContentType" value="application/json" />
        <property name="favorPathExtension" value="false" />
        <property name="favorParameter" value="false" />
        <property name="parameterName" value="mediaType" />
        <property name="ignoreAcceptHeader" value="false" />
        <property name="useJaf" value="false" />
    </bean>
    
  3. ==============================

    3.Jacksonpath와 classpath를 모두 추가해야합니다.

    Jacksonpath와 classpath를 모두 추가해야합니다.

    또한, Spring xml 파일에 다음을 가져야한다.

    <mvc:annotation-driven />
    
  4. ==============================

    4.염두에 두어야 할 중요한 것 : 3.1.2 이전의 Spring 버전은 JACKSON 1.x 및 JACKSON 2.x와 호환되지 않습니다. 이것은 JACKSON 1.x에서 2.x로 변경 되었기 때문에 클래스의 패키지 이름이 변경 되었기 때문입니다. JACKSON 1.x 클래스는 org.codehaus.jackson에 있고 JACKSON 2.x에서는 com.fasterxml.jackson에 있습니다.

    염두에 두어야 할 중요한 것 : 3.1.2 이전의 Spring 버전은 JACKSON 1.x 및 JACKSON 2.x와 호환되지 않습니다. 이것은 JACKSON 1.x에서 2.x로 변경 되었기 때문에 클래스의 패키지 이름이 변경 되었기 때문입니다. JACKSON 1.x 클래스는 org.codehaus.jackson에 있고 JACKSON 2.x에서는 com.fasterxml.jackson에 있습니다.

    이 문제를 해결하기 위해 Spring 3.1.2부터 MappingJacksonHttpMessageConverter를 대체 할 새로운 MappingJackson2HttpMessageConverter를 추가했습니다.

    이 링크에서 호환성 문제에 대한 자세한 내용을 확인할 수 있습니다. Jackson 주석이 Spring에서 무시되고 있습니다.

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

    5.이것은 "HttpMediaTypeNotAcceptableException"에 대한 첫 번째 Google 히트이기 때문에 나는 HttpMediaTypeNotAcceptableException도 발생시킨 다른 문제를 추가하려고합니다.

    이것은 "HttpMediaTypeNotAcceptableException"에 대한 첫 번째 Google 히트이기 때문에 나는 HttpMediaTypeNotAcceptableException도 발생시킨 다른 문제를 추가하려고합니다.

    내 경우에는 컨트롤러가 "생산"을 지정했습니다 (예 :

    @RequestMapping(path = "/mypath/{filename}", method = RequestMethod.GET,
            produces = { MediaType.APPLICATION_XML_VALUE }
    

    XML 파일을 제공하고 싶었 기 때문입니다. 같은 시간에 예외를 잡기 위해 "@ControllerAdvice"클래스를 사용하고 있습니다. 요청한 파일을 찾을 수없는 경우 클라이언트 (각도) 앱이 SPA의 어딘가에 오류 메시지를 표시 할 수 있도록 Exception 핸들러가 JSON을 반환했습니다.

    이제 컨트롤러가 XML을 반환하려고했지만 Exception Handler가 JSON을 반환하므로 HttpMediaTypeNotAcceptableException이 발생했습니다. JSON을 가능한 한 "추가"값으로 추가하여이를 해결했습니다.

    produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}
    

    희망이 다른 사람에게 도움이됩니다. :-)

  6. ==============================

    6.내 경우 favorPathExtension (거짓) 날 도와 줬어.

    내 경우 favorPathExtension (거짓) 날 도와 줬어.

    @Configuration
    public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
    
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer
                .setUseSuffixPatternMatch(false);  // to use special character in path variables, for example, `email@dom.com`
    }
    
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer
                .favorPathExtension(false); // to  avoid HttpMediaTypeNotAcceptableException on standalone tomcat
    }
    

    }

  7. ==============================

    7.WebMvcConfigurerAdapter를 확장 한 Spring @Configuration 클래스에서 configureMessageConverters 메서드를 재정의합니다. 예를 들면 다음과 같습니다.

    WebMvcConfigurerAdapter를 확장 한 Spring @Configuration 클래스에서 configureMessageConverters 메서드를 재정의합니다. 예를 들면 다음과 같습니다.

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    
        // http
        HttpMessageConverter converter = new StringHttpMessageConverter();
        converters.add(converter);
        logger.info("HttpMessageConverter added");
    
        // string
        converter = new FormHttpMessageConverter();
        converters.add(converter);
        logger.info("FormHttpMessageConverter added");
    
        // json
        converter = new MappingJackson2HttpMessageConverter();
        converters.add(converter);
        logger.info("MappingJackson2HttpMessageConverter added");
    
    }
    

    그리고 오류는 사라질 것입니다.

  8. ==============================

    8.나는 같은 문제가 있었지만, 스프링이 응답을 렌더링하려고 할 때 기본적으로 어떤 일이 일어 났는지를 알아 냈습니다. 지정한 미디어 유형에 따라 직렬화하려고 시도하고 클래스의 getter 및 setter 메서드를 사용하여 시도합니다.

    나는 같은 문제가 있었지만, 스프링이 응답을 렌더링하려고 할 때 기본적으로 어떤 일이 일어 났는지를 알아 냈습니다. 지정한 미디어 유형에 따라 직렬화하려고 시도하고 클래스의 getter 및 setter 메서드를 사용하여 시도합니다.

    내 수업이 아래처럼 보일 때까지

    public class MyRestResponse{
        private String message;
    }
    

    솔루션은 아래처럼 보입니다.

    public class MyRestResponse{
        private String message;
        public void setMessage(String msg){
            this.message = msg;
        }
        public String getMessage(){
            return this.message;
        }
    }
    

    그게 내게 효과가 있었어.

  9. ==============================

    9.pom.xml에 "jackson-databind"항아리를 추가하십시오.

    pom.xml에 "jackson-databind"항아리를 추가하십시오.

    `<dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson.databind-version}</version>
    </dependency>`
    

    @RequestMapping으로 = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}을 (를) 만듭니다.

    Es. @RequestMapping (value = "/ api / xxx / {akey} / {md5}")은 = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE} @RequestMapping (value = "/ api / contrassegno / {akey} / {md5}")은 = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}을 생성합니다.

  10. ==============================

    10.Alex가 대답 중 하나를 암시 했으므로 ContentNegotiationManagerFactoryBean을 사용하여 기본 content-type을 "application / json"으로 설정할 수있었습니다. 그러나 그 접근 방식이 저에게 맞지 않는다고 생각했습니다.

    Alex가 대답 중 하나를 암시 했으므로 ContentNegotiationManagerFactoryBean을 사용하여 기본 content-type을 "application / json"으로 설정할 수있었습니다. 그러나 그 접근 방식이 저에게 맞지 않는다고 생각했습니다.

    내가하려는 것은이 같은 메소드에 폼을 게시하는 것이 었습니다.

    @RequestMapping(value = "/post/to/me", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
        public @ResponseBody MyJsonPOJO handlePostForm(@Valid @ModelAttribute("form") ValidateMeForm form, BindingResult bindingResult) throws ApiException {
    

    대신 브라우저에서 요청의 "Accept"헤더를 "application / json"으로 변경하여 SpringMVC가 내 메소드를 찾도록했습니다.

    아직 완성되지 않은 Javascript Fetch API 사용 :

    var form = new FormData();
    form.append("myData", "data");
    
    let fetchConfig = {
        method: "POST",
        body: form,
        headers: {"Accept": "application/json"}
    };
    
    fetch("/post/to/me", fetchConfig)
        .then(... // Javascript Promise API here
    

    Et voilà! 이제 SpringMVC는 메소드를 찾고 양식의 유효성을 검사하며 JSON POJO를 반환 할 수있게합니다.

  11. ==============================

    11.내 경우에는이 문제를 해결하기 위해 @ResponseBody 주석을 추가하십시오.

    내 경우에는이 문제를 해결하기 위해 @ResponseBody 주석을 추가하십시오.

  12. ==============================

    12.나의 경우에는

    나의 경우에는

     {"timestamp":1537542856089,"status":406,"error":"Not Acceptable","exception":"org.springframework.web.HttpMediaTypeNotAcceptableException","message":"Could not find acceptable representation","path":"/a/101.xml"}
    

    원인 :

    path = "/ path / {Variable Name}"하지만 변수 이름에 "abc.xml"과 같은 접미사를 사용하여 전달했습니다.이 클래스는 .xml을 일종의 형식 요청으로 해석합니다. 거기서 답을보십시오.

  13. ==============================

    13.

    response.setHeader("Accept",  "application/json");
    
  14. from https://stackoverflow.com/questions/7197268/spring-mvc-httpmediatypenotacceptableexception by cc-by-sa and MIT license