Java Login

About javalogin.com

Hello guys,
javalogin.com is for Java and J2EE developers, all examples are simple and easy to understand 

It is developed and maintained by Vaibhav Sharma. The views expressed on this website are his own and do not necessarily reflect the views of his former, current or future employers. I am professional Web development. I work for an IT company as Senior Consultant. Primary I write about spring, hibernate and web-services. I am trying to present here new technologies.


     << Previous
Next >>     


BeanParam annotation

The @BeanParam annotation is something new added in the JAX-RS 2.0 specification. It allows you to inject an application-specific class whose property methods or fields are annotated with any of the injection parameters. The JAX-RS runtime will introspect the @BeanParam parameter's type for injection annotations and then set them as appropriate. In this example BeanForParam class is interested QueryParam parameters.
The code of this tutorial is going to be based on Jersey. Let's show the structure of the project:

pom.xml
<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.rest.technology</groupId>
<artifactId>BeanParamAnnotationExample</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>BeanParamAnnotationExample</name>

<build>
<finalName>BeanParamAnnotationExample</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<inherited>true</inherited>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version></version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<!-- use the following artifactId
if you don't need servlet 2.x compatibility -->
<!-- artifactId>jersey-container-servlet</artifactId -->
</dependency>
<!-- this to get JSON support -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
</dependencies>
<properties>
<jersey.version>2.21</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

you create a file called web.xml in the WebContent\WEB-INF folder as the following:

web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>

<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>Jersey Web Application </servlet-name>
<servlet-class>
org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>
jersey.config.server.provider.packages </param-name>
<param-value>com.rest.technology </param-value>
</init-param>
<load-on-startup>1 </load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>Jersey Web Application </servlet-name>
<url-pattern>/webapi/* </url-pattern>
</servlet-mapping>

</web-app>

In web.xml, I am using org.glassfish.jersey.servlet.ServletContainer servlet for configure restful webservice. I have configure com.rest.technology package for searching all annotations and create a one instance when application start using load-on-startup. In this example /webapi/* pattern use for restful URL.



DatabaseClass.java
package com.rest.technology.database;

import java.util.HashMap;
import java.util.Map;

import com.rest.technology.model.Client;

public class DatabaseClass {

private static Map<Long, Client> clients = new HashMap<Long, Client>();

public static Map<Long, Client> getClients() {
return clients;
}
}

I am not using any database. So I am creating a temporary class com/rest/technology/database/DatabaseClass.java that will work like a database.



BeanForParam.java
package com.rest.technology.model;
import javax.ws.rs.QueryParam;
public class BeanForParam {
@QueryParam("year") int year;
@QueryParam("start") int start;
@QueryParam("size") int size;
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}

Here we have a simple POJO (Plain Old Java Object) that contains the year, start and size of using @BeanParam Annotation. We can have JAX-RS create, initialize, and inject this class using the @BeanParam annotation



Client.java
package com.rest.technology.model;

import java.util.Date;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "Client")
public class Client {

private long id;
private String name;
private String address;
private Date created;

public Client() {
}

public Client(long id, String name, String address) {
super();
this.id = id;
this.name = name;
this.address = address;
this.created = new Date();
}

public long getId() {
return id;
}

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

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public Date getCreated() {
return created;
}

public void setCreated(Date created) {
this.created = created;
}
}

Here we have a simple POJO (Plain Old Java Object) that contains information about Client. It contains id, name, address and createdDate variable. I have created @XmlRootElement annotation on class level. This annotation use for when restful service return XML response.



ClientService.java

package com.rest.technology.serviceImpl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

import com.rest.technology.database.DatabaseClass;
import com.rest.technology.model.Client;

public class ClientService {

private Map< Long, Client> clients = DatabaseClass.getClients();

public ClientService() {
clients.put(1L, new Client(1L, "SAMSUNG", "Bangelore"));
clients.put(2L, new Client(2L, "NOKIA", "Mumbai"));
clients.put(3L, new Client(3L, "Ericsson", "Gurgaon"));
clients.put(4L, new Client(4L, "Spice", "Noida"));
clients.put(5L, new Client(5L, "Blackberry", "Delhi"));
clients.put(6L, new Client(6L, "Apple", "Hydrabad"));
clients.put(7L, new Client(7L, "Micromax", "Pune"));
clients.put(8L, new Client(8L, "Karbonn", "Chennai"));
clients.put(9L, new Client(9L, "Intex", "Chandigarh"));
clients.put(10L, new Client(10L,"Lava", "Mohali"));
}

public List<Client> getAllClients() {
return new ArrayList<Client>(clients.values());
}

public List<Client> getAllClientsForYear(int year) {
List<Client> clientForYear = new ArrayList<Client>();
Calendar calendar = Calendar.getInstance();
for(Client client : clients.values()){
calendar.setTime(client.getCreated());
if(calendar.get(Calendar.YEAR) == year)
clientForYear.add(client);
}
return clientForYear;
}

public List<Client> getAllClientsPaginated(int start, int size) {
List<Client> list = new ArrayList<Client>(clients.values());
if(start+size > list.size())
return new ArrayList<Client>();

return list.subList(start, start+size);
}


}

Here I have created class for ClientService.java. In this class I have created one Map clients from DatabaseClass.java as a database and insert values in Map for using client information. Here is three methods for getting client information as per request parameter.



ClientRestService.java
package com.rest.technology.restService;

import java.util.List;

import javax.ws.rs.BeanParam;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import com.rest.technology.model.BeanForParam;
import com.rest.technology.model.Client;
import com.rest.technology.serviceImpl.ClientService;

@Path("/clients")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class ClientRestService {

ClientService service = new ClientService();

@GET
public List<Client> getAllClientUsingBeanParam(
@BeanParam BeanForParam bean){

if(bean.getYear() > 0)
return service.getAllClientsForYear(bean.getYear());

if(bean.getStart() > 0 && bean.getSize() > 0)
return service.getAllClientsPaginated(
bean.getStart(), bean.getSize());

return service.getAllClients();
}
}

The JAX-RS runtime will introspect the @BeanParam parameter's type for injection annotations and then set them as appropriate. In this example, the BeanForParam.java is interested in QueryParam value. This is a great way to aggregate information instead of having a long list of method parameters.
URL for test this example:
http://localhost:8089/RestWebService7/webapi/clients?start=0&size=5
http://localhost:8089/RestWebService7/webapi/clients?year=2015




     << Previous
Next >>