无法从 http 请求中获取 JSON
Can't get JSON from http request
我实现了一个基于 Jersey 的 RESTful 网络服务。
发送我的请求时,我首先检查是否定义了一些强制参数,如果没有,我 return 一个带有错误代码和错误消息的响应。
这是片段:
@Path( "/groups" )
@RequestScoped
@Consumes( MediaType.APPLICATION_JSON )
@Produces( value = {MediaType.APPLICATION_JSON, MediaType.TEXT_XML} )
public class GroupResource
{
...
@POST
public Response createGroup( Group group, @Context UriInfo uriInfo )
{
logger.info("-------------------");
logger.info("Create group");
logger.fine(group.toString());
logger.info("-------------------");
// check mandatory fields
if (!checkMandatoryFields(group, errorMessages))
{
return Response.status(Status.BAD_REQUEST).entity(errorMessages).build();
}
...
}
然后我实现了一个 JUnit 测试来测试它:
@Test
public void testCreateGroup()
{
try
{
URL url = new URL(URL_GROUPS_WS);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
String json2send = "{\"grid\":\"1\", \"gidNumber\":\"2\", \"groupName\":\"TestGroup\", \"groupDescription\":\"Initial description\", \"targetSystems\":[\"ADD TS1\"]}";
OutputStream os = conn.getOutputStream();
os.write(json2send.getBytes());
os.flush();
System.out.println("XXXXXXXX Sending request XXXXXXXX \n");
if (conn.getResponseCode() != 200)
{
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuffer error = new StringBuffer();
String inputLine;
while ((inputLine = in.readLine()) != null)
{
error.append(inputLine);
}
in.close();
throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode() + error.toString());
}
...
}
我的问题是我得到了 responseCode
,但我不知道如何得到错误消息,它应该在响应中的某个地方,对吗? (Response.status(Status.BAD_REQUEST).entity(**errorMessages**).build()
).
上面的代码,我检查响应代码的地方,不起作用...
你能帮帮我吗?
使用 ErrorStream 代替 InputStream -
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
如果出现错误,ErrorStream 会给你响应。
这不是正确测试 jersey 组件的方法,实际上您应该依赖 Jersey Test Framework
来测试组件,因为它隐藏了很多复杂性这样你的单元测试就很容易阅读和维护。
您当前的代码太容易出错,应该避免。
假设您使用 maven
,您需要将接下来的 2 个依赖项添加到具有 test
范围的项目中。
<dependency>
<groupId>org.glassfish.jersey.test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<version>2.24</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>2.24</version>
<scope>test</scope>
</dependency>
然后您可以简单地让您的单元测试扩展 JerseyTest
并覆盖方法 configure
以提供您的其余组件的 class,并且它已完成环境设置。它会自动启动灰熊服务器并为您绑定您的组件,因此唯一要做的就是编写您的单元测试。
你的测试class可能是这样的:
public class GroupResourceTest extends JerseyTest {
@Override
protected Application configure() {
return new ResourceConfig(GroupResource.class);
}
@Test
public void testCreateGroup() {
Group group = // create your group instance to test here
Response response = target("/groups")
.request()
.accept(MediaType.APPLICATION_JSON)
.post(Entity.entity(group, MediaType.APPLICATION_JSON));
Assert.assertEquals(Response.Status.BAD_REQUEST, response.getStatus());
Assert.assertEquals("My error message", response.readEntity(String.class));
}
}
我实现了一个基于 Jersey 的 RESTful 网络服务。 发送我的请求时,我首先检查是否定义了一些强制参数,如果没有,我 return 一个带有错误代码和错误消息的响应。 这是片段:
@Path( "/groups" )
@RequestScoped
@Consumes( MediaType.APPLICATION_JSON )
@Produces( value = {MediaType.APPLICATION_JSON, MediaType.TEXT_XML} )
public class GroupResource
{
...
@POST
public Response createGroup( Group group, @Context UriInfo uriInfo )
{
logger.info("-------------------");
logger.info("Create group");
logger.fine(group.toString());
logger.info("-------------------");
// check mandatory fields
if (!checkMandatoryFields(group, errorMessages))
{
return Response.status(Status.BAD_REQUEST).entity(errorMessages).build();
}
...
}
然后我实现了一个 JUnit 测试来测试它:
@Test
public void testCreateGroup()
{
try
{
URL url = new URL(URL_GROUPS_WS);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
String json2send = "{\"grid\":\"1\", \"gidNumber\":\"2\", \"groupName\":\"TestGroup\", \"groupDescription\":\"Initial description\", \"targetSystems\":[\"ADD TS1\"]}";
OutputStream os = conn.getOutputStream();
os.write(json2send.getBytes());
os.flush();
System.out.println("XXXXXXXX Sending request XXXXXXXX \n");
if (conn.getResponseCode() != 200)
{
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuffer error = new StringBuffer();
String inputLine;
while ((inputLine = in.readLine()) != null)
{
error.append(inputLine);
}
in.close();
throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode() + error.toString());
}
...
}
我的问题是我得到了 responseCode
,但我不知道如何得到错误消息,它应该在响应中的某个地方,对吗? (Response.status(Status.BAD_REQUEST).entity(**errorMessages**).build()
).
上面的代码,我检查响应代码的地方,不起作用...
你能帮帮我吗?
使用 ErrorStream 代替 InputStream -
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
如果出现错误,ErrorStream 会给你响应。
这不是正确测试 jersey 组件的方法,实际上您应该依赖 Jersey Test Framework
来测试组件,因为它隐藏了很多复杂性这样你的单元测试就很容易阅读和维护。
您当前的代码太容易出错,应该避免。
假设您使用 maven
,您需要将接下来的 2 个依赖项添加到具有 test
范围的项目中。
<dependency>
<groupId>org.glassfish.jersey.test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<version>2.24</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>2.24</version>
<scope>test</scope>
</dependency>
然后您可以简单地让您的单元测试扩展 JerseyTest
并覆盖方法 configure
以提供您的其余组件的 class,并且它已完成环境设置。它会自动启动灰熊服务器并为您绑定您的组件,因此唯一要做的就是编写您的单元测试。
你的测试class可能是这样的:
public class GroupResourceTest extends JerseyTest {
@Override
protected Application configure() {
return new ResourceConfig(GroupResource.class);
}
@Test
public void testCreateGroup() {
Group group = // create your group instance to test here
Response response = target("/groups")
.request()
.accept(MediaType.APPLICATION_JSON)
.post(Entity.entity(group, MediaType.APPLICATION_JSON));
Assert.assertEquals(Response.Status.BAD_REQUEST, response.getStatus());
Assert.assertEquals("My error message", response.readEntity(String.class));
}
}