我使用“Jsonitter”作为JSON序列化框架,我不在我的项目中使用Maven。我一直在我的restful api中返回JSON对象,直接将“Jsonitter”的结果写入HttpServletResponse
,直到现在我找到了@RestController
属性。来自ASP.Net MVC背景,我希望框架能够根据Accept
标头自动序列化我的api中的返回对象。但我觉得,Spring需要第三方序列化框架来呈现结果(即Jackson),因为它会返回HTTP Status 406 - Not Acceptable
结果。
我使用它的方式如下:
@RestController
@EnableWebMvc
public class TestApi {
@RequestMapping(value = "Test", method = RequestMethod.Get, produces = "application/json")
public List<String> letsTest(){
return myStringList;
}
}
我没有提及杰克逊,我宁愿根本不使用它,我觉得错误是由于这个原因造成的。没有杰克逊,有没有办法让这项工作?
答案 0 :(得分:4)
由于您的控制器配置为仅在客户端请求application/json
数据时返回响应,
produces = "application/json"
您可能会收到“406 Not Acceptable”,因为您的客户端请求了其他内容/未指定任何Accepts标头。你可以修理:
Accepts
标题*/*
。)这是你唯一的问题,你没有被强制使用Spring的任何Serialization框架(但如果你定义你的控制器方法来返回任意bean,则需要一个Serializer)。您可以将任何String写为对客户的响应。
如果你想继续使用Jsoniter,但是把它移到后台让你的Controller类不再明确提到jsoniter,你需要定义自己的custom HttpMessageConverter。
您需要一些Serializer来从Java生成Json。您可以编写自定义代码,或使用Jackson或Gson。 Spring默认支持Jackson,而Gson使用GsonHttpMessageConverter支持。对于Jackson,您当前的代码是可以的,但您需要添加jackson依赖项。对于Gson,您需要声明转换器,有几个资源在线解释。
与此问题的答案Does spring mvc have response.write to output to the browser directly?
一样您可以使用@ResponseBody
撰写回复。由于@RestController
已经隐含@ResponseBody
,因此您也可以将其排除在外。在此处显示只是为了澄清:
@ResponseBody // not needed with @RestController
@RequestMapping(value = "Test", method = RequestMethod.Get, produces = "application/json")
public String letsTest() {
// Using Jsoniter JsonStream
return JsonStream.serialize(myStringList);
}
答案 1 :(得分:1)
Spring 4.3.10:我使用以下设置来解决问题。
步骤1:添加以下依赖项
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.7</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.7</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
步骤2:在MVC DispatcherServlet上下文配置中添加以下内容:
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>
<bean id="contentNegotiationManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false"/>
<property name="favorParameter" value="true"/>
<property name="ignoreAcceptHeader" value="false" />
</bean>
从Spring 3.2开始,根据默认配置,favorPathExtension设置为true,因此如果请求uri具有任何适当的扩展名,如.htm
,spring将优先考虑扩展名。在第2步中,我添加了contentNegotiationManager bean来覆盖它。
答案 2 :(得分:0)
在我的案例中,方案是使用Spring restTemplate.put方法在数据库中插入pdf资源。
http:// $ {apiGateWay} /resource/provision/Test.pdf
,标题为application / pdf。但是我仍然收到406不可接受的错误。
在调试问题之后,发现put请求不接受带有的密钥。扩展名。
因此网址应为
http:// $ {apiGateWay} / resource / provision / Test