Vaadin - REST example

I want to add some REST-Modifications to my current vaadin project. Therefore I have implemented following code so far:

// calls findByName Method in the RestClient.class
List<Customer> customers = restClient.findByName(firstName.getValue(), lastName.getValue());

/* RestClient-class */
public List<Customer> findByName(String firstname,String lastname) {
        
         List<Customer>customerList = webtarget.path("server").
                 path("restserver").
                 path("findByName").
                 queryParam("firstname", firstname).
                 queryParam("lastname", lastname).
                 request().
                 accept(MediaType.TEXT_PLAIN). // Do I need this?
                 get(Customer.class); // How to cast here?
        
         return customerList;
    }
 
/* Server class - handling requests */
    @GET
    @Path("/findByName")
    @Produces(MediaType.TEXT_PLAIN)
    public List<Customer>findByName(@QueryParam("firstname")String firstname,@QueryParam("lastname")String lastname) throws ClassNotFoundException, SQLException {
        
        System.out.println("findByName in Server aufgerufen");
        customerService = new CustomerService();
        return customerService.findByName(firstname, lastname);
        
    }

My code is not working. I receive HTTP Status 500. I put some comments into the code section. Could you help me to answer these please?
Thanks!!
Best regards,
Nazar Medeiros

Status Code 500 will always go hand in hand with some kind of stacktrace. Could you please provide this crucial information?

Hi Tobias,
please find attached my stacktrace:

javax.ws.rs.InternalServerErrorException: HTTP 500 Internal Server Error at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:1032) at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:819) at org.glassfish.jersey.client.JerseyInvocation.access$700(JerseyInvocation.java:92) at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:701) at org.glassfish.jersey.internal.Errors.process(Errors.java:315) at org.glassfish.jersey.internal.Errors.process(Errors.java:297) at org.glassfish.jersey.internal.Errors.process(Errors.java:228) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444) at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:697) at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:420) at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:316) at com.example.restclient.RestClient.findByName(RestClient.java:87) at com.example.Vaadin_REST.MyUI$MainView.searchCustomer(MyUI.java:198) at com.example.Vaadin_REST.MyUI$MainView.lambda$0(MyUI.java:128) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:510) at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:200) at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:163) at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1015) at com.vaadin.ui.Button.fireClick(Button.java:377) at com.vaadin.ui.Button$1.click(Button.java:54) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:158) at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:119) at com.vaadin.server.communication.ServerRpcHandler.handleInvocation(ServerRpcHandler.java:435) at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:407) at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:273) at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:90) at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41) at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1422) at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:379) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:784) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1452) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745) Best regards,
Nazar

I suspect that it is failing because you are requesting plain text and trying to convert it to a Customer. Try changing the media-type to JSON.

Hmm… didn’t work. Do I have to use some Annotations in my Customer-class?

public class Customer implements Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 1L;
    private Long id;
    private String firstName,lastName;
    
    public Customer(Long id,String firstName,String lastName) {
        
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    
    }

    @Override
    public String toString() {
        return "Customer [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + "]
";
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    
}

Next problem might be the fact that you are requesting a Customer but actually receiving a List of Customers. As far as I remember, it is probably better to use array here and to pass the correct class-type into get().

(new Customer[0]
).getClass();

No success :frowning:

Finally I could solve the problem. There were few steps I had to do. So let’s start with my model class
Customer.java

public class Customer {

    private String firstname;
    
    private String lastName;
    
    private Long id;
    
    public Customer() {
        
    }
    
    public Customer(Long id,String firstname,String lastname) {
        
        this.firstname = firstname;
        this.lastName = lastname;
        this.id = id;
        
    }
    
    @Override
    public String toString() {
        return "Customer [firstname=" + firstname + ", lastName=" + lastName + ", id=" + id + "]
";
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

When using rest services with a content-type like json or xml you have to be sure, that your model class can be converted to the specific format. In my case I decided to use xml. Therefore I had to use the annotation
@XmlRootElement.
You only need to put this annotation at the top of your class… nothing more needed.

The next step was to edit my Rest-Client.java:

[code]
public ListfindByName(String firstname,String lastname) {

    List<Customer>customerList = new ArrayList<Customer>();
    
    customerList = webtarget.path("server").
                        path("restserver").
                        path("findByName").
                        queryParam("firstname", firstname).
                        queryParam("lastname", lastname).  
                        request().
                        accept(MediaType.APPLICATION_XML).
                        get(new GenericType<List<Customer>>(){});  
    return customerList;
    
}

[/code]I expect an xml content-type from the server. This is the reason why I use
accept(MediaType.APPLICATION_XML)
. In case you receive a list of items, you could use
GenericType<List>(){};

The fnal part - My Server.java:

@Path("/restserver")
public class Server {

    @Path("/findByName")
    @GET
    @Produces(MediaType.APPLICATION_XML)
    public GenericEntity<List<Customer>>findByName(@QueryParam("firstname")String firstname,@QueryParam("lastname") String lastname) throws ClassNotFoundException, SQLException
    {
        List<Customer>customerList = DBConnection.findByName(firstname, lastname);
        
         GenericEntity<List<Customer>>
            list = new GenericEntity<List<Customer>>(customerList) {
         };
         return list;
    }

Nothing special here. Just looking for some data in the database and returning them as a type of
List
.
I hope this information could be helpful for someone.
Best regards,
Nazar Medeiros