Working with JAX-RS forms (@FormParam, MultivaluedMap)

This tutorial shows how to capture submitted form data to REST web service using @FormParam and MultivaluedMap.

Example Scenario :

We have a rest service which is like a car inventory and has cars of different models and years. For the sake of simplicity, let’s say it has only Honda cars. We want to modify the information of cars stored in the inventory by submitting forms.


Project artifacts:

1. Technologies used –

a. Eclipse IDE for Java EE developer 4.5.0.20150621-1200 (Mars)
b. Preinstalled Maven with Eclipse Mars
c. Tomcat 7.0.64
d. RESTEasy 3.0.4.Final
e. Java 1.8

Jars used –

javax.ws.rs-api-2.0.jar
resteasy-jaxrs-3.0.4.Final.jar
jaxrs-api-3.0.4.Final.jar
slf4j-simple-1.5.8.jar
slf4j-api-1.5.8.jar
scannotation-1.0.3.jar
javassist-3.12.1.GA.jar
jboss-annotations-api_1.1_spec-1.0.1.Final.jar
activation-1.1.jar
httpclient-4.2.1.jar
httpcore-4.2.1.jar
commons-logging-1.1.1.jar
commons-codec-1.6.jar
commons-io-2.1.jar
jcip-annotations-1.0.jar

2. Eclipse project folder structure:

Form Param Direct Structure

3. Web Project

Create a standard web project in Eclipse by following the below link.

Create a Maven Web Project

4. Maven Dependencies

file:pom.xml. Maven unit of work to declare project dependencies, compile code and build war file for deployment in Tomcat.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.javanbeyond</groupId>
    <artifactId>WorkingWithFormParam</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>Restful Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxrs</artifactId>
            <version>3.0.4.Final</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>WorkingWithFormParam</finalName>
    </build>
</project>

 

5. POJO

file: Car.java. A POJO which is stored as car in Car Inventory web service and whose data is modified in the inventory.

package com.javanbeyond.data;

// Simple POJO
public class Car {
  private int id;
  private String make;
  private String model;
  private String exteriorColor;
  private String interiorColor;
  private int year;

  public int getId() {
    return id;
  }

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

  public String getMake() {
    return make;
  }

  public void setMake(String make) {
    this.make = make;
  }

  public String getModel() {
    return model;
  }

  public void setModel(String model) {
    this.model = model;
  }

  public String getExteriorColor() {
    return exteriorColor;
  }

  public void setExteriorColor(String exteriorColor) {
    this.exteriorColor = exteriorColor;
  }

  public String getInteriorColor() {
    return interiorColor;
  }

  public void setInteriorColor(String interiorColor) {
    this.interiorColor = interiorColor;
  }

  public int getYear() {
    return year;
  }

  public void setYear(int year) {
    this.year = year;
  }

}

6. Application class

file: MyApplication.java. The Class that registers the resource class OrderReceiver with JAX-RS runtime. It has two sets.
Our resource class should be added to the singleton set.

 

package com.javanbeyond.service;

import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;

// Application class
public class MyApplication extends Application {
  private Set<Object> singletons = new HashSet<Object>();
  private Set<Class<?>> empty = new HashSet<Class<?>>();

  public MyApplication() {
    singletons.add(new OrderReceiver());
  }

  @Override
  public Set<Class<?>> getClasses() {
    return empty;
  }

  @Override
  public Set<Object> getSingletons() {
    return singletons;
  }
}

 

7. Resource class

file: OrderReceiver.java . In JAX-RS, we use @FormParam annotation to capture information of a submitted form and pass it to methods as parameters. The “/cars/{make}” @Path value  before the class brings the URI “http://localhost:8080/rest/cars/honda” to this class. {make} is mapped to “honda”. The part after it decides which method will be called at runtime.

Case 1: Getting Form values with @FormParam

The method updateCar receives the URI  “/cars/honda/formParam″ with the values of form parameters mapped  to “carId” and other parameters by @FormParam. The method returns the status of the update.

// Get Form data from submitted form and
  // update the inventory

  @POST
  @Path("formParam")
  public Response updateCar(@FormParam("id"int carId,
      @FormParam("model"String model, @FormParam("year"int year) {
    System.out.println("in updateCar using FormParam");
    Car car = carInventory.get(carId);
    car.setModel(model);
    car.setYear(year);
    carInventory.put(carId, car);
    return Response.status(200)
        .entity("Car with id " + carId + " updated using FormParam")
        .build();

  }

 

Case 2: Getting Form values using  MultivaluedMap

The other method updateCar receives the URI  “/cars/honda/formMulti″ with all values of form parameters  stored in an object of MultivaluedMap and passed as a parameter to the method. The method returns the status of the update.

 

// The whole submitted form can be retrieved with this method.
  // This should be used when the number of form parameters are more.
  // Once we get the form we can parse the values for our
  // operations

  @POST
  @Path("formMulti")
  @Consumes("application/x-www-form-urlencoded")
  public Response updateCar(MultivaluedMap<String, String> form) {
    System.out.println("in updateCar using MultivaluedMap");
    int carId = Integer.valueOf(form.getFirst("id"));
    String model = form.getFirst("model");
    int year = Integer.valueOf(form.getFirst("year"));
    Car car = carInventory.get(carId);
    car.setModel(model);
    car.setYear(year);
    carInventory.put(carId, car);
    return Response.status(200).entity(
        "Car with id " + carId + " updated using MultivaluedMap")
        .build();
  }

8. Deployment descriptor

file: web.xml . Deployment descriptor file for mapping URIs to servlet. Application class is registered by setting as init param to the servlet.

 

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
    <display-name>Archetype Created Web Application</display-name>
    <context-param>
        <param-name>resteasy.servlet.mapping.prefix</param-name>
        <param-value>/rest</param-value>
    </context-param>
    <servlet>
        <servlet-name>rest</servlet-name>
        <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.javanbeyond.service.MyApplication</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>rest</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>client.html</welcome-file>
    </welcome-file-list>
</web-app>

 

Example Execution:

1. Deploy the application in Tomcat and type the URI http://localhost:8080/WorkingWithFormParam/. You should get a client as below:

JAX-RSFormParam Client

2. Fill up the form of “FormParam” with your desired values.

JAX-RS FormParam

3. Click on “Update Car Info by FormParam” button. You should see the below response.

 

JAX-RFormParam Result

 

4. Go back and fill the details of MultiValuedMap form.

JAX-RSMultiValuedMap

5. Click on “Update Car Info by MultivaluedMap” button and get the response accordingly.

 

JAX-RSMultiValuedMapResult

 

 

Back to Top