Search code examples
javaweb-servicesrestcxfcxf-client

Usage of client.reset in CXF Rest client


I am working on Rest web services and client using CXF 3.1.2 , and i have few clarification as below,

Service:

    import javax.jws.WebService;
    import javax.ws.rs.Consumes;
    import javax.ws.rs.GET;
    import javax.ws.rs.POST;
    import javax.ws.rs.Path;
    import javax.ws.rs.PathParam;
    import javax.ws.rs.Produces;
    import javax.ws.rs.core.MediaType;
    public class GenServiceImpl  {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Consumes(MediaType.TEXT_PLAIN)
    @Path("/agentLogin/{ext}")

    public String agentLogin(@PathParam("ext") Integer ext) {
    return "EventAgentLoggedIn";
    }

    @POST
    @Produces(MediaType.TEXT_PLAIN)
    @Consumes({"application/xml", MediaType.TEXT_PLAIN})
    @Path("/agentLogout")
    public String agentLogout(String ext) {
    return "EventAgentLoggedOut";
    }

    }

Client:

    import javax.ws.rs.core.Response;
    import org.apache.cxf.jaxrs.client.WebClient;
    public class TestClient {
    static final String REST_URI = "http://localhost:8080/RestfulSample/Restful";
    public static void main(String[] args) {
    WebClient client = WebClient.create(REST_URI);

    //Get
    client.path("agentLogin").path(new Integer(1234)).accept(MediaType.TEXT_PLAIN);
    String agentLoginResponse = client.get(String.class);
    System.out.println(agentLoginResponse);
    client.reset();

    //Post
    client.path("agentLogout").accept(MediaType.TEXT_PLAIN);
    Response agentLogoutResponse = client.post("10245");
    System.out.println(agentLogoutResponse.readEntity(String.class));
    client.reset();
    }

Clarifications:

  1. In my above example - In service class Post method(agentLogout) , i am getting error if i replace @Consumes({"application/xml", MediaType.TEXT_PLAIN})
    with @Consumes(MediaType.TEXT_PLAIN) whereas it works fine in Get method(agentLogin), may i know why it is so?

  2. It is right to use client.reset(); - Here i am trying to use single WebClient to access all my methods.

  3. Could you please let me know what i tried in my example is best practice ? and it will be appreciated if you could correct me here

Thanks,


Solution

  • Here are the clarifications.

    1. Set content type to text/plain while posting. And you can set in your servers side class @Consumes(MediaType.TEXT_PLAIN)

      client.replaceHeader("Content-Type",MediaType.TEXT_PLAIN);

    2. Yes you can use rest method, here is java doc

    When reusing the same WebClient instance for multiple invocations, one may want to reset its state with the help of the reset() method, for example, when the Accept header value needs to be changed and the current URI needs to be reset to the baseURI (as an alternative to a back(true) call). The resetQuery() method may be used to reset the query values only. Both options are available for proxies too.

    1. I would prefer to use proxy and access REST more like OOPS.

    You could create interface for the above server class(Generally I careate REST definition as interface and then implement the interface( more like SOAP way)), which could be auto generated using WADLToJava maven plugin from WADL.

    Here is sample interface for above server side rest class

    public interface GenService {
    
        @GET
        @Produces(MediaType.TEXT_PLAIN)
        @Consumes(MediaType.TEXT_PLAIN)
        @Path("/agentLogin/{ext}")
    
        public String agentLogin(@PathParam("ext") Integer ext);
    
        @POST
        @Produces(MediaType.TEXT_PLAIN)
        @Consumes(MediaType.TEXT_PLAIN)
        @Path("/agentLogout")
        public String agentLogout(String ext);
    
    } 
    

    Since you are not using spring , I will create a singleton class

    public class CxfRestSingleton {
    
        public static GenService obj;
    
        public static GenService getInstance() {
    
            if (obj == null) {
                obj = JAXRSClientFactory.create("http://localhost:8080/RestfulSample/Restful", GenService.class);
            }
            return obj;
        }
    
    }
    

    And you can access the rest using below code.

     public static void main( String[] args )
        {
            System.out.println( CxfRestSingleton.getInstance().agentLogin(12345));
        }