使用泽西在POST中检索JsonObject [英] retrieve JsonObject in POST with jersey

查看:101
本文介绍了使用泽西在POST中检索JsonObject的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在应用程序中遇到了一些问题,我发送了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆