我正在练习 REST 服务。我正在尝试发送 JSON(来自 org.json 库的 JSONObject),但是当我尝试在 REST 方法中读取 JSON 时,它是空的。我打印发送的 JSON 的长度并显示“0”。
REST 服务
@Path("/users")
public class UserService {
final private UserDao userDao = new UserDao();
final private UserEmailDao userEmailDao = new UserEmailDao();
final private UserPhoneDao userPhoneDao = new UserPhoneDao();
@POST
@Path("/save")
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public void save(JSONObject user) {
System.out.println(user.length()); // prints '0'
}
@PUT
@Path("/update")
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public void update(JSONObject user) {
}
@DELETE
@Path("/remove/{id}")
public void delete(@PathParam("id") Short id) {
}
@GET
@Produces(MediaType.TEXT_HTML)
@Path("/all")
public String findAll() {
System.out.println("Recuperar todos!");
return "<p>Accediendo a todos los usuarios...</p>";
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/find/{i}")
public void find(@PathParam("id") Short id) {
}
}
客户端
public class ClientTest {
public static void main(String[] args) {
Logger logger = Logger.getLogger(ClientTest.class.getName());
try {
Map<String, List<?>> user = new HashMap<>();
List<Object> userData = new ArrayList<>();
Collections.addAll(userData,
"Shaquille", "O'neil", "12345678", "06-03-1972",
"Av. desconocida #123", "28/03/2015", (Boolean) true);
user.put("user", userData);
JSONObject json = new JSONObject();
json.put("user", user);
System.out.println(json.length()); // prints '1'
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080/UsersControl/api/users/save");
Response response = target.request()
.buildPost(Entity.entity(json, MediaType.APPLICATION_JSON)).invoke();
System.out.println(response);
} catch (NullPointerException e) {
logger.warning(e.getMessage());
}
}
}
为什么会出现这种情况?我做错了什么吗?感谢您的帮助。
最佳答案
错误可能出现在您的客户端代码中。您是否尝试过使用 postman 或等效工具使用 json 字符串测试其余服务以确保其正常工作?
使用 Jersey 和 jackson 使这一切变得非常容易。
最后一个 get 方法的路径注释是 {i} 但应该是 {id}
更新
由于我最初没有用代码给出完整的答案,所以这是我的完整答案。我认为问题在于使用 JSONObject,而不是使用可由 ObjectMapper 序列化的已定义类。这是使用 Jersey/Jackson(maven 项目)的工作代码示例
首先,安装文件
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.vbranden</groupId>
<artifactId>UserWS</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.17</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.17</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
</project>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>UserRESTWS</display-name>
<servlet>
<servlet-name>User REST WS</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.vbranden.UserWSApplication</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>User REST WS</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
UserWSApplication.java
package com.vbranden;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;
public class UserWSApplication extends Application {
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(UserService.class);
return s;
}
}
现在我将定义一个可由 ObjectMapper 序列化的 UserModel 类
UserModel.java
package com.vbranden;
import java.util.List;
public class UserModel {
private String username;
private List<Object> userData;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public List<Object> getUserData() {
return userData;
}
public void setUserData(List<Object> userData) {
this.userData = userData;
}
}
现在我将创建 Web 服务并添加一个名为/testsave 的资源来测试 ClientTest 对象(看起来很有趣,但重点是测试客户端代码)
UserService.java
package com.vbranden;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.json.JSONObject;
@Path("/users")
public class UserService {
/*
final private UserDao userDao = new UserDao();
final private UserEmailDao userEmailDao = new UserEmailDao();
final private UserPhoneDao userPhoneDao = new UserPhoneDao();
*/
@POST
@Path("/save")
@Produces(MediaType.APPLICATION_JSON)
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response save(UserModel user) {
return Response.ok().entity(user).build();
}
@PUT
@Path("/update")
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public void update(UserModel user) {
}
@DELETE
@Path("/remove/{id}")
public void delete(@PathParam("id") Short id) {
}
@GET
@Produces(MediaType.TEXT_HTML)
@Path("/all")
public String findAll() {
System.out.println("Recuperar todos!");
return "<p>Accediendo a todos los usuarios...</p>";
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/find/{id}")
public void find(@PathParam("id") Short id) {
}
@GET
@Path("/testsave")
@Produces(MediaType.APPLICATION_JSON)
public Response testSave() {
ClientTest clientTest = new ClientTest();
return clientTest.test();
}
}
最后使用 UserModel 类而不是 JSONObject 更新了客户端代码
ClientTest.java
package com.vbranden;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
public class ClientTest {
public ClientTest() { }
public Response test() {
Logger logger = Logger.getLogger(ClientTest.class.getName());
try {
UserModel user = new UserModel();
user.setUsername("shaqattack");
List<Object> userData = new ArrayList<Object>();
Collections.addAll(userData, "Shaquille", "O'neil", "12345678", "06-03-1972",
"Av. desconocida #123", "28/03/2015", (Boolean) true);
user.setUserData(userData);
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080/StackOverflow-29332634/users/save");
Response response = target.request()
.buildPost(Entity.entity(user, MediaType.APPLICATION_JSON)).invoke();
System.out.println(response);
return response;
} catch (NullPointerException e) {
logger.warning(e.getMessage());
return Response.status(404).build();
}
}
}
然后使用 postman 测试其余客户端
关于java - JSON (org.json) 在发送到 REST 服务时丢失值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29332634/