How to pass a custom object in REST webservice

2019-07-21 06:15发布

问题:

i'm having problems transfering a custom object to the client. How can i transfer a custom object to the client and receive it back to the webservice? i'm transferring a file by chunks. i want to know how i should write my client. i tried passing it as MediaType.APPLICATION_JSON in client but i get no result meaning it doesn't get passed back to the webservice. Below is a bit of code im working on.

Webservice

 @POST
    @Path("/fileTransfer")
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_JSON})
    public final TransferInfomation transferInfo(final FileModel file)
{
...
}

...(some code)(lets just say a syso)

FileModel Class

public class FileModel {

private String fileID;
private DataHandler dataHandler;

/**
 * Constructor.
 */
public FileModel() {
}

(lets assume setters and getters are made)

(Not sure if the webservice is correct). Still learning REST, i want to know how the client should be.

thanks in advance.

回答1:

A good way to "marshal" and "unmarshal" "custom objects" (in JSON, XML, etc.) in Jersey is to use JAXB (https://jaxb.java.net/).

To do this you need to create a "jaxb class", with the proper getters and setters (and annotations), e.g.:

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class FileModel{

    private String fileID;
    private DataHandler dataHandler;

    public String getFileID(){
        return fileID;
    }

    public void setFileID(String fileID){
        this.fileID = fileID;
    }

    public DataHandler getDataHandler(){
        return dataHandler;
    }

    public void setDataHandler(DataHandler dataHandler){
        this.dataHandler = dataHandler;
    }

}

Do not forget to declare the @XmlRootElement. Then you can simply declare and use these objects in your API endpoints (methods):

@POST
@Path("/fileTransfer")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public final FileModel transferInfo(FileModel file)
{
    // read file in "FileModel" format
    // ... make several operations
    // return new FileModel (or another format if you will)
}

This should work. Make sure you follow the data structure defined for FileModel correctly in the client side. See here a example on how to handle that in Jersey: How do I POST a Pojo with Jersey Client without manually convert to JSON? (where JAXB is also used).



回答2:

Your REST endpoint indicates you want to consume and produce JSON. So the REST client needs to send JSON that can be deserialized into FileModel, and the TransferInfomation returned by transferInfo needs to be serialized into JSON to return to the client.

Typically, Java REST frameworks like RESTEasy, Restlet, Camel, and Spring MVC provide facilities that let you define a JSON serializer/deserializer like Jackson and the mapping rules from JSON <--> Java, and the framework handles the details for you.

So if you use one of these frameworks, you will just have to configure them to use the preferred JSON tool and define the rules.



回答3:

You can achive this like below:

Server Side:

@PUT
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public String addRecord(CustomClass mCustomClass)
{
    ///
    ///
    ///
    return "Added successfully : "+CustomClass.getName();

}// addRecord

Client Side:

public static void main(String[] args)
{
    ///
    ///
    ///
    CustomClass mCustomClass = new CustomClass();
    Client client = ClientBuilder.newClient();
    String strResult = client.target(REST_SERVICE_URL).request(MediaType.APPLICATION_XML).put(Entity.xml(mCustomClass), String.class);
}