2016-01-20 154 views
1

我知道这个问题之前已经问过了,我已经检查了Spring MVC的每条消息和406错误消息,并且我身边不知道如何解决这个问题,因为我已经尝试所有以前的答案都是第四。Spring MVC Restful 406不可接受的错误

这一个网络服务需要一个电子邮件地址,并返回一个JSON用户对象。我可以告诉你,单元测试很好。我知道我们通过了Spring Security,我们正在执行servlet ......现在唯一的问题是JSON输出......我不明白,我收到了这个错误消息。

所以,确切的说:
弹簧芯:4.2.4.RELEASE 春季安全:4.0.3.RELEASE 杰克逊更快的XML:2.6.5(核心,数据绑定,注释) 2.7.0没有按”不像是会工作尚未...

这里是用SpringMVC-servlet.xml中:

<context:annotation-config /> 
<context:component-scan base-package="com.agmednet.server.controller" /> 

<mvc:annotation-driven> 
    <mvc:message-converters register-defaults="true"> 
     <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
      <property name="objectMapper"> 
      <bean class="com.agmednet.server.HibernateAwareObjectMapper"> 

        <property name="dateFormat"> 
         <bean class="java.text.SimpleDateFormat"> 
          <constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss.SSS"></constructor-arg> 
         </bean> 
        </property> 

      </bean> 
      </property> 
     </bean> 
    </mvc:message-converters> 
</mvc:annotation-driven> 

这里是控制器:

@Controller 
@RequestMapping("/users") 
public class UserAccountController 
{ 
@Autowired 
private UserAccountService userAccountService; 

@RequestMapping(value = "/email/{email:.*}", method = RequestMethod.GET) 
public @ResponseBody UserAccountEntity getByEmailAddress(@PathVariable("email") String email) 
{ 
    Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 
    User user = null; 
    if (principal instanceof User) 
    { 
     user = ((User) principal) 
    } 
    UserAccountEntity userAccount = userAccountService.getByEmailAddress(email); 
    return userAccount; 
} 
} 

正如你所看到的,我有Accept标头设置,我有@ResponseBody注释。

我有一个SimpleCORSFilter代码在此之上:

@Component 
public class SimpleCORSFilter implements Filter 
{ 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException 
    { 
    HttpServletResponse response = (HttpServletResponse) res; 
    response.setHeader("Access-Control-Allow-Origin", "*"); 
    response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE"); 
    response.setHeader("Access-Control-Max-Age", "3600"); 
    response.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type, Accept, If-Modified-Since, openam_token"); 
    chain.doFilter(req, res); 
    } 

    public void init(FilterConfig filterConfig){} 
    public void destroy(){} 
} 

正如你所看到的,此接受我的一个“openam_token”自定义标题,但有 “接受”和“内容类型”以及。

我从防火墙后面Linux中调用这个,所以我要SSH到机器,并执行此卷曲声明:

curl -v -i -X GET -H "openam_token: AQIC5wM2LY4Sfcxfw-GSBSndg-4DMEyrEqcBgiTE4b4e3aE.*AAJTSQACMDE.*" -H "Content-Type: application/json, text/html" -H "Accept: application/json, text/html" backend.spring.mycompany.net:8080/services/api/users/email/[email protected] 

所以,在这里就是我通过卷曲的发要求:

* Trying 10.0.4.107... 
* Connected to backend.spring.agmednet.net (10.0.4.107) port 8080 (#0) 
> GET /services/api/users/email/[email protected] HTTP/1.1 
> User-Agent: curl/7.40.0 
> Host: backend.spring.agmednet.net:8080 
> openam_token: AQIC5wM2LY4Sfcxfw-GSBSndg-4DMEyrEqcBgiTE4b4e3aE.*AAJTSQACMDE.* 
> Content-Type: application/json, text/html 
> Accept: application/json, text/html 

这里是回应:

< HTTP/1.1 406 Not Acceptable 
HTTP/1.1 406 Not Acceptable 
< Server: Apache-Coyote/1.1 
Server: Apache-Coyote/1.1 
< Access-Control-Allow-Origin: * 
Access-Control-Allow-Origin: * 
< Access-Control-Allow-Methods: POST, PUT, GET, OPTIONS, DELETE 
Access-Control-Allow-Methods: POST, PUT, GET, OPTIONS, DELETE 
< Access-Control-Max-Age: 3600 
Access-Control-Max-Age: 3600 
< Access-Control-Allow-Headers: x-requested-with, Content-Type, Accept, If-Modified-Since, openam_token 
Access-Control-Allow-Headers: x-requested-with, Content-Type, Accept, If-Modified-Since, openam_token 
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate 
Cache-Control: no-cache, no-store, max-age=0, must-revalidate 
< Pragma: no-cache 
Pragma: no-cache 
< Expires: 0 
Expires: 0 
< X-XSS-Protection: 1; mode=block 
X-XSS-Protection: 1; mode=block 
< X-Frame-Options: DENY 
X-Frame-Options: DENY 
< X-Content-Type-Options: nosniff 
X-Content-Type-Options: nosniff 
< Set-Cookie: JSESSIONID=76C4B28DD0B5D88EB9341944BDBCD045; Path=/services/; HttpOnly 
Set-Cookie: JSESSIONID=76C4B28DD0B5D88EB9341944BDBCD045; Path=/services/; HttpOnly 
< Content-Type: text/html;charset=utf-8 
Content-Type: text/html;charset=utf-8 
< Content-Language: en 
Content-Language: en 
< Content-Length: 1110 
Content-Length: 1110 
< Date: Wed, 20 Jan 2016 14:30:28 GMT 
Date: Wed, 20 Jan 2016 14:30:28 GMT 


    <!DOCTYPE html> 
    <html><head> 
    <title>Apache Tomcat/8.0.30 - Error report</title> 
    </head> 
    <body> 
    <h1>HTTP Status 406 - </h1> 
    <div class="line"></div><p><b>type</b> Status report</p> 
    <p><b>message</b> <u></u></p> 
    <p><b>description</b> 
    <u>The resource identified by this request is only capable of generating 
    responses with characteristics not acceptable according to the request* 
    Connection #0 to host backend.spring.agmednet.net left intact 
    "accept" headers.</u></p> 
    <hr class="line"><h3>Apache Tomcat/8.0.30</h3></body></html> 

归根结底,这是错误的MES以上列出的鼠尾草:

The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request* Connection #0 to host backend.spring.mycompany.net left intact 

“接受”标题。

所以,我使用@ResponseBody,我使用的是最新的Jackson 2.x版本。我正在按照以前的问题提出所有建议,但仍然无法实现这个目标。

任何帮助将不胜感激。

+1

对于初学者,删除'@ EnableWebMvc'你已经拥有了''。 –

+0

如上所述,删除EnableWebMVC,为什么你想收到一个清晰的邮件地址作为路径变量..收到一个简单的字符串,并检查它是否是一个有效的电子邮件。其次,你不需要显式地添加生产和接受。 –

+0

首先....网络服务没有检查电子邮件的有效性。这是基于我们需要的,我们传递一封电子邮件,然后我们在该字段上进行数据库查询并从中返回一个用户,这是一个业务需求!其次,我明白我不需要一个“产品”,但不接受“接受”,但我会删除它,看看它是否能解决我的问题。我添加他们的唯一原因是测试出来,看看是否能解决问题,但事实并非如此。如前所述,我已经从我的控制器中删除了@EnableWebMvc。所以,我现在正在测试过程中。 – tjholmes66

回答

1

@EnableWebMVC不是问题,并且您在问题中看到的所有内容都是100%正确的。我有两个其他Web服务运行正常。这个问题最终出现在curl语句本身:

curl -v -i -X GET -H/
"openam_token: AQIC5wM2LY4Sfcxfw-GSBSndg-4DMEyrEqcBgiTE4b4e3aE.*AAJTSQACMDE.*"/
-H "Content-Type: application/json, text/html"/
-H "Accept: application/json, text/html"/
backend.spring.mycompany.net:8080/services/api/users/email/[email protected] 

如果您注意到,URL和路径变量不在引号中。 如果您注意到,电子邮件地址中有@符号,我发现这意味着要卷曲。所以,我所做的就是将我的卷曲改为以下。

curl -v -i -X GET -H/
"openam_token: AQIC5wM2LY4Sfcxfw-GSBSndg-4DMEyrEqcBgiTE4b4e3aE.*AAJTSQACMDE.*"/
-H "Content-Type: */*"/
-H "Accept: */*"/ 
"backend.spring.mycompany.net:8080/services/api/users/email/user4252002%40mycompany%2Ecom" 

1)I编码的电子邮件地址自己@到%40期点到%2E 你可以使用任何工具,你的意思是路径变量进行编码。 2)即使我正在返回一个转换成JSON的java对象,我将标题“Accept”和“Content-Type”更改为“/”。

就是这样。这工作和406错误信息消失。