Twitter

luni, 19 octombrie 2015

Bind HTML form parameters value to JAX-RS resource

In this post, you can see how to bind HTML form parameters value to JAX-RS resource

In order to accomplish this task, you have to follow two steps:

- indicate the JAX-RS resource path in the action attribute of the form
- use @FormParam to obtain the submitted values

Let's suppose that we have a JAX-RS resource that respond to the following path:

http://localhost:8080/JaxrsBindHTMLFormToResource_EE7/resources/user/order

Then the resources/user/order should be indicated in the action attribute as:
<form id="addId" method="post" action="resources/user/order">
 ...
</form>
Let's take the below HTML form:
<form id="addId" method="post" action="resources/user/order">
 <fieldset>
  <legend>Personal details</legend>
   <div>
    <label>First Name
     <input id="name" name="name" type="text" placeholder="First name only" required autofocus>
    </label>
   </div>
   <div>
    <label>Security code
     <input id="security" name="security" type="number" required title="The last three digits on the back of your card.">
    </label>
   </div>
   <div>
    <label>Country
     <input id="country" name="country" list="country-names" type="text" required>
     <datalist id="country-names">
      <option label="England" value="England"></option>
      <option label="Northern Ireland" value="Northern Ireland"></option>
      <option label="Ireland" value="Ireland"></option>
      <option label="Scotland" value="Scotland"></option>
      <option label="Wales" value="Wales"></option>
     </datalist>
    </label>
   </div>
   <fieldset>
    <legend>Card type</legend>
    <div class="card">                    
    <input id="visa" name="card" value="VISA" type="radio">
    <label for="visa">VISA</label>
    <input id="mastercard" name="card" value="Mastercard" type="radio">
    <label for="mastercard">Mastercard</label>
    <input id="amex" name="card" value="AMEX" type="radio">
    <label for="amex">AMEX</label>
   </div>
  </fieldset>
  <fieldset>
   <legend>Subscribe for</legend>
   <div class="order">                    
    <input id="newsletter" name="order" value="Newsletter" type="checkbox">
    <label for="newsletter">Newsletter</label>
    <input id="news" name="order" value="News" type="checkbox">
    <label for="news">News</label>
    <input id="promotions" name="order" value="Promotions" type="checkbox">
    <label for="promotions">Promotions</label>
   </div>
  </fieldset>
 </fieldset>
 <fieldset>
  <div>
   <button type=submit>Place Order</button>
  </div>
 </fieldset>
</form>
The @FormParam obtains the submitted values by indicating the values of each name attibute:
import java.util.Arrays;
import javax.ws.rs.FormParam;
import javax.ws.rs.Produces;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;

@Path("user")
public class OrderResource {

    @POST
    @Path("/order")
    @Produces("text/html") // default: */*
    public Response orderAction(
            @FormParam("name") String name,
            @FormParam("security") int sn,
            @FormParam("country") String country,
            @FormParam("card") String card,
            @FormParam("order") String[] order) {

        return Response.status(200)
           .entity("<h1>Thank you :</h1>" + name
                 + "Your subscription overview: "
                 + "<h2>Security: </h2>" + sn
                 + "<h2>Country: </h2>" + country
                 + "<h2>card: </h2>" + card
                 + "<h2>Order: </h2>" + Arrays.toString(order))
          .build();
    }
}
The response is redirected to the same URL and it looks like figure below:
The complete application is available here. In the next post we will process date/time values.

luni, 12 octombrie 2015

JAX-RS Access HTTP Cookie in Resource

In this post, you can see how to access cookie parameters from a JAX-RS resource

Let's suppose that we have an application named, JaxrsCookieParameters_EE7, and a cookie as: hellofrom = Leonard. Via javax.ws.rs.CookieParam we can easily access this cookie in a JAX-RS resource as below:
import javax.ws.rs.CookieParam;
import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("hello")
public class HelloResource {

    @GET
    @Produces("text/plain") // default: */*
    public String hello(@CookieParam(value="hellofrom") String from) {
        return "Hello, " + from+"!";
    }
}
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("webresources")
public class ApplicationConfig extends Application {
}
The output will be as in figure below (for testing I just added the cookie manually in Google Chrome). The test URL is: http://localhost:8080/JaxrsCookieParameters_EE7/webresources/hello


Note Do not forget that cookies implies several limitations (use of semi-colons ;, and commas ,)! Is important to read the corresponding RFC.

The complete application is available here.

vineri, 9 octombrie 2015

JAX-RS extract the URI path parameters from the request URI

In this post, you can see how to extract the URI path parameters from the request URI in a JAX-RS application

Let's suppose that we have an application named, JaxrsPathParameters_EE7, and the following JAX-RS resource:
import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("/users/{username: [a-zA-Z][a-zA-Z_0-9]*}")
public class HelloUsersResource {

 @GET
 @Path("/admin/{id: \\d+}")
 @Produces("text/plain")
 public String helloAdmin() {
  return "Hello, Admin!";
 }
   
 @GET
 @Path("/user")
 @Produces("text/plain")
 public String helloUser() {
  return "Hello, User!";
 }
}
You already know how to work with this resource from the JAX-RS working with URI path templates example.
Further, let's suppose that you need to extract the URI parameters (in this case, username and id). This is very easy to accomplish via javax.ws.rs.PathParam annotation in the method parameter, as below:
import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;

@Path("/users/{username: [a-zA-Z][a-zA-Z_0-9]*}")
public class HelloUsersResource {

 @GET
 @Path("/admin/{id: \\d+}")
 @Produces("text/plain")
 public String helloAdmin(@PathParam("username") String admin, @PathParam("id") String id) {
  return "Hello, " + admin + " (" + id + ")!";
 }

 @GET
 @Path("/user")
 @Produces("text/plain")
 public String helloUser(@PathParam("username") String user) {
  return "Hello, " + user + "!";
 }
}
Now, check out two examples:

http://localhost:8080/JaxrsPathParameters_EE7/webresources/users/foo/admin/007
Produces: Hello, foo (007)!

http://localhost:8080/JaxrsPathParameters_EE7/webresources/users/buzz/user
Produces: Hello, buzz!

  • If the URI path template variable cannot be cast to the specified type, the JAX-RS runtime returns an HTTP 400 ("Bad Request") error to the client.
  • If the @PathParam annotation cannot be cast to the specified type, the JAX-RS runtime returns an HTTP 404 ("Not Found") error to the client.

The complete application is available here.

marți, 6 octombrie 2015

JAX-RS consume a RESTful web service from a Servlet (including asynchronous)

In this post, you can see a simple example of consuming a RESTful web service from a Servlet (including asynchronous calls).

JavaEE 7 Client API for JAX-RS API is useful to access the RESTful web services. Basic steps:
  • Get the instance of javax.ws.rs.client.Client class (entry point for invoking RESTful web services).
  • Create an instance of javax.ws.rs.client.WebTarget using the instance of Client class (used to invoke a RESTful web service at some location or URI).
  • Populate the target with the required data (e.g. MIME type, post data, query parameters), and create a request of appropriate HTTP method type which would be an instance of javax.ws.rs.client.Invocation.
  • Obtain the response from the desired RESTful web service via javax.ws.rs.client.Invocation object.
Let's suppose that we have the following JAX-RS resource:
import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("helloworld")
public class HelloWorldResource {

    @GET
    @Produces("text/plain") // default: */*
    public String helloWorld() {
        return "Hello, World!";
    }
}
Configured as:
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("webresources")
public class ApplicationConfig extends Application {
}
If the application is named JaxrsSimpleServletClient_EE7, then the resource is available at:

http://localhost:8080/JaxrsSimpleServletClient_EE7/webresources/helloworld

From a Servlet we can access this resource like below:
@WebServlet("/ClientServlet")
public class ClientServlet extends HttpServlet {

    // for simple demo, URL is hard-coded
    private final String jaxrsResource = "http://localhost:8080/JaxrsSimpleServletClient_EE7/webresources/helloworld/";

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // get the instance of client which will be entry point to invoking services
        Client jaxrsClient = ClientBuilder.newClient();

        // targeting the JAX-RS serivce we want to invoke by capturing it in WebTarget instance
        WebTarget webTarget = jaxrsClient.target(jaxrsResource);

        // build the request (e.g. a GET request)
        Invocation invocation = webTarget.request("text/plain").buildGet();

        // invoke the request
        Response jaxrsResponse = invocation.invoke();

        // respond to client (user)
        String hello = jaxrsResponse.readEntity(String.class);

        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.println("<h3>" + hello + "</h3>");
    }

    @Override
    public String getServletInfo() {
        return "Client Server";
    }

}
If you need to perform asynchronous request then add client support for making asynchronous calls to the server by using the AsyncContext class:
@WebServlet(urlPatterns={"/ClientServlet"}, asyncSupported=true)

Complete example is available here.

Read also:
Consume a RESTful web service from JSF

sâmbătă, 3 octombrie 2015

JAX-RS configure application examples

In this post, you can see how to configure a JAX-RS application

Let's suppose that we have an application named, JaxrsConfigureApplication_EE7, and the following two resources:
import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("helloworld")
public class HelloWorldResource {

 @GET
 @Produces("text/plain") // default: */*
 public String helloWorld() {
  return "Hello, World!";
 }
}

import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("byeworld")
public class ByeWorldResource {

 @GET
 @Produces("text/plain") // default: */*
 public String byeWorld() {
  return "Bye, World!";
 }
}
Basically, by configuring a JAX-RS application means to set the base URI from which an application's resources respond to requests. This can be accomplished in two ways:

·         using the @ApplicationPath annotation in a subclass of javax.ws.rs.core.Application packaged within the WAR

For example, if your base URI will be /webresources (or, webresources) then simply add the following class:
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("webresources")
public class ApplicationConfig extends Application {
}
In the preceding example, the base URI is set to /webresources, which means that all resources defined within the application are relative to /webresources. Check out the below URLs:

// this URL will invoke HelloWorldResource#helloWorld()
http://localhost:8080/JaxrsConfigureApplication_EE7/webresources/helloworld

// this URL will invoke ByeWorldResource#byeWorld()
http://localhost:8080/JaxrsConfigureApplication_EE7/webresources/byeworld

So, by default, all the resources in an archive will be processed for resources. We can easily alter this behavior by overriding the getClasses() method to manually register the resource classes in the application with the JAX-RS runtime. For example, we can register the HelloWorldResource in HelloApplicationConfig, as below:
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("helloresources")
public class HelloApplicationConfig extends Application {

 @Override
 public Set<Class<?>> getClasses() {
  final Set<Class<?>> classes = new HashSet<>();
  classes.add(HelloWorldResource.class);
  // add more classes
  return classes;
 }
}
And, we can register the ByeWorldResource in ByeApplicationConfig, as below:
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("byeresources")
public class ByeApplicationConfig extends Application {

 @Override
 public Set<Class<?>> getClasses() {
  final Set<Class<?>> classes = new HashSet<>();
  classes.add(ByeWorldResource.class);
  return classes;
 }
}
Now, the URLs will become:

// this URL will invoke HelloWorldResource#helloWorld()
http://localhost:8080/JaxrsConfigureApplication_EE7/helloresources/helloworld

// this URL will invoke ByeWorldResource#byeWorld()
http://localhost:8080/JaxrsConfigureApplication_EE7/byeresources/byeworld

The following URLs will not work!

http://localhost:8080/JaxrsConfigureApplication_EE7/helloresources/byeworld
http://localhost:8080/JaxrsConfigureApplication_EE7/byeresources/helloworld

The complete application is available here.

·         using the servlet-mapping tag within the WAR's web.xml deployment descriptor

Let's suppose that we have an application named, JaxrsConfigureApplicationWebXml_EE7, and the same two resources, HelloWorldResource and ByeWorldResource.

This time we will configure the application via the <servlet-mapping> tag in the web.xml deployment descriptor, using the Application class name as the servlet:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">

 <servlet-mapping>
  <servlet-name>javax.ws.rs.core.Application</servlet-name>
  <url-pattern>/webresources/*</url-pattern>
 </servlet-mapping>
</web-app>
Check out the following valid URLs:

// this URL will invoke HelloWorldResource#helloWorld()
http://localhost:8080/JaxrsConfigureApplicationWebXml_EE7/webresources/helloworld

// this URL will invoke ByeWorldResource#byeWorld()
http://localhost:8080/JaxrsConfigureApplicationWebXml_EE7/webresources/byeworld

This setting will also override the path set by @ApplicationPath when using an Application subclass.  For example let's suppose that we have the following Application subclass:
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("webresources")
public class ApplicationConfig extends Application {
}
And, in web.xml we have:
...
<servlet-mapping>
 <servlet-name>ee7.jaxrs.ApplicationConfig</servlet-name>
 <url-pattern>/greetings/*</url-pattern>      
</servlet-mapping>
...
Now, the following URLs will work:

// this URL will invoke HelloWorldResource#helloWorld()
http://localhost:8080/JaxrsConfigureApplicationWebXml_EE7/greetings/helloworld

// this URL will invoke ByeWorldResource#byeWorld()
http://localhost:8080/JaxrsConfigureApplicationWebXml_EE7/greetings/byeworld

While the following two will not work:

http://localhost:8080/JaxrsConfigureApplicationWebXml_EE7/webresources/helloworld
http://localhost:8080/JaxrsConfigureApplicationWebXml_EE7/webresources/byeworld

The complete application is available here.

vineri, 2 octombrie 2015

JAX-RS working with @Path at class and method level examples

In this post, you can see a very simple JAX-RS application for working with @Path at class and method level

In the JAX-RS HelloWorld Example we have used @Path to define a relative URI at class level (this comes after the base URI). Basically, @Path can be used at:

·         class level:
@Path("/account")
public class HelloUsersResource {

 @GET   
 @Produces("text/plain")
 public String helloAdmin() {
  return "Hello, Admin!";
 }
   
 @GET   
 @Produces("text/plain")
 public String helloUser() {
  return "Hello, User!";
 }
}
A valid URL will be of type (the application name is, JaxrsUsingPathAnnotation_EE7, and the base URI is, webresources ):

http://localhost:8080/JaxrsUsingPathAnnotation_EE7/webresources/account

Is easy to intuit that the our relative URI looks ambiguous, because @Path is placed at class level and we have to methods that produces output. JAX-RS will pick up the helloAdmin() method for the above URL. But, if we rename the helloAdmin() as, helloXman(), then JAX-RS will pick up the helloUser() to produce the response for the above URL. It looks like, JAX-RS picked up the method based on kind of alphabetical criteria. Actually, this is the last criteria, while the most important are:

·         Isolate the methods that correspond to the HTTP request type. For example, if we simply paste our URL in the browser address bar, we will have a HTTP GET request. Further, if we annotate the helloAdmin() method with @POST (indicating a HTTP POST request), then JAX-RS will pick up the helloUser() method instead of helloAdmin():
@Path("/account")
public class HelloUsersResource {

 @POST
 @Produces("text/plain")
 public String helloAdmin() {
  return "Hello, Admin!";
 }
   
 @GET   
 @Produces("text/plain")
 public String helloUser() {
  return "Hello, User!";
 }
}
·         If a resource class is capable of producing more than one MIME media type then the resource method chosen will correspond to the most acceptable media type as declared by the client.  For example, we can use the @Produces at class level to indicate the MIME type of the expected response, and override it locally (at method level, e.g. helloAdmin()). In the below example, JAX-RS will pick up the helloUser() method as the most acceptable media type as declared by the client:
@Path("/account")
@Produces("text/html")
public class HelloUsersResource {

 @GET
 @Produces("text/plain")
 public String helloAdmin() {
  return "Hello, Admin!";
 }
   
 @GET   
 @Produces("text/html")
 public String helloUser() {
  return "Hello, User!";
 }
}
·         class and method level:

Using @Path at method level also will not override the @Path from class level. Actually, the relative URI will be obtained be concatenating the value of @Path from class level with the value if @Path from method level, as below - now we can build custom URL per method:
@Path("/account")
public class HelloUsersResource {

 @GET
 @Path("/admin")
 @Produces("text/plain")
 public String helloAdmin() {
  return "Hello, Admin!";
 }
   
 @GET   
 @Path("/user")
 @Produces("text/plain")
 public String helloUser() {
  return "Hello, User!";
 }
}
And, the accepted URL:

http://localhost:8080/JaxrsUsingPathAnnotation_EE7/webresources/account/admin
http://localhost:8080/JaxrsUsingPathAnnotation_EE7/webresources/account/user

The complete application is available here.

A @Path value may or may not begin with a '/', it makes no difference.

JAX-RS working with URI path templates example

In this post, you can see a very simple JAX-RS application for working with URI path templates

URI path templates are URIs with variables embedded within the URI syntax. In the JAX-RS HelloWorld Example, we have used a static (hard-coded) relative URI, helloworld (or, /helloworld). In order to use a path template  just wrap the variables in curly braces, as below (/users is the static part of the relative URI, while username is the variable part):
@Path("/users/{username}")
If we suppose that our application (JaxrsURIpathtemplates_EE7) has the base URI, webresource, and the above URI path template then URL like below will work:

http://localhost:8080/JaxrsURIpathtemplates_EE7/webresources/users/leo
http://localhost:8080/JaxrsURIpathtemplates_EE7/webresources/users/12345
http://localhost:8080/JaxrsURIpathtemplates_EE7/webresources/users/!@!

The {username} was replaced by, leo, 12345 and !@!.  If leo looks like an user name, we cannot say the same thing about 12345 and !@!. In order to restrict the variable to a pattern, it is possible to declare a particular regular expression, which overrides the default regular expression, [^/]+, for example:
@Path("/users/{username: [a-zA-Z][a-zA-Z_0-9]*}")
The variables can be chained. This is ok:
@Path("/users/{username: [a-zA-Z][a-zA-Z_0-9]*}/admin/{id: \\d+}")
A possible URL will be:

http://localhost:8080/JaxrsURIpathtemplates_EE7/webresources/users/leo/admin/9009

We also can chain variables as below (see, JAX-RS working with @Path at class and method level):
import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("/users/{username: [a-zA-Z][a-zA-Z_0-9]*}")
public class HelloUsersResource {

 @GET
 @Path("/admin/{id: \\d+}")
 @Produces("text/plain")
 public String helloAdmin() {
  return "Hello, Admin!";
 }
   
 @GET
 @Path("/user")
 @Produces("text/plain")
 public String helloUser() {
  return "Hello, User!";
 }
}
Some valid URL are:

// for admins
http://localhost:8080/JaxrsURIpathtemplates_EE7/webresources/users/leo/admin/9001

// for normal users
http://localhost:8080/JaxrsURIpathtemplates_EE7/webresources/users/kelly/user

The complete application is available here.

In the below figure (copy-paste from Java EE 7 tutorial) you can see more examples:

These variables are substituted at runtime in order for a resource to respond to a request based on the substituted URI. Commonly they are provided by the user (or indirectly computed via the user actions). In the next post, you will see how to obtain the variables passed by the user from an interface.

joi, 1 octombrie 2015

JAX-RS HelloWorld example

In this post, you can see a very simple JAX-RS application (the HelloWorld example).

This application consist in a Java web application that contain a RESTful root resource class and a class for configuring our application - defines the base URI from which our application's resources respond to requests.

The below POJO class uses the JAX-RS annotations to become a RESTful root resource class:
import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("helloworld")
public class HelloWorldResource {

 @GET
 @Produces("text/plain") // default: */*
 public String helloWorld() {
  return "Hello, World!";
 }
}
We can put this in words as follows: This ia a RESTful root resource class hosted at the relative URI, helloworld (you can use /helloworld also, it makes no difference), indicated via @Path annotation. It will respond to requests of type HTTP GET (@GET) and it can produce (return) plain text as the MIME type (text/plain) indicates via the @Produces annotation.

So, the helloworld is the relative URI. Further we need to define the base URI which can be accomplished easily by using the @ApplicationPath annotation in a subclass of javax.ws.rs.core.Application packaged within the WAR:
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("webresources")
public class ApplicationConfig extends Application {
}
Done! The application is ready and we can test it by accessing the correct URL in the browser address bar:

http://localhost:8080/JaxrsHelloWorld_EE7/webresources/helloworld

It will simply display: Hello, World!

The complete application is available here.