Spring MVC总是返回406(已经从其他论坛搜索过)

时间:2015-11-10 09:03:46

标签: spring spring-mvc

我是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天了。我不知道如何解决它。

感谢您的帮助。

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