可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am using Spring MVC with JSON as specified in Ajax Simplification Spring 3.0 article.
After so many attempts and variations of my code depending on advice found on various forums, my code still doesn't work.
I keep on getting the following error: (406) The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers ().
I have in my appconfig.xml as required.
app-config.xml
<context:component-scan base-package="org.ajaxjavadojo" />
<!-- Configures Spring MVC -->
<import resource="mvc-config.xml" />
mvc-config.xml
<mvc:annotation-driven />
<!-- Forwards requests to the "/" resource to the "index" view -->
<mvc:view-controller path="/" view-name="index"/>
<!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="html" value="text/html"/>
<entry key="json" value="application/json"/>
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</list>
</property>
</bean>
This is what I have for my controller
@Controller
@RequestMapping (value = "/convert")
public class ConversionController {
@RequestMapping(method=RequestMethod.GET)
public String getConversionForm(){
return "convertView";
}
@RequestMapping(value = "/working", headers="Accept=application/json", method=RequestMethod.GET)
public @ResponseBody Conversion getConversion(){
Conversion d = new Conversion("d");
return d;
}
}
jsp jquery call
function convertToDecimal(){
$.getJSON("convert/working", {key: "r"}, function(aConversion){
alert("it worked.");
$('#decimal').val(aConversion.input);
});
}
I would really appreciate any input on this issue.
Thank you
回答1:
Try remove the header limitation for Accept
, put a breakpoint and see what's the actual value. Or do this with FireBug.
Also take a look at this jquery issue
回答2:
To return JSON response from @ResponseBody
-annotated method, you need two things:
<mvc:annotation-driven />
(you already have it)
- Jackson JSON Mapper in the classpath
You don't need ContentNegotiatingViewResolver
and headers
in @RequestMapping
.
回答3:
I had this problem after I upgraded Spring to 4.1.x from 3.2.x. I fixed by upgrading Jackson from 1.9.x to 2.2.x (fasterxml)
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.2.3</version>
</dependency>
回答4:
Add org.springframework.http.converter.json.MappingJacksonHttpMessageConverter
and org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
to DispatcherServlet-servlet.xml. and refer to the the first one in the second using
<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>
回答5:
I too got this error and while debugging deep down into the rabbit hole i came across this exception
java.lang.IllegalArgumentException: Conflicting getter definitions for property "error": com.mycomp.model.OutputJsonModel#isError(0 params) vs com.mycomp.model.OutputJsonModel#getError(0 params)
So basically in my java bean i had something like the following:
private boolean isError;
private ErrorModel error;
public ErrorModel getError() {
return error;
}
public void setError(ErrorModel error) {
this.error = error;
}
public boolean isError() {
return isError;
}
public void setError(boolean isError) {
this.isError = isError;
}
Changing one of the error member variable name to something else solved the issues.
回答6:
I had this problem too, you have to add <mvc:annotation-driven />
in your configuration xml
and
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.databind-version}</version>
</dependency>
in your pom.xml
回答7:
I have used java configuration and i got this same error. I have missed to add the @EnableWebMvc to the configuration file. This error is resolved after i add the @EnableWebMvc in my webconfig file.
Also the Object that is returned from your Spring Controller, should have proper getter and setter methods.
package com.raghu.dashboard.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import com.raghu.dashboard.dao.ITaskDAO;
import com.raghu.dashboard.dao.TaskDAOImpl;
@Configuration
@EnableWebMvc //missed earlier...after adding this it works.no 406 error
@ComponentScan(basePackages = { "com.raghu.dashboard.api", "com.raghu.dashboard.dao" })
public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() { return null;}
protected Class<?>[] getServletConfigClasses() {
return new Class[] { MongoConfiguration.class};
}
protected String[] getServletMappings() {
return new String[]{"*.htm"};
}
@Bean(name = "taskDao")
public ITaskDAO taskDao() {
return new TaskDAOImpl();
}
@Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/pages/");
resolver.setSuffix(".jsp");
return resolver;
}
}
AppInitializer.java
package com.raghu.dashboard.config;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class AppInitalizer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext)
throws ServletException {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/*");
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(com.raghu.dashboard.config.WebConfig.class);
context.scan("com.raghu.dashboard.api");
return context;
}
}
Also make sure the Object that is returned, has the proper getter and setter.
Example:
@RequestMapping(value = "/list", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<TaskInfo> findAll() {
logger.info("Calling the findAll1()");
TaskInfo taskInfo = dashboardService.getTasks();
HttpHeaders headers = new HttpHeaders();
headers.add("Access-Control-Allow-Origin", "*");
ResponseEntity<TaskInfo> entity = new ResponseEntity<TaskInfo>(taskInfo,
headers, HttpStatus.OK);
logger.info("entity is := " + entity);
return entity;
}
TaskInfo object should have proper getter and setter. if not, 406 error will be thrown.
POM File for Reference:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.raghu.DashBoardService</groupId>
<artifactId>DashBoardService</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>DashBoardService Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<!-- Spring -->
<spring-framework.version>4.0.6.RELEASE</spring-framework.version>
<jackson.version>2.4.0</jackson.version>
<jaxb-api.version>2.2.11</jaxb-api.version>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>2.10.1</version>
</dependency>
<!-- Spring Data Mongo Support -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.4.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-dao</artifactId>
<version>2.0.3</version>
</dependency>
<!-- Jackson mapper -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>1.7.1</version>
</dependency>
<!-- Log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>1.5.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<finalName>DashBoardService</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
回答8:
issue is not related to jquery . even bug is saying it is server side issue . please make sure that following 2 jar present in class path :-
jackson-core-asl-1.9.X.jar
jackson-mapper-asl-1.9.X.jar
回答9:
I also faced this same issue and I downloaded this [jar]: (http://www.java2s.com/Code/Jar/j/Downloadjacksonall190jar.htm)! and placed in lib folder and the app works like a charm :)
回答10:
See my answer to a similar problem here with Spring MVC interpreting the extension of the URI and changing the expected MIME type produced behind the scene, therefore producing a 406.
回答11:
Well, The answers on this page might be right but they didn't expatiate well. This is what I did
I added this to my pom.xml
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.8</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.8</version>
</dependency>
Then I added headers to my RequestMapping like below
@RequestMapping(value="/admin/getGallery", method = RequestMethod.GET, headers={"Content-Type=application/json"})
Then in my jquery ajax I added - contentType: "application/json", so it looks like
jQuery.ajax({
type:'GET',
url:"getGallery.html",
data: "designId="+designId,
processData:false,
contentType: "application/json",
//dataType: "json",
success:function(data){
console.log(data);
},
error : function(e) {
console.log("ERROR: ", e);
},
});
Then in my servlet I added
<bean id="jsonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
<!-- Bind the return value of the Rest service to the ResponseBody. -->
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<util:list id="beanList">
<ref bean="jsonHttpMessageConverter" />
</util:list>
</property>
</bean>
If you have problem with util tag in your servlet just just add in the same servlet file
xmlns:util="http://www.springframework.org/schema/util"
and
xsi:schemaLocation="http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd
回答12:
As said by axtavt, mvc:annotation-driven and jackson JSON mapper are all that you need. I followed that and got my application to return both JSON and XML strings from the same method without changing any code, provided that there are @XmlRootElement and @XmlElement in the object you are returning from the controller. The difference was in the accept parameter passed in the request or header. To return xml, any normal invocation from the browser will do it, otherwise pass the accept as 'application/xml'. If you want JSON returned, use 'application/json' in the accept parameter in request.
If you use firefox, you can use tamperdata and change this parameter
回答13:
Using jQuery , you can set contentType to desired one (application/json; charset=UTF-8' here) and set same header at server side.
REMEMBER TO CLEAR CACHE WHILE TESTING.
回答14:
Instead of @RequestMapping(...headers="Accept=application/json"...)
use @RequestMapping(... , produces = "application/json")