java - JSON (org.json) 在发送到 REST 服务时丢失值

标签 java json rest jakarta-ee jersey

我正在练习 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 测试其余客户端

enter image description here

关于java - JSON (org.json) 在发送到 REST 服务时丢失值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29332634/

相关文章:

json - 在 jq 中转义正则表达式特殊字符

javascript - 如何实现http请求的函数返回

java - 带有路径注释的简单 REST 服务 - 404 错误

java - 以矩阵格式打印二维数组

java - Eclipse 不断丢失库的源位置

Java 守护进程部署基础设施

java - 当我删除一个项目时,回收站查看列表修改所有项目

PHP json_decode Big(O) 和优化

java - 如何使用空的soapAction定义调用Web服务?

java - 使用矩阵参数创建 GET 请求