Spring 网络应用 returns HTTP 状态 406
Spring web app returns HTTP Status 406
我正在创建一个基于 spring 的基本网络应用程序:
pom 依赖项:
<properties>
<java-version>1.8</java-version>
<springframework-version>4.3.3.RELEASE</springframework-version>
<jackson-version>2.8.3</jackson-version>
<org.slf4j-version>1.7.6</org.slf4j-version>
<logback.version>1.1.7</logback.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springframework-version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<!-- Jackson JSON Mapper -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson-version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
</dependencies>
为了跳过 web.xml 的用法,我正在使用 WebApplicationInitializer:
public class AppInitializer 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.setConfigLocation(SpringModule.class.getPackage().getName());
return context;
}
这是我的 spring 配置 class:
@Configuration
@ComponentScan(basePackages = "com.company.app")
public class SpringModule extends WebMvcConfigurerAdapter {
public SpringModule() {
super();
}
private MappingJackson2HttpMessageConverter customJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
jsonConverter.setObjectMapper(objectMapper);
return jsonConverter;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
messageConverters.add(customJackson2HttpMessageConverter());
messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
messageConverters.add(new StringHttpMessageConverter());
messageConverters.add(new ByteArrayHttpMessageConverter());
messageConverters.add(new ResourceHttpMessageConverter());
messageConverters.add(new SourceHttpMessageConverter());
messageConverters.add(new FormHttpMessageConverter());
super.configureMessageConverters(messageConverters);
}
/*
* Configure ContentNegotiationManager
*/
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.ignoreAcceptHeader(true).defaultContentType(
MediaType.APPLICATION_JSON);
}
这是我的测试控制器:
@Controller
@RequestMapping(value = "/user")
public class SomeController {
@RequestMapping(value = "/", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Person helloElad() {
return new Person("some name");
}
}
测试控制器时(使用浏览器)我得到:
如果我返回一个纯字符串,它工作正常。
我尝试调试方法 configureMessageConverters
和 configureContentNegotiation
但由于某种原因它永远不会到达那里(在引导时),但我不确定它是否与问题有关。
有什么想法吗?
HTTP 406 表示您的请求内容未协商,可能是配置中未找到必要的 HTTP 消息转换器。添加基本消息转换器集的简单方法是注释您的控制器 @EnableMvc
我遇到了同样的问题,但在这里或其他地方都找不到解决方案。
我也尝试了在我的 AppConfig 上应用 @EnableMvc 的建议,但这导致了一个不同的问题,Tomcat 甚至无法成功启动。
最终,我不得不重写我的 AppInit class 如下:
https://github.com/viralpatel/spring4-restful-example/tree/master/src/main/java/net/viralpatel/spring/config
现在,当我 return 一个 POJO 时,我 JSON 回来了。我不喜欢这个修复。与此处问题中显示的 AppInit 相比,代码似乎不完整,但我没有被卡住。
我正在创建一个基于 spring 的基本网络应用程序:
pom 依赖项:
<properties>
<java-version>1.8</java-version>
<springframework-version>4.3.3.RELEASE</springframework-version>
<jackson-version>2.8.3</jackson-version>
<org.slf4j-version>1.7.6</org.slf4j-version>
<logback.version>1.1.7</logback.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springframework-version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<!-- Jackson JSON Mapper -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson-version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
</dependencies>
为了跳过 web.xml 的用法,我正在使用 WebApplicationInitializer:
public class AppInitializer 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.setConfigLocation(SpringModule.class.getPackage().getName());
return context;
}
这是我的 spring 配置 class:
@Configuration
@ComponentScan(basePackages = "com.company.app")
public class SpringModule extends WebMvcConfigurerAdapter {
public SpringModule() {
super();
}
private MappingJackson2HttpMessageConverter customJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
jsonConverter.setObjectMapper(objectMapper);
return jsonConverter;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
messageConverters.add(customJackson2HttpMessageConverter());
messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
messageConverters.add(new StringHttpMessageConverter());
messageConverters.add(new ByteArrayHttpMessageConverter());
messageConverters.add(new ResourceHttpMessageConverter());
messageConverters.add(new SourceHttpMessageConverter());
messageConverters.add(new FormHttpMessageConverter());
super.configureMessageConverters(messageConverters);
}
/*
* Configure ContentNegotiationManager
*/
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.ignoreAcceptHeader(true).defaultContentType(
MediaType.APPLICATION_JSON);
}
这是我的测试控制器:
@Controller
@RequestMapping(value = "/user")
public class SomeController {
@RequestMapping(value = "/", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Person helloElad() {
return new Person("some name");
}
}
测试控制器时(使用浏览器)我得到:
如果我返回一个纯字符串,它工作正常。
我尝试调试方法 configureMessageConverters
和 configureContentNegotiation
但由于某种原因它永远不会到达那里(在引导时),但我不确定它是否与问题有关。
有什么想法吗?
HTTP 406 表示您的请求内容未协商,可能是配置中未找到必要的 HTTP 消息转换器。添加基本消息转换器集的简单方法是注释您的控制器 @EnableMvc
我遇到了同样的问题,但在这里或其他地方都找不到解决方案。
我也尝试了在我的 AppConfig 上应用 @EnableMvc 的建议,但这导致了一个不同的问题,Tomcat 甚至无法成功启动。
最终,我不得不重写我的 AppInit class 如下: https://github.com/viralpatel/spring4-restful-example/tree/master/src/main/java/net/viralpatel/spring/config
现在,当我 return 一个 POJO 时,我 JSON 回来了。我不喜欢这个修复。与此处问题中显示的 AppInit 相比,代码似乎不完整,但我没有被卡住。