Author Archives: Parvinder

About Parvinder

Hi, I want to share my opinion,knowledge related to software technologies and related area.

Static Blocks in Java with Example

Static block in a class are the block of code portion which  executed only once,

1.Before creation of any object of the class.

2.Before any static member of the class in been accessed.

Example: Before creation of any object of the class

package com.devil.java.concept;

public class StaticBlockForConstructor {

static {
System.out.println("I am in first static block");
}

public StaticBlockForConstructor() {
System.out.println("I am in the constructor");
}

public static void main(String args[]) {
StaticBlockForConstructor constr1 = new StaticBlockForConstructor();
StaticBlockForConstructor constr2 = new StaticBlockForConstructor();
}
}

 
Important point to note that static block is been exceuted only once when we create first object constr1
and not when second object constr2 is been created .Output of the above programme is :

I am in first static block
I am in the constructor
I am in the constructor

We can use multiple static blocks as well, they will be executed in the order they are defined in the class, like:

package com.devil.java.concept;

public class StaticBlockForConstructor {

static {
System.out.println("I am in First static block");
}

static {
System.out.println("I am in Second static block");
}

static {
System.out.println("I am in Third static block");
}

public StaticBlockForConstructor() {
System.out.println("I am in the constructor");
}

public static void main(String args[]) {
StaticBlockForConstructor constr1 = new StaticBlockForConstructor();
StaticBlockForConstructor constr2 = new StaticBlockForConstructor();
}
}

Output of the above programme will be :

I am in First static block
I am in Second static block
I am in Third static block
I am in the constructor
I am in the constructor

Example: Before any static member of the class in been accessed.

package com.devil.java.concept;

public class StaticBlock {
static int i;

static {
i = 10;
System.out.println("static block called here");
}

public static void main(String args[]) {

System.out.println(StaticBlock.i);
}
}

Output of the above programme will be:

static block called here
80

If we use multiple variables , in that case also static block will be executed only once like:

package com.devil.java.concept;

public class StaticBlock {
static int i;
static int j;
static int k;

static {
i = 80;
j = 90;
k = 150;
System.out.println("static block called here");
}

public static void main(String args[]) {

System.out.println(StaticBlock.i);
System.out.println(StaticBlock.j);
System.out.println(StaticBlock.k);
}
}

Output of the above programme will be:

static block called here
80
90
150

So that is it about the static block in Java. Hope it will be helpful.

Generics in Java with examples

Generics has been introduced in java 1.5.Generics provide many advantage like code re-usability and detect compile time error related to type safety.

Idea is to pass object as an parameter to the class, function and interface(like passing object Integer,Double or any other user defined object).
Primitive types like int, double etc are not allowed to pass as an parameter.

Generic Class Illustration:

package com.devil.java.generics;

public class GenericClass<T> {
T genericObject;

public GenericClass(T obj) {
this.genericObject = obj;
}

public T getGenericObject() {
return genericObject;
}

}

For creating object for the above class:

When String is passed as an parameter:

GenericClass<String> stringObject = new GenericClass<String>(
"Merry Christmas");

When Integer is passed as an parameter:

GenericClass<Integer> intObject = new GenericClass<Integer>(10);

When Double is passed as an parameter:

GenericClass<Integer> intObject = new GenericClass<Integer>(80.89);

Now if we try to pass primitive type as an parameter,it will give compile error.Like below code will give compile error.

GenericClass<int> doubleObject = new GenericClass<int>(80);

Example illustrating above object (not primitive type)passing is:

package com.devil.java.generics;

public class GenericClassMain {

public static void main(String args[]) {
GenericClass<String> stringObject = new GenericClass<String>(
"Merry Christmas");
String str = stringObject.getGenericObject();
System.out.println("String name from Generic is: " + str);

GenericClass<Integer> intObject = new GenericClass<Integer>(10);

Integer intNumber = intObject.getGenericObject();
System.out.println("IntNumber from generic is :" + intNumber);

GenericClass<Double> doubleObject = new GenericClass<Double>(80.89);

Double doubleNumber = doubleObject.getGenericObject();
System.out.println("Double Number from generic is :" + doubleNumber);
}
}

Output of the above Programme will be:
String name from Generic is: Merry Christmas
IntNumber from generic is :10
Double Number from generic is :80.89

We can pass multiple type parameters as well like:

class name<T1, T2, …, Tn> { /* … */ }

Like in this example , we are passing three parameter.

package com.devil.java.generics;

public class GenericClassMultipleParameter<T, S, U> {
public T obj1;
public S obj2;
public U obj3;

public GenericClassMultipleParameter(T ob1, S ob2, U ob3) {
this.obj1 = ob1;
this.obj2 = ob2;
this.obj3 = ob3;
}

public void printParameter() {
System.out.println("First Parameter is: " + obj1);
System.out.println("Second Parameter is: " + obj2);
System.out.println("Third Parameter is: " + obj3);

}
}

Programme to use above class is :

package com.devil.java.generics;

public class GenericClassMultipleParameterMain {
public static void main(String args[]) {
GenericClassMultipleParameter<String, Integer, Double> genericObject =
new GenericClassMultipleParameter<String, Integer, Double>(
"Merry Christmas", 100, 900.67);
genericObject.printParameter();
}
}

Output of the above programme will be:

First Parameter is: Merry Christmas
Second Parameter is: 100
Third Parameter is: 900.67

Generic Function Illustration:

In the generic function we will use parameters between access modifier and return type like this:

For one parameter:

public <T> void printDetail(T object){/*....*/ }

For multiple parameters:

public <T,U,V> void printDetail(T object1,U object2,V object3){/*....*/}

Example illustrating using of one parameter:


package com.devil.java.generics;

public class GenericFuncton {

public <T> void printDetail(T object) {
System.out.println("Passed object is :" + object.getClass().getName()
+ " and value is :" + object);
}

public <T> T getObjectDetail(T object) {
return object;
}

public static void main(String args[]) {
GenericFuncton function = new GenericFuncton();
function.printDetail("Merry Christmas");
function.printDetail(800);
function.printDetail(456.90);

String str = function.getObjectDetail("Merry Christmas-2016");
System.out.println("Value of returned String object is: " + str);
/**similarly we can get do for other parameter */

}
}

Output of the above programme will be :

Passed object is :java.lang.String and value is :Merry Christmas
Passed object is :java.lang.Integer and value is :800
Passed object is :java.lang.Double and value is :456.9
Value of returned String object is: Merry Christmas-2016

Example illustrating using of multiple parameters:

package com.devil.java.generics;

package com.devil.java.generics;

public class GenericFunctonMultipleParameter {
public <T, U, V> void printDetail(T object1, T object2, T object3) {
System.out.println("First Passed object is :"
+ object1.getClass().getName() + " and value is :" + object1);

System.out.println("Second Passed object is :"
+ object2.getClass().getName() + " and value is :" + object2);

System.out.println("Third Passed object is :"
+ object1.getClass().getName() + " and value is :" + object3);
}

public static void main(String args[]) {
GenericFunctonMultipleParameter function =
new GenericFunctonMultipleParameter();
function.printDetail("Merry Christmas",800,456.90);

}
}

Output of the above programme will be :

First Passed object is :java.lang.String and value is :Merry Christmas
Second Passed object is :java.lang.Integer and value is :800
Third Passed object is :java.lang.String and value is :456.9

Advantage of using Java Generics:

1.Code re-usabilty:We can write a generic method/class/interface once and use for any type we want.

2.Using of generics will detect errors at compile rather than throwing error/exception at run time.like if we do not use generic collection (say ArrayList) in our example.It will allow insertion of 10 (Integer type) at compile time but will throw exception at run time.

package com.devil.java.generics;

import java.util.ArrayList;

public class NoTypeSafety {
public static void main(String[] args)
{
ArrayList al = new ArrayList();

al.add("Banglore");
al.add("Kolkata");
al.add(10); // Compiler allows this

String s1 = (String)al.get(0);
String s2 = (String)al.get(1);

// throws Runtime Exception
String s3 = (String)al.get(2);
}
}

Output will be :

Exception in thread “main” java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
    at com.devil.java.generics.NoTypeSafety.main(NoTypeSafety.java:18)

Using of generics will solve this problem and will detect error at compile time, like this:

package com.devil.java.generics;

import java.util.ArrayList;

public class TypeSafety {
public static void main(String[] args)
{
ArrayList <String> al = new ArrayList<String> ();

al.add("Banglore");
al.add("Kolkata");

//  Compiler doesn't allow this
al.add(10);

String s1 = (String)al.get(0);
String s2 = (String)al.get(1);
String s3 = (String)al.get(2);
}
}

Compiler error will be :
The method add(int, String) in the type ArrayList<String> is not applicable for the arguments (int)

 

 

So this is all about using of generics  in Java.Let me now if there is any questions.

Upload/POST XML data or XML data object to an URL (i.e Web Service URL) through HTTP POST Request in Java

This is about how we can post XML data or data object to an URL( webservice URL or any other URL which can accept these POST request.)

Common Scenario: Lets say we are having data in some tables and we want to post /send these data in the form of xml request to some external URL( which can be a web service URL). We will convert each of these row data in to xml data object and will send this xml data object with the help  marshalling/de-marshalling functionality and will do a POST request to the external URL.

Below is the XML data object used for carrying XML data .

TransactionXMLData Class:

package com.abc.xyz.xml.model;
import java.util.Date;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "Transaction")
public class TransactionXMLData {

@XmlElement(name = "TransactionId")
private long transactionId;
@XmlElement(name = "DCCode")
private String dcCode;
@XmlElement(name = "TransactionType")
private String transactionType;
@XmlElement(name = "TransactionDate")
private Date transactionDate;
@XmlElement(name = "SourceLicensePlateNo")
private String sourceLicensePlateNo;
@XmlElement(name = "DestLicensePlateNo")
private String destLicensePlateNo;
@XmlElement(name = "ProductId")
private String productId;
@XmlElement(name = "PerformedBy")
private String performedBy;
@XmlElement(name = "OrderId")
private String orderId;
@XmlElement(name = "OrderType")
private String orderType;
@XmlElement(name = "OrderLineNo")
private String orderLineNo;

public long getTransactionIdValue() {
return transactionId;
}
public void setTransactionId(long transactionId) {
this.transactionId = transactionId;
}
public String getDcCodeValue() {
return dcCode;
}
public void setDcCode(String dcCode) {
this.dcCode = dcCode;
}
public String getTransactionTypeValue() {
return transactionType;
}
public void setTransactionType(String transactionType) {
this.transactionType = transactionType;
}
public Date getTransactionDateValue() {
return transactionDate;
}
public void setTransactionDate(Date transactionDate) {
this.transactionDate = transactionDate;
}
public String getSourceLicensePlateNoValue() {
return sourceLicensePlateNo;
}
public void setSourceLicensePlateNo(String sourceLicensePlateNo) {
this.sourceLicensePlateNo = sourceLicensePlateNo;
}
public String getDestLicensePlateNoValue() {
return destLicensePlateNo;
}
public void setDestLicensePlateNo(String destLicensePlateNo) {
this.destLicensePlateNo = destLicensePlateNo;
}
public String getProductIdValue() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public String getPerformedByValue() {
return performedBy;
}
public void setPerformedBy(String performedBy) {
this.performedBy = performedBy;
}
public String getOrderIdValue() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getOrderTypeValue() {
return orderType;
}
public void setOrderType(String orderType) {
this.orderType = orderType;
}
public String getOrderLineNoValue() {
return orderLineNo;
}
public void setOrderLineNo(String orderLineNo) {
this.orderLineNo = orderLineNo;
}
}

WebServiceUploadConfig Class:

package com.abc.xyz;
public class WebServiceUploadConfig {
private String url;
private String username;
private String password;

public WebServiceUploadConfig(String url) {
super();
this.url = url;
}
public WebServiceUploadConfig(String url, String username, String password) {
super();
this.url = url;
this.username = username;
this.password = password;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}

}

 

WebServiceUploadException Class:


package com.abc.xyz.exception;

public class WebServiceUploadException extends Exception {

private static final long serialVersionUID = 1L;

public WebServiceUploadException(String msg) {
super(msg);
}

public WebServiceUploadException(Throwable t) {
super(t);
}

public WebServiceUploadException(String msg, Throwable t) {
super(msg, t);
}
}

WebServiceUploadAudit Class:


package com.abc.xyz.model.dataobjects;
import java.util.Date;

public class WebServiceUploadAudit {
private long id;
private long transactionId;
private String transactionType;
private String remoteHost;
private String requestURL;
private String requestBody;
private Date sendDate;
private String responseHeader;
private String responseBody;
private String host;
private String userId;
private boolean success;
private String errorMessage;

public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getRemoteHost() {
return remoteHost;
}
public void setRemoteHost(String remoteHost) {
this.remoteHost = remoteHost;
}
public String getRequestURL() {
return requestURL;
}
public void setRequestURL(String requestURL) {
this.requestURL = requestURL;
}
public String getRequestBody() {
return requestBody;
}
public void setRequestBody(String requestBody) {
this.requestBody = requestBody;
}
public Date getSendDate() {
return sendDate;
}
public void setSendDate(Date sendDate) {
this.sendDate = sendDate;
}
public String getResponseHeader() {
return responseHeader;
}
public void setResponseHeader(String responseHeader) {
this.responseHeader = responseHeader;
}
public String getResponseBody() {
return responseBody;
}
public void setResponseBody(String responseBody) {
this.responseBody = responseBody;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public boolean getSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public long getTransactionId() {
return transactionId;
}
public void setTransactionId(long transactionId) {
this.transactionId = transactionId;
}
public String getTransactionType() {
return transactionType;
}
public void setTransactionType(String transactionType) {
this.transactionType = transactionType;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}

}

XMLConverter Class:


package com.abc.xyz;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.log4j.Logger;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;

public class XMLConverter {
Logger logger = Logger.getLogger(XMLConverter.class);
private Marshaller marshaller;
private Unmarshaller unmarshaller;

public Marshaller getMarshaller() {
return marshaller;
}
public void setMarshaller(Marshaller marshaller) {
this.marshaller = marshaller;
}
public Unmarshaller getUnmarshaller() {
return unmarshaller;
}
public void setUnmarshaller(Unmarshaller unmarshaller) {
this.unmarshaller = unmarshaller;
}

public void convertFromObjectToOutPutStream(Object object,OutputStream os)
throws IOException {
if (logger.isInfoEnabled()) {
logger.info("converting object to xml");
}
try {
getMarshaller().marshal(object, new StreamResult(os));
} finally {
if (os != null) {
os.close();
}
}
}

public Object convertFromXMLToObject(String xmlfile) throws IOException {
if (logger.isInfoEnabled()) {
logger.info("converting xml to object");
}

FileInputStream is = null;
try {
is = new FileInputStream(xmlfile);
return getUnmarshaller().unmarshal(new StreamSource(is));
} finally {
if (is != null) {
is.close();
}
}
}

}

WebServiceUploadAuditDAO Class:

package com.abc.xyz.dao;

import com.abc.xyz.model.dataobjects.WebServiceUploadAudit;

public interface WebServiceUploadAuditDAO {

public void save(WebServiceUploadAudit audit);

}

WebServiceUploadAuditDAOImpl Class:

package com.abc.xyz.dao;

import org.apache.log4j.Logger;
import org.springframework.jdbc.core.JdbcTemplate;

import com..abc.xyz.model.dataobjects.WebServiceUploadAudit;

public class WebServiceUploadAuditDAOImpl implements WebServiceUploadAuditDAO {
Logger logger = Logger.getLogger(WebServiceUploadAuditDAOImpl.class);
private JdbcTemplate jdbcTemplate;

public void save(WebServiceUploadAudit audit) {
if (logger.isInfoEnabled()) {
logger.info("Inserting Data in WEBSERVICE_UPLOAD_LOG table");
}

String insertQuery = "INSERT INTO      WEBSERVICE_UPLOAD_LOG(ID,REMOTE_HOST,REQUEST_URL,SEND_DATE,HOST,USER_ID,SUCCESS_IND,ERROR_MESSAGE,TRANSACTION_ID,TRANSACTION_TYPE,REQUEST_BODY,RESPONSE_HEADER,RESPONSE_BODY)values(WEBSERVICE_UPLOAD_LOG_SEQ.nextval,?,?,?,?,?,?,?,?,?,?,?,?)";
jdbcTemplate.update(
insertQuery,
new Object[] { audit.getRemoteHost(), audit.getRequestURL(),
audit.getSendDate(), audit.getHost(),
audit.getUserId(), audit.getSuccess(),
audit.getErrorMessage(), audit.getTransactionId(),
audit.getTransactionType(), audit.getRequestBody(),
audit.getResponseHeader(), audit.getResponseBody() });
}

public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}

 

XMLUploadBusinessProcessImpl Class: This is the class used for POST request of xml data to an URL.

 


package com.abc.xyz.businessprocess;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.log4j.Logger;
import org.springframework.transaction.annotation.Transactional;

import com.abc.xyz.WebServiceUploadConfig;
import com.abc.xyz.XMLConverter;
import com.abc.xyz.dao.WebServiceUploadAuditDAO;
import com.abc.xyz.exception.WebServiceUploadException;
import com.abc.xyz.model.dataobjects.WebServiceUploadAudit;
import com.abc.xyz.xml.model.TransactionXMLData;

public class XMLUploadBusinessProcessImpl implements XMLUploadBusinessProcess {
private XMLConverter xmlConverter;

private WebServiceUploadAuditDAO webServiceUploadAuditDAO;
Logger logger = Logger.getLogger(XMLUploadBusinessProcessImpl.class);

public void processTransactionXMLObjectForUpload(
WebServiceUploadConfig webServiceUploadConfig,
TransactionXMLData transactionXMLData)
throws WebServiceUploadException {
if (webServiceUploadConfig == null)
throw new IllegalArgumentException("WebServiceUploadConfig is null");

WebServiceUploadAudit audit = new WebServiceUploadAudit();
HttpClient client = HttpClientBuilder.create().build();
try {

ByteArrayOutputStream baos = new ByteArrayOutputStream();
xmlConverter.convertFromObjectToOutPutStream(transactionXMLData,
baos);

HttpPost post = new HttpPost(webServiceUploadConfig.getUrl());

if (!StringUtils.isEmpty(webServiceUploadConfig.getUsername())) {

post.addHeader(new BasicScheme().authenticate(
new UsernamePasswordCredentials(webServiceUploadConfig
.getUsername(), webServiceUploadConfig
.getPassword()), null, null));
}
InputStreamEntity reqEntity = new InputStreamEntity(
new ByteArrayInputStream(baos.toByteArray()), -1);

post.addHeader("Content-Type", "application/xml");
post.setEntity(reqEntity);
String host = "hostname";
audit.setHost(host);
audit.setSuccess(true);
audit.setRequestURL(webServiceUploadConfig.getUrl());
audit.setUserId(webServiceUploadConfig.getUsername());

audit.setRequestBody(baos.toString());

audit.setSendDate(new Date());
audit.setTransactionId(transactionXMLData.getTransactionIdValue());
audit.setTransactionType(transactionXMLData
.getTransactionTypeValue());

HttpResponse response = client.execute(post);

// convert header to string
StringBuilder sb = new StringBuilder();

sb.append("HTTP Response Status: ");
sb.append(response.getStatusLine().toString());
// attach new line
sb.append("\n");

Header[] headers = response.getAllHeaders();

for (int i = 0; i < headers.length; i++) {
sb.append(headers[i].getName());
sb.append(":");
sb.append(headers[i].getValue());

// attach new line
sb.append("\n");
}

audit.setResponseHeader(sb.toString());

ByteArrayOutputStream responseBaos = new ByteArrayOutputStream();
response.getEntity().writeTo(responseBaos);

audit.setResponseBody(responseBaos.toString());

if (logger.isInfoEnabled()) {
logger.info("response" + response.getEntity().getContent()
+ "-" + response.getStatusLine());
}

if (response.getStatusLine().getStatusCode() != 200) {
audit.setSuccess(false);
audit.setErrorMessage("Status code is not success: "
+ response.getStatusLine());
throw new WebServiceUploadException(response.getStatusLine()
.toString());
}

} catch (Throwable t) {
logger.warn("Error response", t);
audit.setSuccess(false);
audit.setErrorMessage(t.getMessage());
throw new WebServiceUploadException(t);
} finally {
webServiceUploadAuditDAO.save(audit);
}

}

&nbsp;

 

So with the above approach, we can send XML data to an external URL (i.e Web service URL)

throgh http POST request.

Using of JsonView with Apache CXF (JAX-RS API implementation).

By using JsonView, we need only one Json data view class for both input and output Json data.And in the output response , we can create dynamic response data
on the basic of type of operation in a method or the role of the user who is calling this method.
JsonView is a feature provided by Jackson library. Jar file which containing this feature is jackson-mapper-asl.jar. Class which should be used for JsonView is
org.codehaus.jackson.map.annotate.JsonView

Below is the maven artifact for downloading this:

<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>

 

We can use JsonView feature for JAX-RS based web service(REST Web Services).JsonView works with various JAX-RS  implementation like Apache CXF, Jeresy etc.In this article, we will use Apache CXF (version- 2.5.0). Below are the configuration for Apache CXF.

Add below configuration in web.xml :

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/cxf-servlet.xml</param-value>
</context-param>


<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>2</load-on-startup>

</servlet>

 

And add below configuration in cxf-servlet.xml file:

<jaxrs:server id="searchservice" address="/api">
<jaxrs:serviceBeans>
<ref bean="searchServiceImpl" />
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean id="jacksonProvider" class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"></bean>
</jaxrs:providers>
</jaxrs:server>

 

Controller interface method declaration is annotated with @JsonView (ResultView.class).  In this API, GenericDataView class object will be used for both input and output.In input only two attribute(username and email) will be used.

Below is the controller interface in which API is defined.

@Api(value = "/searchservice", description = "searchservice REST API")
public interface SearchService{

@POST
@Path("/diagnostic_sessions/getSearchResult")
@Produces(MediaType.APPLICATION_JSON)
@JsonView(ResultView.class)
public GenericDataView getSearchResultForJsonView(@Description("Diagnostic Session ID") GenericDataView genericDataView)throws Exception;

}

 

Controller implementation will be:

@Component("searchServiceImpl")
public class SearchServiceImpl implements SearchService {

@Override
public GenericDataView getSearchResultForJsonView(GenericDataView genericDataView) throws Exception {
GenericDataView dataView= new GenericDataView();
dataView.setUsername(genericDataView.getUsername());
dataView.setEmail(genericDataView.getEmail());
dataView.setEmpCode("CTYOP890");
dataView.setAddress("Chicago, America");
dataView.setPhone("681432413");
return dataView;
}

}

}

 

Now lets see how @JsonView works.
Scenario-1: First lets define the type of views for the attributes in View Object.

public class Views {
static class ParamView { }
static class ResultView{ }

}

 

Our Data Model class for View object is:

public class GenericDataView {

@JsonView(ParamView.class)
String username;

@JsonView(ParamView.class)
String email;

@JsonView(ResultView.class)
String empCode;

@JsonView(ResultView.class)
String phone;

@JsonView(ResultView.class)
String address;
}

 

Now lets deploy the above REST API , and send the below json request:

{

"username": "ABCD",
"email": "abcd@xyz.com"

}

 

Output Json response from the above REST API  will be:


{
 "empCode": "CTYOP890",
 "phone": "681432413",
 "address": "Chicago, America"
}

 

In output only empCode,phone,address attributes will be displayed in Json output which are annotated with ResultView(Same view with which above REST API is annotated).

Scenario-2:Lets use below views(ParamView extends ResultView).

public class Views {
static class ParamView { }
static class ResultView extends ParamView { }
}

 

We extends ResultView from ParamView here,So with the same request ,in output all the attributes(annotated with @ParamView and @ResultView will be displayed)


{
 "username": "ABCD",
 "email": "abcd@xyz.com",
 "empCode": "CTYOP890",
 "phone": "681432413",
 "address": "Chicago, America"
}

 

So all the attributes username, email ,empCode,phone,address will be displayed in json output.

That is it about working of @JsonView with JAX-RS API implementation.Still if you face any issue, Please let me know at-  parry.ism@gmail.com

Working and Difference of HashMap ,HashTable,SynchronizedMap, ConcurrentHashMap,TreeMap,SynchronizedSortedMap and ConcurrentSkipListMap

All the above five class implementation are of Map interface.Map object store an key,value pair in the memory.Both key and value should be object not some primitive type like int,float.

Lets start with HashMap and HashTable.Hashtable is synchronized but HashMap is not synchronized other difference is that  in HashMap we can put null as an key or as an value but in HashTable  we can not put null as an key or as an value.

The Below Code example show that in HashMap we can put null as an key or as an value but in HashTable  we can not put null as an key or as an value. Although there is no problem at compile time but it(HashTable) will throw exception at run time.

 

package com.devil;

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

public class MapExample1 {

public static void main(String args[]) {
Map<String, String>hashMap = new HashMap<String, String>();
hashMap.put(null, null);
for (String str : hashMap.keySet()) {
String value = hashMap.get(str);
System.out.println("HashMap Value:-" + value);
}

Map<String, String>hashTable = new Hashtable<String, String>();
hashTable.put(null, null);
for (String str : hashTable.keySet()) {
String value = hashTable.get(str);
System.out.println("HashTable Value:-" + value);
}

}

}

 

Output will be—

HashMap Value:-null

Exception in thread “main” java.lang.NullPointerException

      at java.util.Hashtable.put(Unknown Source)

      at MapExample1.main(MapExample1.java:17)

If we are inserting  multiple keys as an null in HashMap.Than latest insertion will be considered as an entry in to the HashMap

package com.devil;

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

public class MapExample2 {

public static void main(String args[]) {
Map<String, String> hashMap = new HashMap<String, String>();
hashMap.put(null, null);
hashMap.put(null,"HashValue");
for (String str : hashMap.keySet()) {
String value = hashMap.get(str);
System.out.println("HashMap Value:-" + value);
}

Map<String, String>hashTable = new Hashtable<String, String>();
hashTable.put(null, null);
for (String str : hashTable.keySet()) {
String value = hashTable.get(str);
System.out.println("HashTable Value:-" + value);
}

}

}

Output will be—

HashMap Value:-HashValue

Exception in thread “main” java.lang.NullPointerException

      at java.util.Hashtable.put(Unknown Source)

      at MapExample2.main(MapExample2.java:17)


Hashtable is synchronized i.e methods for getting and putting element are made tothread safe by putting ‘synchronized’ keyword before the methods.

In HashMap get() and put() are:

public Value get(Object key) {

Value v;

—implementataion—

return v;

}

public Value put(Key key, Value value){

Value v;

—implementataion—

return v;

}

And in Hashtable get() and put() are: 

public synchronized  Value get(Object key){

Value v;

—implementataion—

return v;

}

Public synchronized Value put(Key key, Value value) {

Value v;

—implementataion—

return v;

}

 

Synchronization and Concurrency: 

Concurrency means number of executing units(like thread)are doing their work on the shared code portion(Class,Method)simultaneously without outputting wrong result. And Synchronization is the way to achieve Concurrency. Proper usage of synchronisation make sure data integrity and sanity in a multithreaded environment (which is concurrent environment). Use of ‘synchronised’ keyword and use of locks are some of the synchronization technique used in Java.

Now Collections.synchronizedMap: 

Collections.synchronizedMap(Map<K,V> m)is wrapper class for HashMap and is almost same as that of HashTable. It has‘synchronized’ keyword internally on every method. Functionally, HashTable and  SynchronizedMap are same.Both are slow,thread safe and had lot of performance overhead due to synchronization mechanism.Now in between HashMap and HashTable,HashMap should be used always for single thread environment .If in case we need to use it in multi- threaded environment, we should use Collections.synchronizedMap(Map<k,v>m) which gives synchronized HashMap.

 Also HashTable is from JDK1.0 and rest of the collection framework(Map,Set,List)is from JDK 1.2 and HashTable is kind of obsolete data structure now. Its retained in further JDK version just to support legacy code.

Now in multithreaded environment when size of HashMap becomes large,Using of Collections. synchronizedMap (Map <K,V> m) or Hashtable make our code very slow since in both the cases lock is acquired on whole object.

So now in this situation ConcurrentHashMap comes in rescue which was accommodated in JDK1.5 and is part of concurrent package(java.util.concurrent). ConcurrentHashMap use segmentationInternally, by using segmentation it lock only some portion of the map object and rest of the portion can be processed by different thread on different segments of the Map (We can see source code for ConcurrentHashMap on how segmentation works internally).

So below is the whole summary:

HashMap:Use it in single threaded environment. When only one thread is accessing our Map object.Here null is allowed as an key or value.

 HashTable:Never use it in new code. Sometimes it becomes necessary to use it to support legacy code, But never use it in new independent code.Here null is not allowed as an key or value.

Collections. synchronizedMap (Map <K,V> m):Use it in Multithreaded environment whenthere are limited number of threads and want to access code through single lock.Here null is allowed as an key or value

 ConcurrentHashMap:Use it in highly concurrent environment when number of concurrent access is very high.It permits any number of concurrent reader threads and multiple writer thread on different segment of map and so is highly scalable on highly concurrent environment. Here null is not allowed as an key or value

TreeMap :TreeMap data structure has different objective in the Map family.It keeps the data in sorted order with respect to its keys.Means sorting criteria is driven by their key.It implement SortedMap interface(which in turn extend Map interface).

TreeMap Example:-


package com.devil;

import java.util.TreeMap;

public class TreeMapExample1 {

public static void main(String args[]) {
TreeMap<String, String> treeMap = new TreeMap<String, String>();
treeMap.put("Delhi","India");
treeMap.put("Washington","USA");
treeMap.put("Beizing","China");
treeMap.put("Tokyo","Japan");
treeMap.put("Paris","France");
for (String str : treeMap.keySet()) {
String value = treeMap.get(str);
System.out.println("TreeMap Value:-" + value);
}
}

}

Output of the above code is:

TreeMap Value:-China
TreeMap Value:-India
TreeMap Value:-France
TreeMap Value:-Japan
TreeMap Value:-USA

There are two ways to define the sorting order:

  1.) Java object which are used as an key in TreeMap should implement Comparable interface and sorting logic should be put in compareTo() method. Generally we use String or Integer object(in the above example,String is used as an Key) as an key.These object already implement Comparable interface.So in that case there is no need to do that.

Example:

 Map<Person,String>treeMap=new TreeMap<Person,String>();

 Lets Person class is :

public class Person {

public String age;

public String name;

}

Here Person is used as an key so this class should implement Comparable interface.Otherwise a RunTime Exception will occur when we run the code.

2.) Passing an Comparator as an argument to the constructor of TreeMap when we create a new object.

Example: 

Map<Person,String>treeMap=new TreeMap<Person,String>(AgeComparator)

This will sort the map according to AgeComparator logic(sorting on the basis of age). Map<Person,String>treeMap=new TreeMap<Person,String>(NameComparator) This will sort the map according to AgeComparator logic(sorting on the basis ofName).More detail about Comparator and Comparable interface are in this posthttps://devilspace.org/2012/07/25/sorting-in-javacomparable-and-comparator/

TreeMap is not synchronised and so its not thread safe.We can use

Sortedmap sortedMap=Collections.SynchronizedSortedMap(new TreeMap()) to achieve thread safety in TreeMap.

Concurrent analog of TreeMap is ConcurrentSkipListMap() which should be used in highly concurrent environment.

Performance:Internally TreeMap use Red-Black Tree(a self balanced binary search tree)for storing data.Its access time(search),insert time is O(log n) as comparison to other Map implementation(all the above discussed map which are based on Hashing)which takes O(1) as look up time + O(k) time for looking in to each bucket(k is the number of element in each bucket).Generally HashMap are faster(unless we design a bad hash function).so if we do not require sorting, We should useHashMap.   So with all this, we have now got basic idea about the Map family, their usage in different situation.

 

 

XML validation with XSD(XML Schema Definition)

We use XML for storing/keeping some data. In most scenario it becomes very necessary  to check if the XML file is having valid data or not.We can validate a XML file by using a XSD file.XSD file is a kind of document which formally describes the structure of data in the XML file.

Below are the common simple scenario in which XML validation with XSD is useful.

1. If a Web Service(any API) is been created on system which consume/gets a XML request and respond back a success/failure(simple response data) after processing the request.We have to define the contract for incoming XML request  so that client send a valid XML(and so valid data) to the called web service and so that it be processed successfully. XSD will be agreement document between client and server.With this client can validate XML request with this XSD before sending it to Web Service and Web Service can validate the incoming XML request with XSD before processing further the request.

2. Similarly , same thing can be done for response as well, Say if  a web service generate lot of data in the response, we can send them in the form of XML.Now this XML content can also be validated before sending it to the client to make sure client is getting accurate data.In this case also, we can use a XSD file/document which will act as an contract for the response (between server client).

3. Third case can be to cover both of above two scenario.We will use one XSD document/file for incoming XML request  and second XSD document/file for validating response before sending it back to client.This will make sure data validity for both request and response.

 

Below is code which will verify a XML file with a XSD file by using a Java program:

 

XSD file is:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://xyz.com/abc" xmlns:abc="http://xyz.com/abc"
elementFormDefault="qualified">
<xs:element name="Transaction">
<xs:complexType>
<xs:sequence>
<xs:element name="AMCode" minOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1" />
<xs:maxLength value="10" />
</xs:restriction>
</xs:simpleType>
</xs:element>

<xs:element name="TransactionType" minOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="0" />
<xs:maxLength value="3" />
</xs:restriction>
</xs:simpleType>
</xs:element>

<xs:element name="TransactionDate" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:dateTime">
</xs:restriction>
</xs:simpleType>
</xs:element>

</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

XML file which needs to get validate with the above XSD file is :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Transaction xmlns="http://xyz.com/abc">
<AMCode>DCM</AMCode>
<TransactionType>GT2</TransactionType>
<TransactionDate>2013-09-18T13:31:34.681+05:30</TransactionDate>
</Transaction>

Java program which validate the above XML file with that of XSD file is :

package com.xyz.abc.validation;

import java.io.File;
import java.io.IOException;

import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.apache.log4j.Logger;
import org.xml.sax.SAXException;

public class XMLValidationMain {
private final Logger logger = Logger.getLogger(XMLValidationMain.class);
private static final String INPUT_TRANSACTION_XML_FILE_NAME = "example.xml";
private final static String INPUT_TRANSACTION__XSD_FILE_NAME = "example.xsd";

public static void main(String args[]) {
XMLValidationMain xmlValidationMain= new XMLValidationMain();
try {
xmlValidationMain.isXMLValid(INPUT_TRANSACTION_XML_FILE_NAME, INPUT_TRANSACTION__XSD_FILE_NAME);
} catch (IOException e) {
e.printStackTrace();
}
}

public boolean isXMLValid(String xmlFile, String xsdFile)
throws IOException {

Source xmlFileData = null;
try {
xmlFileData = new StreamSource(xmlFile);
SchemaFactory schemaFactory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
File inputXsdFile = new File(xsdFile);
Schema schema = schemaFactory.newSchema(inputXsdFile);
Validator validator = schema.newValidator();
validator.validate(xmlFileData);

if (logger.isInfoEnabled()) {
logger.info(xmlFileData.getSystemId() + " is valid");

}
} catch (IOException e) {
logger.error("Reason: " + e.getMessage());
return false;
} catch (SAXException e) {
logger.error(xmlFileData.getSystemId() + " is NOT valid");
logger.error("Reason: " + e.getMessage());
return false;
}
return true;
}

}

Now since the above XML file is having valid data w.r.t XSD .So output of the above program will be :


INFO  com.xyz.abc.validation.XMLValidationMain  - example.xml is valid

Now , lets us change xml file to make invalid data(Set the value of <AMCode></AMCode> empty and this can not be empty as per XSD ) in it w.r.t XSD.Changed XMl file is:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Transaction xmlns="http://xyz.com/abc">
<AMCode></AMCode>
<TransactionType>GT2</TransactionType>
<TransactionDate>2013-09-18T13:31:34.681+05:30</TransactionDate>
</Transaction>

So output of the java program(after changing above xml data) will be :

ERROR com.xyz.abc.validation.XMLValidationMain&amp;amp;nbsp; - example.xml is NOT valid
ERROR com.xyz.abc.validation.XMLValidationMain&amp;amp;nbsp; - Reason: cvc-minLength-valid:
Value '' with length = '0' is not facet-valid with respect to minLength '1' for type '#AnonType_AMCodeTransaction'.

That is it, So we have seen how we can validate a XML with the XSD.Let me know if you have any question about this.

 

Insert Operations in to Multiple Tables By Using SimpleJdbcInsert Class Of Spring Framework

When we want to insert data in table by using spring framework,We use usually use update() method from JdbcTemplate class.
 

public int insertSystemParameterDetail(String parameterName, String dcCode,
            String value) {
    String insertQuery = "insert into SYSTEM_PARAMETER_DETAIL (PARAMETER_NAME,CODE,VALUE) values(?,?,?)";
    int count = jdbcTemplate.update(insertQuery, new Object[] {
                parameterName, code, value });
        return count;

    }

 

Also we can use SimpleJdbcInsert class from spring for inserting the data in to table.SimpleJdbcInsert is having definitely
better capability then JdbcTemplate class for inserting data in to tables.

public int insertSystemParameterDetail(String parameterName, String dcCode,
String value) {
Map<String, Object> dcMasterMap = new HashMap<>();

dcMasterMap.put("PARAMETER_NAME", parameterName);
dcMasterMap.put("CODE", code);
dcMasterMap.put("VALUE", value);

SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(jdbcTemplate)
.withTableName("SYSTEM_PARAMETER_DETAIL");
int count = 0;

count = simpleJdbcInsert.execute(dcMasterMap);

return count;
}

Although making a  Java Data Access Object class for every table is a good practice in standard Java based enterprise application,There may be some situation in which you want to insert data in lot of tables and you may like to do less coding.In these situations, using of SimpleJdbcInsert can be a very good option.

 


public class GenericOperationDAOImpl implements GenericOperationDAO {

    private final Logger logger = Logger
            .getLogger(GenericOperationDAOImpl.class);
    private JdbcTemplate jdbcTemplate;

    public int genericInsert(Map<String, Object> genericMap, String tableName) {
        if (logger.isInfoEnabled()) {
            logger.info("Inserting Data into table : " + tableName);
        }
        SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(jdbcTemplate)
                .withTableName(tableName);
        int count = 0;

        count = simpleJdbcInsert.execute(genericMap);

        return count;

    }

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

}

 

 


public class GenericDBOperationalAPIImpl implements GenericDBOperationalAPI {

private final Logger logger = Logger.getLogger(GenericDBOperationalAPIImpl.class);

GenericOperationDAO genericOperationDAO;

public int genericInsert(Map<String, Object> genericMap,String tableName) {

if (logger.isInfoEnabled()) {
logger.info("Starting Insertion of Data into table : " + tableName);
}

genericOperationDAO.genericInsert(GenericMapUtils.getCarrierMap("1", "WL-ST"), "CARRIER");
genericOperationDAO.genericInsert(GenericMapUtils.getMasterMap("ABC", "UTC", "1", "Unregistered"),"MASTER");
genericOperationDAO.genericInsert(GenericMapUtils.getAttributeMap("DDS", "ABC"),"ATTRIBUTE");
genericOperationDAO.genericInsert(GenericMapUtils.getDeliveryAreaCodeMap("DAC"), "DELIVERY_AREA_CODE");

}

public void setGenericOperationDAO(GenericOperationDAO genericOperationDAO) {
                 this.genericOperationDAO = genericOperationDAO;
}

}

 

 

public class GenericMapUtils {

    public static final Map<String, Object> getCarrierMap(String proNumber,
            String carrierId) {
        Map<String, Object> carrierMap = new HashMap<>();

        carrierMap.put("PRO_NUMBER", proNumber);
        carrierMap.put("CARRIER_ID", carrierId);
        return carrierMap;
    }

    public static final Map<String, Object> getMasterMap(String code,
            String timeZone, String defaultSystemFlag, String description) {
        Map<String, Object> masterMap = new HashMap<>();

        masterMap.put("CODE",code);
        masterMap.put("TIMEZONE", timeZone);
        masterMap.put("DEFAULT_SYSTEM_FLAG", defaultSystemFlag);
        masterMap.put("DESCRIPTION", description);

        return masterMap;

    }

    public static final Map<String, Object> getAttributeMap(
            String attributeName, String code) {

        Map<String, Object> attributeMap = new HashMap<>();

        attributeMap.put("ATTRIBUTE_NAME", attributeName);
        attributeMap.put("CODE", code);
        attributeMap.put("ATTRIBUTE_TYPE", "attT");
        attributeMap.put("ATTRIBUTE_ID", 32);
        return attributeMap;
    }

    
    public static final Map<String, Object> getDeliveryAreaCodeMap(
            String deliveryArea) {

        Map<String, Object> deliveryAreaCodeMap = new HashMap<>();

        deliveryAreaCodeMap.put("DELIVERY_AREA_CODE", deliveryAreaCode);

        return deliveryAreaCodeMap;
    }
}

 

and spring xml configuration is:


<?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:context="http://www.springframework.org/schema/context"
xmlns:oxm="http://www.springframework.org/schema/oxm" xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-3.0.xsd
     http://www.springframework.org/schema/oxm
     http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>

<bean id="genericDBOperationalAPI" class="com.svg.move.api.GenericDBOperationalAPIImpl">
<property name="genericOperationDAO" ref="genericOperationDAO" />
</bean>

<bean id="genericOperationDAO" class="com.svg.move.dao.GenericOperationDAOImpl">
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>

<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:1521:Oracle" />
<property name="username" value="abc" />
<property name="password" value="abc" />
</bean>

</beans>

That is it,So by using SimpleJdbcInsert we can insert in to multiple tables with less and clean coding.This approach is very useful as well in writing junits which involves multiple tables insertion.