with not httpmediatypenotacceptableexception could acceptable json spring spring-mvc spring-json

json - httpmediatypenotacceptableexception - not acceptable could not find acceptable representation



Spring MVC-HttpMediaTypeNotAcceptableException (12)

Sigo recibiendo este error HttpMediaTypeNotAcceptableException para las solicitudes AJAX cuando se usa con Spring MVC y JSON. El rastro de la pila completa del error es ...

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)

poco google que hice muestra que la solicitud debe contener algo así como "accept: application / json", que sí tiene ... aquí están los encabezados de solicitud de 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

Ahora estoy completamente perdido en lo que está sucediendo aquí ... ¿Qué más puede salir mal aquí para obtener este error ...


Asegúrate de agregar ambos Jars de Jackson a classpath:

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

Además, debe tener lo siguiente en su archivo Spring xml:

<mvc:annotation-driven />


Asegúrese de tener lo siguiente en su archivo 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>

y todos los artículos de su POJO deben tener getters / setters. Espero eso ayude


Como Alex insinuó en una de las respuestas, podría usar ContentNegotiationManagerFactoryBean para establecer el tipo de contenido predeterminado en "application / json", pero sentí que ese enfoque no era para mí.

Lo que intentaba hacer era publicar un formulario en un método como este

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

Lo que en cambio decidí hacer fue cambiar el encabezado "Aceptar" de la solicitud del navegador a "application / json", haciendo que SpringMVC encuentre mi método.

Uso de la API de extracción de Javascript (aún no finalizada):

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à! Ahora SpringMVC encuentra el método, valida el formulario y le permite devolver un JSON POJO.


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

Tienes este Spring @RestController y asignó una URL que contiene un correo electrónico como parte de la ruta de la URL. Has trabajado astutamente en el problema del truncamiento de puntos [1] y estás listo para rodar. Y de repente, en algunas URL, Spring devolverá un 406 [2] que dice que el navegador solicitó un cierto tipo de contenido y Spring no puede serializar la respuesta a ese tipo de contenido. El punto es que has estado haciendo aplicaciones de Spring durante años e hiciste todas las declaraciones de MVC correctamente e incluiste a Jackson y básicamente estás estancado. Peor aún, escupirá ese error solo en algunos correos electrónicos en la ruta de la URL, sobre todo los que terminan en un dominio ".com".

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

El problema [3] es bastante complicado: el servidor de aplicaciones realiza alguna negociación de contenido y convence a Spring de que el navegador solicitó un contenido de "aplicación / x-msdownload" , a pesar de que no se haya presentado en la solicitud.

La solución es especificar un administrador de negociación de contenido para el contexto de la aplicación web:

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


Debido a que este es el primer hit de Google para "HttpMediaTypeNotAcceptableException", me gustaría agregar otro problema con el que tropecé y que también dio como resultado HttpMediaTypeNotAcceptableException.

En mi caso, era un controlador que especificaba "produce", por ejemplo:

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

porque quería servir un archivo XML. Al mismo tiempo, estoy usando una clase con "@ControllerAdvice" para capturar Excepciones, por ejemplo, si no se encontró el archivo solicitado. El controlador de excepción devolvía JSON para que la aplicación cliente (angular) pudiera mostrar el mensaje de error en algún lugar del SPA.

Ahora el controlador quería devolver XML pero el manejador de excepciones devolvía JSON, por lo que se generó HttpMediaTypeNotAcceptableException. Lo resolví agregando JSON como posible valor "produce":

produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}

Espero que esto ayude a alguien más. :-)


En mi caso, solo agrega la anotación @ResponseBody para resolver este problema.


En su clase Spring @Configuration que amplía WebMvcConfigurerAdapter, anule el método configureMessageConverters, por ejemplo:

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

Y el error desaparecerá


Intenta agregar jarras "jackson-databind" a pom.xml

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

Y produces ={MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE} en @RequestMapping

Es. @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},...


Solo algo importante a tener en cuenta: las versiones Spring anteriores a 3.1.2 son compatibles con JACKSON 1.x y NO con JACKSON 2.x. Esto se debe a que al pasar de JACKSON 1.xa 2.x, se cambiaron los nombres de los paquetes de las clases. En JACKSON 1.x las clases están bajo org.codehaus.jackson mientras que en JACKSON 2.x están bajo com.fasterxml.jackson.

Para resolver este problema, comenzando con Spring 3.1.2 agregaron un nuevo MappingJackson2HttpMessageConverter para reemplazar MappingJacksonHttpMessageConverter.

Puede encontrar más detalles sobre problemas de compatibilidad en este enlace: las anotaciones de Jackson se ignoran en Spring


Tuve el mismo problema, pero me di cuenta de que, básicamente, lo que sucede cuando Spring está tratando de generar la respuesta intentará serializarlo de acuerdo con el tipo de medio que haya especificado y mediante el uso de métodos getter y setter en su clase

antes mi clase solía verse como a continuación

public class MyRestResponse{ private String message; }

la solución se ve a continuación

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

así es como me funcionó


en mi caso, favorPathExtension (falso) me ayudó

@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 protected]` } @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer .favorPathExtension(false); // to avoid HttpMediaTypeNotAcceptableException on standalone tomcat }

}


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