mvc:annotation-driven 不能解决 406 错误
Posted
技术标签:
【中文标题】mvc:annotation-driven 不能解决 406 错误【英文标题】:mvc:annotation-driven doesnt solve 406 error 【发布时间】:2018-02-15 12:29:15 【问题描述】:我正在尝试为 Spring 编写一个 Junit 测试用例,经过大量阅读后,我得到了一个返回 text/plain 的方法的一切工作。当我尝试返回 application/json 时遇到了问题。
关于 SO 的共识似乎是:使用mvc:annotation-driven。我试过这个(通过根据here创建下面显示的spring-web-servlet.xml。但这并没有解决我的问题。有人知道我还在做错什么吗?
spring-web-servlet.xml(在 WEB-INF 文件夹中)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:annotation-driven />
</beans>
有问题的方法(在 HelloService 类中)
@GET
@RequestMapping("/json2")
@Produces("application/json")
@ResponseBody
public Object getUserInfoJSON(@RequestParam(value="p",defaultValue="0") Integer userId)
try (Connection conn = conn())
String query = "SELECT * FROM pulse.customer WHERE userId = ?";
PreparedStatement preparedStmt = conn.prepareStatement(query);
preparedStmt.setInt(1, userId);
ResultSet rs=preparedStmt.executeQuery();
if(rs.next())
return Json.createObjectBuilder().add("login name", rs.getString("loginName"));
return Json.createObjectBuilder().add("login name", "shit broke yo!!!");
catch(SQLException s)
return "sql exception:"+s.toString();
catch (NoResultException nre)
//throw new UserNotFoundException(userId);
return "UserNotFoundException";
catch (PersistenceException e)
//throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
return "WebApplicationException";
Junit测试方法(带String的版本完美运行)
@Test
public void testUserInfoResponseJSON() throws Exception
MvcResult result=mockMvc.perform(get("/helloservice/json2?p=103")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith("application/json"))
.andReturn();
String content = result.getResponse().getContentAsString();
assertNotNull(content,"login name:jbray");
如果需要,这是我的 pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client -->
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
</dependency>
<!-- Adding RESTEasy support to Bean Validations -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-validator-provider-11</artifactId>
<version>3.1.4.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-links -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-links</artifactId>
<version>3.1.4.Final</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.6.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.ehcache/ehcache -->
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
</dependency>
<!--SPRING-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.paypal.springboot</groupId>
<artifactId>resteasy-spring-boot-starter</artifactId>
<version>2.3.3-RELEASE</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!--JUNIT-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.0.RELEASE</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.1.1</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>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
【问题讨论】:
请检查***.com/a/30549204/3530898,需要添加转换器才能将java对象转换为JSON,反之亦然<beans:bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> </beans:bean>
我将转换器添加到 spring-web-xml,但这似乎没有帮助。我还根据您链接的帖子尝试使用 ResponseEntity 。无法让它工作。
如果你得到它的工作,我会感谢你分享代码,因为我可能只是在测试时误解/错误实施了你的建议
你有什么异常吗?
我会尝试运行您的代码,但您可以先尝试保持 jackson-databind、jackson-core 和 jackson-databind 版本相同,并添加对 jackson-annotations 的依赖项,我使用的是 2.8.7在我的代码中
【参考方案1】:
我详细查看了您的依赖项和代码,发现您正在使用 Glassfish 的 JSR 353 提供程序实现。这些类是 org.glassfish.json.JsonObjectBuilderImpl$JsonObjectImpl, org.glassfish.json.JsonStringImpl, and org.glassfish.json.JsonNumberImpl, and javax.json.JsonValue$3 (an anonymous class for the value FALSE)
。
您需要更改以下代码
return Json.createObjectBuilder().add("login name", rs.getString("loginName"));
return Json.createObjectBuilder().add("login name", "shit broke yo!!!");
到
return Json.createObjectBuilder().add("login name", rs.getString("loginName")).build().toString();
return Json.createObjectBuilder().add("login name", "shit broke yo!!!").build().toString();
并将getUserInfoJSON()
方法的返回类型更改为String
。 JSR 353 类及其映射到 ObjectMapper 的详细说明可在https://***.com/a/19205116/3530898获得。
【讨论】:
我试图让该方法返回一个 JSON 对象,返回一个字符串有什么帮助?字符串是否解析为 JSON? 如果你返回 JSONObject 那么它就像一个地图然后你会看到下面的响应 "login name": "chars": "shit broke yo!!!", "string": "shit broke yo!!!", "valueType": "STRING"
而您只是试图返回 JsonObjectBuilder
的对象,因为您没有在 JSONObjectBuilder
类上调用 build()。要返回 JsonObject,您需要调用 build() 方法。以上是关于mvc:annotation-driven 不能解决 406 错误的主要内容,如果未能解决你的问题,请参考以下文章
160331使用@Controller注解为什么要配置<mvc:annotation-driven />
<mvc:annotation-driven/>与<mvc:default-servlet-handler/>之间的一个问题
如何摆脱 <mvc:annotation-driven />?
springMVC-mvc:annotation-driven