In this article, we will learn and implement @FormParam annotation in JAX-RS Restful web service. @FormParam binds the value/s of form parameter sent by the client in the POST request into formal arguments of Java method
@FormParam v/s @QueryParam
Use @FormParam for POST request when using form and prefer @QueryParam for GET requests
Annotation Used
- @FormParam (javax.ws.rs.FormParam)
- @Path (javax.ws.rs.Path)
- @GET (javax.ws.rs.GET)
- @Service (org.springframework.stereotype.Service)
Technology Used
- Java 1.7
- Eclipse Luna IDE
- Spring-4.0.0-RELEASE
- Apache-CXF-3.0.0
- Apache Maven 3.2.1
- Apache Tomcat 7.0.54
Mavenize or download required jars
Add Apache-CXF-3.0.0 and Spring-4.0.0-RELEASE dependencies to pom.xml
<dependencies> <!-- Apache CXF --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxrs</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>${cxf.version}</version> </dependency> <!-- Apache HTTP components for writing test client --> <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>${apache.httpcomponents.version}</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>${apache.httpcomponents.version}</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>${apache.httpcomponents.version}</version> <scope>compile</scope> </dependency> <!-- Spring framework --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> </dependencies>
Folks who aren’t familiar with Maven concepts or don’t require maven for their project, can download the below jars individually from the spring site or maven repository and include them in the classpath.
- cxf-rt-frontend-jaxrs
- cxf-rt-transports-http
- cxf-rt-transports-http-jetty
- commons-httpclient
- httpclient
- httpcore
- httpmime
- spring-core-4.0.0-RELEASE
- spring-context-4.0.0-RELEASE
- spring-beans-4.0.0-RELEASE
- spring-aop-4.0.0-RELEASE
- spring-expression-4.0.0-RELEASE
- spring-web-4.0.0-RELEASE
- spring-webmvc-4.0.0-RELEASE
- commons-logging-1.1.1
- aopalliance-1.0
Directory Structure
Before moving on, let us understand the directory/package structure once you create project in Eclipse IDE
Maven has to follow certain directory structure
- src/test/java –> test related files, mostly JUnit test cases
- src/main/java –> create java source files under this folder
- src/main/resources –> all configuration files placed here
- Maven Dependencies or Referenced Libraries –> includes jars in the classpath
- WEB-INF under webapp –> stores web.xml & other configuration files related to web application
Project Structure (Package Explorer view in Eclipse)
Jars Libraries Used in the Project (Maven Dependencies)
Web application
For any web application, entry point is web.xml which describes how the incoming http requests are served / processed. Further, it describes about the global-context and local-context param (i.e.; <context-param> & <init-param>) for loading files particular to project requirements & contains respective listener.
With this introduction, we will understand how we configured web.xml for Apache CXF JAX-RS Restful web service
web.xml (the entry point –> under WEB-INF)
This web.xml file describes,
- Like any JEE web framework register org.apache.cxf.transport.servlet.CXFServlet with servlet container
- http requests with URL pattern “/services/*” will be sent to the registered servlet called “CXFServlet” (org.apache.cxf.transport.servlet.CXFServlet)
- <context-param> with its attributes describes the location of the “apache-cxf-service.xml” file from where it has to be loaded. We will discuss briefly about this file
- <welcome-file-list> files under this tag is the start-up page
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name>ApacheCXF-FormParam</display-name> <!-- Apache CXF --> <servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> <!-- web context param --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>WEB-INF/apache-cxf-services.xml</param-value> </context-param> <!-- listener --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- welcome file list --> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
Apache CXF services
Apache CXF comes with spring based configuration, so it is easy to register beans in the spring container much like we do any bean in spring application. CXFServlet receives the incoming http requests and invokes corresponding registered beans in according to http url path
NOTE: For this Restful JAX-RS application, we are using Spring annotations to define/register beans in the spring container thereby avoiding lot of boilerplate code to write
This apache-cxf-services.xml describes,
- <context:annotation-config /> to activate annotation on the registered beans with the application context
- <context:component-scan base-package=”” /> this tag scans all classes & sub-classes under the value of base-package attribute and register them with the Spring container
- <jaxrs:server /> defines which service bean to be invoked for the incoming http requests. In this case, any wild card pattern “/” will invoke “playerService” which is registered as service bean using @Service(“playerService”) annotation (on top of the PlayerServiceImpl java class)
- for two different beans we can have two different url-pattern(address) like
<jaxrs:server id="restContainer" address="/"> <jaxrs:serviceBeans> <ref bean="playerService" /> </jaxrs:serviceBeans> </jaxrs:server> <jaxrs:server id="twotest" address="/two"> <jaxrs:serviceBeans> <ref bean="testService" /> </jaxrs:serviceBeans> </jaxrs:server>
apache-cxf-services.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- to turn on annotation wiring == turns on only the registered beans through ApplicationContext --> <context:annotation-config /> <!-- scans and register beans using annotation-config (metadata) --> <context:component-scan base-package="com.apache.cxf.formparam.service" /> <!-- register restful web service endpoints --> <jaxrs:server id="restContainer" address="/"> <jaxrs:serviceBeans> <ref bean="playerService" /> </jaxrs:serviceBeans> </jaxrs:server> </beans>
Let’s see coding in action
URL Pattern
Http url for any common web application is http://<server>:<port>/<root-context>/<from_here_application_specific_path>
In our example, we are going to deploy the war into local Tomcat 7.0 server so our server and port are localhost and 8080 respectively. Context root is the project name i.e.; ApacheCXF-FormParam. Initial path for this application is http://localhost:8080/ApacheCXF-FormParam
We have configured “/services/*” as url-pattern for CXFServlet in web.xml and at interface-level (or say class-level) path configured is “/player” using @Path annotation. Next respective path for each method annotated with @Path (method-level)
Player Service interface
A simple method which takes three-arguments using @FormParam annotation (multiple parameters)
URL: http://localhost:8080/ApacheCXF-FormParam/services/player/addinfo
POST request from the form will invoke this method, when relative action (path) is set to “services/player/addinfo”
NOTE: It’s always a good programming to do code-to-interface and have its implementation separately
IPlayerService.java
package com.apache.cxf.formparam.service; import javax.ws.rs.FormParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.core.Response; @Path("/player") public interface IPlayerService { // http://localhost:8080/ApacheCXF-FormParam/services/player/addinfo @POST @Path("/addinfo") public Response getPlayerInfo( @FormParam("name") String playerName, @FormParam("age") int age, @FormParam("matches") int matches); }
Player Service implementation
Implements above interface returning Response object
PlayerServiceImpl.java
package com.apache.cxf.formparam.service; import javax.ws.rs.core.Response; import org.springframework.stereotype.Service; @Service("playerService") public class PlayerServiceImpl implements IPlayerService { /** * this method takes three argument from FormParam and returns a Response */ public Response getPlayerInfo(String playerName, int age, int matches) { String playerInfo = "Player with information " + "[name=" + playerName + ", age=" + age + ", matches=" + matches + "]" + " added to the database"; return Response.status(200).entity(playerInfo).build(); } }
View Technologies
Start up page which redirects the request to the addPlayer.html page
index.jsp (\src\main\webapp\index.jsp)
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>JAX-RS Restful web service</title> </head> <body> <center> <b>Welcome to the JAX-RS Restful web service Learning</b> <h2> <% response.sendRedirect("addPlayer.html"); %> </h2> </center> </body> </html>
Simple HTML form with POST action (method) which takes three inputs from the user to add a player to the database
addPlayer.html (\src\main\webapp\addPlayer.html)
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>JAX-RS Restful web service</title> </head> <body> <center> <b>Welcome to the JAX-RS Restful web service Learning</b> <form method="post" action="services/player/addinfo"> <table> <tr> <td>Name:</td> <td><input type="text" name="name" /></td> </tr> <tr> <td>Age:</td> <td><input type="text" name="age" /></td> </tr> <tr> <td>Matches:</td> <td><input type="text" name="matches" /></td> </tr> <tr> <td colspan="1"><input name="submit" type="submit" value="Add Player" /></td> <td colspan="1"><input name="reset" type="reset" value="Reset" /></td> </tr> </table> </form> </center> </body> </html>
Deployment
- Run maven command to build the war : mvn clean install (use command prompt or integrated maven in eclipse IDE
- Copy the war file from the target folder
- Paste it into apache tomcat (webapps folder)
- Start the tomcat server
Test the service !!
Testing
Access the default URL http://localhost:8080/ApacheCXF-FormParam it will redirect to addPlayer.html page which displays user fields for entering name, age & matches to capture player information and store it in the database
Or else directly access the URL for the same page
http://localhost:8080/ApacheCXF-FormParam/addPlayer.html –> displays below page
Enter details of any player like
Name : Steve Waugh
Age : 49
Matches : 168
Clicking “Add Player” button will invokes POST method configured in the form tag with action=“services/player/addinfo”
On successful execution of the request, a success message is returned to the user as shown below
Conclusion: When the requirement is to send the data from the form, then this approach would be appropriate
Download project
ApacheCXF-@FormParam-annotation (4kB)
Happy Coding !!
Happy Learning !!