programing

스프링 MVC - Http Media Type Not Acceptable예외.

instargram 2023. 4. 2. 09:42
반응형

스프링 MVC - Http Media Type Not Acceptable예외.

이 Http Media Type Not Acceptable이 계속 표시됩니다.Spring MVC 및 JSON과 함께 사용할 때 AJAX 요청에 대한 예외 오류.. 오류의 전체 스택 추적은 다음과 같습니다.

 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"과 같은 것이 포함되어 있어야 합니다.fire bug의 요청 헤더는 다음과 같습니다.

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

지금 여기서 무슨 일이 일어나고 있는지 완전히 모르겠어.여기서 또 뭐가 잘못될 수 있을까요?

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의 모든 아이템에는 getter/setter가 있어야 합니다.도움이 되었으면 좋겠다

송신원: http://georgovassilis.blogspot.ca/2015/10/spring-mvc-rest-controller-says-406.html

Spring @RestController를 사용하여 URL 경로의 일부로 이메일을 포함하는 URL을 매핑했습니다.도트 잘라내기 문제 [1]를 교묘하게 해결했습니다.이제 바로 시작할 준비가 되었습니다.그리고 갑자기 일부 URL에서 Spring은 브라우저가 특정 콘텐츠 유형을 요청했으며 Spring은 해당 콘텐츠 유형에 대한 응답을 직렬화할 수 없음을 나타내는 406 [2]를 반환합니다.요점은, 당신은 수년간 봄맞이 어플리케이션을 해왔고, 모든 MVC 선언을 제대로 했고, 잭슨도 포함시켰는데, 기본적으로 당신은 꼼짝 못하고 있다는 것입니다.게다가 이 에러는, URL 패스내의 일부의 전자 메일, 특히 「.com」도메인으로 끝나는 전자 메일에만 발생합니다.

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

문제 [3]는 매우 까다롭습니다.어플리케이션서버는 콘텐츠 네고시에이션을 실행해, 실제로 브라우저가 송신한 요구의 어디에도 없는 「어플리케이션/x-msdownload」콘텐츠를 요구했다고 Spring에게 납득시킵니다.

해결책은 웹 응용 프로그램콘텍스트의 콘텐츠네고시에이션 매니저를 지정하는 것입니다.

<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>

Classpath에 두 개의 Jackson jar를 추가해야 합니다.

  • 잭슨 코어-아슬-x.jar
  • 잭슨매퍼아슬x.jar

또한 Spring xml 파일에는 다음 내용이 포함되어 있어야 합니다.

<mvc:annotation-driven />

이는 'HttpMediaTypeNotAcceptable'의 첫 번째 구글 히트작이기 때문이다.예외"는 HttpMediaTypeNotAcceptable이 된 다른 문제를 추가합니다.예외도 있어요.

제 경우, "제품"을 지정하는 컨트롤러였습니다. 예를 들어 다음과 같습니다.

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

XML 파일을 제공하고 싶었기 때문입니다.동시에 "@ControllerAdvice"가 있는 클래스를 사용하여 예를 들어 요청된 파일을 찾을 수 없는 경우 예외를 탐지합니다.예외 핸들러가 JSON을 반환하고 있었기 때문에 클라이언트(angular) 앱이 SPA 어딘가에 오류 메시지를 표시할 수 있었습니다.

컨트롤러가 XML을 반환하려고 했는데 예외 핸들러가 JSON을 반환하고 있었기 때문에 Http MediaTypeNotAcceptable이예외가 발생했습니다.JSON을 가능한 한 "products" 가치로 추가하여 이 문제를 해결했습니다.

produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}

이것이 다른 사람에게 도움이 되기를 바랍니다. :-)

중요한 점: 3.1.2 이전 버전의 봄은 JACKON 1.x와 호환되며 JACKON 2.x와는 호환되지 않습니다.이는 JACKON 1.x에서 2.x로 클래스 패키지 이름이 변경되었기 때문입니다.잭슨 1.x 클래스는 org.codehouse.jackson 아래에 있고 잭슨 2.x 클래스는 com.fasterxml.jackson 아래에 있습니다.

이 문제에 대처하기 위해 Spring 3.1.2부터 새로운 MappingJackson2가 추가되었습니다.MappingJacksonHttpMessageConverter를 대체하는 HttpMessageConverter.

호환성 문제에 대한 자세한 내용은 이 링크에서 확인할 수 있습니다.Jackson 주석들은 봄에 무시됩니다.

경우 Path Extension(false)이 도움이 되었습니다.

@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
}

}

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");

}

그러면 오류는 사라집니다.

저도 같은 문제가 있었습니다만, 기본적으로 봄은 응답을 렌더링하려고 하면, 지정한 미디어 타입에 따라서, 클래스내에서 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;
    }
}

나는 그렇게 했다.

response.setHeader("Accept",  "application/json");

pom.xml에 "jackson-databind" jars를 추가합니다.

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

★★★★★★★★★★★★★★★★★.produces ={MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}@RequestMapping으로 합니다.

ㅇㅇ.@RequestMapping(value = "/api/xxx/{akey}/{md5}", produces ={MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE} @RequestMapping(value = "/api/contrassegno/{akey}/{md5}", produces ={MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE},...

Alex가 몇 가지 답변에서 시사한 바와 같이 Content Negotiation Manager Factory Bean을 사용하여 기본 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

엣보일라!이제 SpringMVC는 메서드를 찾아 폼을 검증하고 JSON POJO를 반환할 수 있습니다.

저 같은 경우에는 그냥 추가해주세요.@ResponseBody주석을 사용하여 이 문제를 해결합니다.

저 같은 경우에는

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

원인:

path = "/path/{VariableName}"하지만 "abc.xml"과 같은 접미사와 함께 VariableName을 전달했습니다.이 접미사는 대신 .xml을 일종의 형식 요청으로 해석합니다.정답을 참조하십시오.

저에게 문제는 접속하려는 URL이었습니다.url은 다음과 같습니다.

{{ip}}:{{port}}/{{path}}/person.html

.html로 url을 종료하면 html 이외의 payload는 받지 않습니다.엔드포인트가 정상적으로 동작하기 위해서는 .html을 끝에서 삭제해야 합니다.(url 끝에 .json을 추가할 수도 있고 동작할 수도 있습니다.)

또한 url-pattern은web.xml리소스에 액세스할 수 있도록 올바르게 구성해야 합니다.저는요

<servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

이전에 나는 가지고 있었다.*.html*엔드포인트 접속을 방해하고 있었어요

대답이라기보다 코멘트...

저는 Lombok을 사용하고 있으며 (매우) 스켈레톤 API를 개발 중이었고, 제 응답 DTO에는 (아직) 필드가 없었습니다.HttpMediaTypeNotAcceptableException통합 테스트 실행 중 오류가 발생했습니다.

응답 DTO에 필드를 추가하면 문제가 수정되었습니다.

언급URL : https://stackoverflow.com/questions/7197268/spring-mvc-httpmediatypenotacceptableexception

반응형