我是Spring的新手,使用Spring 4.2.0。我想将JSON返回给客户端。它总是向客户端返回406错误。
这是我的代码,
@RequestMapping(
value = "/account",
method = RequestMethod.GET,
headers="Accept=*/*"
)
@ResponseBody
public Object account() throws ClientProtocolException, IOException{
JSONArray result = null;
HttpGet request = new HttpGet(baseURL+"/user/accountuser/2");
request.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
request.setHeader(HttpHeaders.AUTHORIZATION, authenCode);
HttpResponse response = client.execute(request);
String json = IOUtils.toString(response.getEntity().getContent());
try {
result = new JSONArray(json); // here is a json array from 3rd services
System.out.println(result);
return result;
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
我使用
尝试了此问题Spring MVC Controller Return JSON - Error 406的解决方案 <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>
它仍然是一样的。
之后我使用
尝试了此解决方案spring mvc not returning json content - error 406 <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>
而不是解决之前,但它仍然相同。
此外,我在@RequestMapping中改变了很多东西,例如
@RequestMapping(value = "/account",method = RequestMethod.GET,headers="Accept=*/*")
@RequestMapping(value = "/account",method = RequestMethod.GET,headers="Accept=application/json")
@RequestMapping(value = "/account",method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
它也一样。
我已经面临这个问题2天了。我不知道如何解决它。
感谢您的帮助。
答案 0 :(得分:1)
我的解决方案基于Spring的RestTemplate
。这是与远程服务通信的便捷方法。只要在类路径上有必要的库,各种HttpMessageConverter
将请求/响应对象转换为常见的格式,如XML或JSON,即可开箱即用。
您的代码甚至不需要Jackson
,因为它充当第三方服务的代理。铭记于心。这是一个演示,并不打算在生产系统中使用。
@Controller
public class DemoController {
private final RestTemplate restTemplate = new RestTemplate();
private final String baseUrl = "http://localhost:8080";
@RequestMapping(value = "/account", method = GET, produces = APPLICATION_JSON_VALUE)
public void account(HttpServletResponse response) throws Exception {
ResponseEntity<Resource> exchange = restTemplate.exchange(baseUrl + "/user/accountuser/2", HttpMethod.GET, createEntity(), Resource.class);
IOUtils.copy(exchange.getBody().getInputStream(), response.getOutputStream());
}
private HttpEntity<String> createEntity() {
final HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add(AUTHORIZATION, "someCode");
httpHeaders.setContentType(APPLICATION_JSON);
return new HttpEntity<String>(httpHeaders);
}
}
因为你是Spring的新手,我把一个有效的例子推到了Github。项目演示充当第三方服务,演示webapp包含DemoController。
答案 1 :(得分:0)
可能有两件事导致此异常,缺少依赖项或返回值不是正确的java bean。您可以阅读更多here
如果您删除codehaus
个依赖关系并仅保留fasterxml
,则可以确定您具有适当的jackson
依赖关系来为转换器提供信息。
但问题是JSONArray
不是一个合适的java bean。为了使其工作,您可以简化您的方法
@RequestMapping(
value = "/account",
method = RequestMethod.GET,
produces=MediaType.APPLICATION_JSON_VALUE
)
@ResponseBody
public String account() throws ClientProtocolException, IOException{
HttpGet request = new HttpGet(baseURL+"/user/accountuser/2");
request.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
request.setHeader(HttpHeaders.AUTHORIZATION, authenCode);
HttpResponse response = client.execute(request);
String json = IOUtils.toString(response.getEntity().getContent());
return json;
}
并在xml
中注册application/json
类型
<mvc:annotation-driven >
<mvc:message-converters register-defaults="true">
<bean class = "org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven >
或在java配置中
@Override
public void configureMessageConverters(
List<HttpMessageConverter<?>> converters) {
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(
Charset.forName("UTF-8"));
stringConverter.setSupportedMediaTypes(Arrays.asList(MediaType.TEXT_PLAIN, MediaType.TEXT_HTML,
MediaType.APPLICATION_JSON));
converters.add(stringConverter);
}
您在控制器中发布新的获取请求这一事实看起来非常可疑,但我不会进入。
当您应用此解决方案时会发生这种情况,您说您的方法将生成具有json
内容类型的响应。由于该方法返回String
,因此您添加了一个配置,以便StringHttpMessageConverter
也适用于json
类型