使用泽西在POST中检索JsonObject [英] retrieve JsonObject in POST with jersey
问题描述
我在应用程序中遇到了一些问题,我发送了POST请求,但无法检索服务器中的JsonObject,这是要发送的代码:
String quo ={\network \:{\label \:\new net 111 \,\cidr \:\ 10.20.105.0/24\}};
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
JsonParser json = new JsonParser();
JsonObject jo =(JsonObject)json.parse(quo);
ClientConfig config = new ClientConfig();
客户端客户端= ClientBuilder.newClient(config);
WebTarget target = client.target(http:// localhost:7999 / jersey / rest / network /+ tenant_id);
响应oj = target.request()。accept(MediaType.APPLICATION_JSON)
.header(X-Auth-Token,令牌)
.post(Entity.json (gson.toJson(JO)));
尝试用以下方式检索:
<$ p $ ($ / $ tenant_id})
public String createNetwork(@HeaderParam(value =X){code> @POST
@Produces(MediaType.APPLICATION_JSON)
@Path(/ {tenant_id}) -Auth-Token)字符串authToken,
@PathParam(value =tenant_id)字符串tenant_id,
JsonObject网络){
响应响应= client.target(NOVA_ENDPOINT + tenant_id)
.request(MediaType.APPLICATION_JSON)
.header(X-Auth-Token,authToken)
.post(Entity.json(gson.toJson(network)));
System.out.println(Hello);
String responseJson = response.readEntity(String.class);
JsonObject网络似乎是空的,实际上它并不执行该方法(Hello is not打印),我得到的错误是无效的请求主体(因为JsonObject是空的,我认为)..
我的代码有什么问题?
好的,我知道这个问题与我使用Gson的Json处理有关。这是我改进后的代码(简化版),遵循用户建议,但我仍然有问题。
客户端:
package openstack;
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.Response;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.net.URI;
$ b $ public class Post {
public static HttpServer startServer(){
final ResourceConfig resourceConfig = new ResourceConfig()
.packages() openstack)
.register(GsonMessageBodyHandler.class);
返回GrizzlyHttpServerFactory.createHttpServer(URI.create(http:// localhost:7999 / jersey / rest),resourceConfig);
}
public static void main(String [] args){
String quo ={\keypair \:{\name \: \我的钥匙\}};
HttpServer server = startServer();
客户端客户端= ClientBuilder.newClient();
client.register(GsonMessageBodyHandler.class);
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
JsonParser json = new JsonParser();
JsonObject jo =(JsonObject)json.parse(quo);
WebTarget target = client.target(http:// localhost:7999 / jersey / rest / test / prova);
System.out.println(jo);
响应oj = target.request()。post(Entity.json(jo));
String responseString = oj.readEntity(String.class);
System.out.println(responseString);
$ b $ / code>
服务器端:
package openstack;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
@Path(/ test)
public class Test {
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
议会议会=新议会();
JsonParser json = new JsonParser();
私人最终客户端客户端;
$ b $ public Test(){
client = ClientBuilder.newClient()。register(GsonMessageBodyHandler.class);
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path(/ prova)
public Response mymethod(JsonObject keypairsob){
return Response.ok(keypairsob).build();
$ b $ / code $ / pre
我创建了一个GsonMessageBodyHandler.java我的包与用户peeskillet下面建议的代码。在我的web-inf / lib中添加了jersey-container-grizzly2-http.jar(我不知道如何正确使用Maven),但仍然无法正常工作。我错过了什么? 解决方案为了将JSON转换为Java类型,需要为 MessageBodyReader 和一个 MessageBodyWriter
实现进行转换。由于您使用的是GSON类型的 JsonObject
,因此您可以看到这个实现。尽管如此,实现还存在一个问题,因为< code> readFrom
方法不能与Jersey 2一起编译。这是一个固定版本
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
导入javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@Provider
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public final class GsonMessageBodyHandler implements MessageBodyWriter< Object> ;,
MessageBodyReader< Object> {
private static final String UTF_8 =UTF-8;
私人Gson gson;
$ b $ private Gson getGson(){
if(gson == null){
final GsonBuilder gsonBuilder = new GsonBuilder();
gson = gsonBuilder.create();
}
返回gson;
}
$ b $ @Override
public boolean isReadable(Class <?> type,Type genericType,
java.lang.annotation.Annotation [] annotations,MediaType mediaType ){
返回true;
$ b @Override
public Object readFrom(Class< Object> type,Type type1,Annotation [] antns,
MediaType mt,MultivaluedMap< String,String> mm,InputStream in)
抛出IOException,WebApplicationException {
InputStreamReader streamReader = new InputStreamReader(in,UTF_8);
尝试{
类型jsonType;
if(type.equals(type1)){
jsonType = type;
} else {
jsonType = type1;
}
return getGson()。fromJson(streamReader,jsonType);
} finally {
streamReader.close();
$ b @Override
public boolean isWriteable(Class <?> type,Type genericType,
Annotation [] annotations,MediaType mediaType) {
返回true;
$ b @Override
public long getSize(Object object,Class<> type,Type genericType,
Annotation [] annotations,MediaType mediaType){
返回-1;
$ b @Override
public void writeTo(Object object,Class<> type,Type genericType,
Annotation [] annotations,MediaType mediaType,
MultivaluedMap< String,Object> httpHeaders,OutputStream entityStream)
抛出IOException,WebApplicationException {
OutputStreamWriter writer = new OutputStreamWriter(entityStream,UTF_8);
尝试{
类型jsonType;
if(type.equals(genericType)){
jsonType = type;
} else {
jsonType = genericType;
}
getGson()。toJson(object,jsonType,writer);
} finally {
writer.close();
}
}
}
然后我们只需要注册它与客户端和应用程序。我使用独立测试,您可以在这里看到配置
最终ResourceConfig resourceConfig = new ResourceConfig()
.packages(jersey.stackoverflow.standalone)
.register(GsonMessageBodyHandler.class);
...
客户端c = ClientBuilder.newClient();
c.register(GsonMessageBodyHandler.class);
以下是我用于测试的资源类别
import com.google.gson.JsonObject;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import jersey.stackoverflow.standalone.provider.GsonMessageBodyHandler;
@Path(/ gson)
public class GsonResource {
private final Client client;
private static final String BASE_URI =http:// localhost:8080 / api / gson;
public GsonResource(){
client = ClientBuilder.newClient()。register(GsonMessageBodyHandler.class);
}
@POST
@Path(/ proxy)
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public response proxyPost(JsonObject json){
Response response = client.target(BASE_URI)
.path(main-resource)。request()。post(Entity.json(json) );
JsonObject fromMainResource = response.readEntity(JsonObject.class);
return Response.created(null / *应该是一个创建的URI * /)
.entity(fromMainResource).build();
}
@POST
@Path(/ main-resource)
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON )
public response mainResource(JsonObject json){
return Response.ok(json).build();
$ b $ p
$ b 这是完整的测试,它需要这个maven dependency
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.net.URI;
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.Response;
import static jersey.stackoverflow.standalone.Main.BASE_URI;
import jersey.stackoverflow.standalone.provider.GsonMessageBodyHandler;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import org.junit.Test;
public class GsonProviderTest {
public static HttpServer startServer(){
final ResourceConfig resourceConfig = new ResourceConfig()
.packages(jersey.stackoverflow .standalone)
.register(GsonMessageBodyHandler.class);
返回GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI),resourceConfig);
public static Client getClient(){
Client c = ClientBuilder.newClient();
c.register(GsonMessageBodyHandler.class);
return c;
@Test
public void testGetIt(){
HttpServer server = startServer();
客户端c = getClient();
c.register(GsonMessageBodyHandler.class);
String quo ={\network \:{\label \:\new net 111 \,\cidr \:\ 10.20.105.0/24\}};
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
JsonParser json = new JsonParser();
JsonObject jo =(JsonObject)json.parse(quo);
WebTarget target = c.target(http:// localhost:8080 / api / gson / proxy);
Response response = target.request()。post(Entity.json(jo));
String responseString = response.readEntity(String.class);
System.out.println(responseString);
response.close();
c.close();
server.stop();
所有测试都发送的JSONObject
。虽然没有任何可见的转换到JSON,但在我的任何代码中,它都是由 GsonMessageBodyHandler
在幕后发生的。如果你看看 GsonResource
类,你可以看到这些方法只发出 JsonObject
。在客户端测试中,我将响应作为字符串读取,您可以看到与初始请求中发送的结果相同的结果。
I have some problems in my application, I send a POST request, but I cannot retrieve the JsonObject in my server, this is the code to send:
String quo = "{\"network\": {\"label\": \"new net 111\",\"cidr\": \"10.20.105.0/24\"}}";
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
JsonParser json = new JsonParser();
JsonObject jo = (JsonObject)json.parse(quo);
ClientConfig config = new ClientConfig();
Client client = ClientBuilder.newClient(config);
WebTarget target = client.target("http://localhost:7999/jersey/rest/network/"+tenant_id);
Response oj = target.request().accept(MediaType.APPLICATION_JSON)
.header("X-Auth-Token", token)
.post(Entity.json(gson.toJson(jo)));
Trying to retrieve with:
@POST
@Produces(MediaType.APPLICATION_JSON)
@Path("/{tenant_id}")
public String createNetwork(@HeaderParam(value = "X-Auth-Token") String authToken,
@PathParam(value = "tenant_id") String tenant_id,
JsonObject network){
Response response = client.target(NOVA_ENDPOINT+tenant_id)
.request(MediaType.APPLICATION_JSON)
.header("X-Auth-Token", authToken)
.post(Entity.json(gson.toJson(network)));
System.out.println("Hello");
String responseJson = response.readEntity(String.class);
JsonObject network seems to be empty, in fact it doesn't execute the method ("Hello is not printed"), the error I get is "Invalid request body" (because the JsonObject is empty I think)..
What's wrong with my code?
Ok, I understood that the problem is related to Json handling such as I'm using Gson. This is my improved code (simplified version) following users suggestion, but I still have problems..
Client Side:
package openstack;
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.Response;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.net.URI;
public class Post {
public static HttpServer startServer() {
final ResourceConfig resourceConfig = new ResourceConfig()
.packages("openstack")
.register(GsonMessageBodyHandler.class);
return GrizzlyHttpServerFactory.createHttpServer(URI.create("http://localhost:7999/jersey/rest"), resourceConfig);
}
public static void main(String[] args) {
String quo = "{\"keypair\": {\"name\": \"MyKey\"}}";
HttpServer server = startServer();
Client client = ClientBuilder.newClient();
client.register(GsonMessageBodyHandler.class);
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
JsonParser json = new JsonParser();
JsonObject jo = (JsonObject)json.parse(quo);
WebTarget target = client.target("http://localhost:7999/jersey/rest/test/prova");
System.out.println(jo);
Response oj = target.request().post(Entity.json(jo));
String responseString = oj.readEntity(String.class);
System.out.println(responseString);
}
}
Server Side:
package openstack;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
@Path("/test")
public class Test {
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
Parliament parliament = new Parliament();
JsonParser json = new JsonParser();
private final Client client;
public Test() {
client = ClientBuilder.newClient().register(GsonMessageBodyHandler.class);
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/prova")
public Response mymethod(JsonObject keypairsob){
return Response.ok(keypairsob).build();
}
}
I created a GsonMessageBodyHandler.java in my package with the code suggested below by the user peeskillet. Added jersey-container-grizzly2-http.jar to my web-inf/lib (I don't know how to proper use Maven), but still doesn't work.. what am I missing?
解决方案 In order to convert JSON to a Java type, there is need to for a MessageBodyReader
and a MessageBodyWriter
implementation to do the conversion to and from. Since you are using JsonObject
which is a GSON type, you can see this implementation. There is a problem with the implementation though, as the readFrom
method doesn't compile with Jersey 2. Here is the a fixed version
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@Provider
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public final class GsonMessageBodyHandler implements MessageBodyWriter<Object>,
MessageBodyReader<Object> {
private static final String UTF_8 = "UTF-8";
private Gson gson;
private Gson getGson() {
if (gson == null) {
final GsonBuilder gsonBuilder = new GsonBuilder();
gson = gsonBuilder.create();
}
return gson;
}
@Override
public boolean isReadable(Class<?> type, Type genericType,
java.lang.annotation.Annotation[] annotations, MediaType mediaType) {
return true;
}
@Override
public Object readFrom(Class<Object> type, Type type1, Annotation[] antns,
MediaType mt, MultivaluedMap<String, String> mm, InputStream in)
throws IOException, WebApplicationException {
InputStreamReader streamReader = new InputStreamReader(in, UTF_8);
try {
Type jsonType;
if (type.equals(type1)) {
jsonType = type;
} else {
jsonType = type1;
}
return getGson().fromJson(streamReader, jsonType);
} finally {
streamReader.close();
}
}
@Override
public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return true;
}
@Override
public long getSize(Object object, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return -1;
}
@Override
public void writeTo(Object object, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
throws IOException, WebApplicationException {
OutputStreamWriter writer = new OutputStreamWriter(entityStream, UTF_8);
try {
Type jsonType;
if (type.equals(genericType)) {
jsonType = type;
} else {
jsonType = genericType;
}
getGson().toJson(object, jsonType, writer);
} finally {
writer.close();
}
}
}
Then we just need to register it with both the client and the application. I'm using a standalone test, where you can see the configuration here
final ResourceConfig resourceConfig = new ResourceConfig()
.packages("jersey.stackoverflow.standalone")
.register(GsonMessageBodyHandler.class);
...
Client c = ClientBuilder.newClient();
c.register(GsonMessageBodyHandler.class);
Here is the resource class I used for the test
import com.google.gson.JsonObject;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import jersey.stackoverflow.standalone.provider.GsonMessageBodyHandler;
@Path("/gson")
public class GsonResource {
private final Client client;
private static final String BASE_URI = "http://localhost:8080/api/gson";
public GsonResource() {
client = ClientBuilder.newClient().register(GsonMessageBodyHandler.class);
}
@POST
@Path("/proxy")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response proxyPost(JsonObject json) {
Response response = client.target(BASE_URI)
.path("main-resource").request().post(Entity.json(json));
JsonObject fromMainResource = response.readEntity(JsonObject.class);
return Response.created(null /* should be a created URI */)
.entity(fromMainResource).build();
}
@POST
@Path("/main-resource")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response mainResource(JsonObject json) {
return Response.ok(json).build();
}
}
Here's the complete test, which requires this maven dependency
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.net.URI;
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.Response;
import static jersey.stackoverflow.standalone.Main.BASE_URI;
import jersey.stackoverflow.standalone.provider.GsonMessageBodyHandler;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import org.junit.Test;
public class GsonProviderTest {
public static HttpServer startServer() {
final ResourceConfig resourceConfig = new ResourceConfig()
.packages("jersey.stackoverflow.standalone")
.register(GsonMessageBodyHandler.class);
return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), resourceConfig);
}
public static Client getClient() {
Client c = ClientBuilder.newClient();
c.register(GsonMessageBodyHandler.class);
return c;
}
@Test
public void testGetIt() {
HttpServer server = startServer();
Client c = getClient();
c.register(GsonMessageBodyHandler.class);
String quo = "{\"network\": {\"label\": \"new net 111\",\"cidr\": \"10.20.105.0/24\"}}";
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
JsonParser json = new JsonParser();
JsonObject jo = (JsonObject) json.parse(quo);
WebTarget target = c.target("http://localhost:8080/api/gson/proxy");
Response response = target.request().post(Entity.json(jo));
String responseString = response.readEntity(String.class);
System.out.println(responseString);
response.close();
c.close();
server.stop();
}
}
All the test does is send the JsonObject
. Though there isn't any visible conversion to JSON, in any of my code, it is happening behind the scenes by the GsonMessageBodyHandler
. If you look at the GsonResource
class, you can see the methods don't do anything but send out the JsonObject
. In the client test, I read the response as a String, and you can see the result the same as what sent out in the initial request.
这篇关于使用泽西在POST中检索JsonObject的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!