Я занимаюсь услугами REST. Я пытаюсь отправить JSON (JSONObject из библиотеки org.json), но когда я пытаюсь прочитать JSON в методе REST, он пуст. Я печатаю длину отложенного 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());
}
}
}
Зачем это случилось? Я делаю что-то неправильно? Я ценю вашу помощь.
Ошибка может быть в вашем клиентском коде. Вы пробовали использовать почтальон или эквивалент, чтобы проверить службу отдыха с помощью строки json, чтобы убедиться, что она работает?
Использование Джерси и Джексона делает все это довольно легко.
Также аннотация пути по вашему последнему методу get {i}, но должна быть {id}
ОБНОВИТЬ
Поскольку я изначально не дал полного ответа с кодом, вот мой полный ответ. Я полагаю, что проблема связана с использованием JSONObject, а не с использованием определенного класса, который может быть сериализован ObjectMapper. Вот пример рабочего кода с использованием Джерси/Джексона (проект 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;
}
}
Теперь я определяю класс UserModel, который может быть сериализован ObjectMapper
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;
}
}
Теперь я создам веб-службу и добавлю ресурс под названием /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();
}
}
}
затем используя почтальон для тестирования остального клиента