Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Friday, January 16, 2015

Accept encoding with Jersey REST API

Consider following Jersey resource definition -
@Path("/data")
@GET
@Produces(MediaType.TEXT_HTML)
public String getData();
If the client does not provide HTTP request header "Accept" with value "text/html" you will see following exception in your application. To fix ensure client provided Accept encoding matches with what is defined by the REST API.
javax.ws.rs.WebApplicationException: null
        at com.sun.jersey.server.impl.uri.rules.TerminatingRule.accept(TerminatingRule.java:66) ~[jersey-server-1.17.jar:1.17]
        at com.sun.jersey.server.impl.uri.rules.ResourceObjectRule.accept(ResourceObjectRule.java:100) ~[jersey-server-1.17.jar:1.17]
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) ~[jersey-server-1.17.jar:1.17]
        at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) ~[jersey-server-1.17.jar:1.17]
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1511) [jersey-server-1.17.jar:1.17]
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1442) [jersey-server-1.17.jar:1.17]
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1391) [jersey-server-1.17.jar:1.17]
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1381) [jersey-server-1.17.jar:1.17]
        at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416) [jersey-servlet-1.17.jar:1.17]
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538) [jersey-servlet-1.17.jar:1.17]
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716) [jersey-servlet-1.17.jar:1.17]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:728) [servlet-api-3.0.jar:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) [tomcat-catalina-7.0.42.jar:7.0.42]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [tomcat-catalina-7.0.42.jar:7.0.42]

Tuesday, June 11, 2013

Simple slf4j configuration with Maven

Just add the following dependencies to your project pom.xml. The slf4j logging will be up and running with default implementation of logback configuration. The default configuration shows logs of DEBUG and above level for all packages.

Each dependencies are explained below -


  1. slf4j-api - slf4j api which you will use in your code to log messages.
  2. commons-logging - note the version this is too exclude all the commons-logging dependencies coming from other dependencies of your project. This version is available at http://version99.qos.ch/commons-logging/commons-logging/99-empty/
  3. logback-* - logback implementation which will be used to configure/control the logging. You can choose to use log4j or other implementation also.
  4. jcl-over-slf4j - enables migration from commons logging to slf4j without any code changes
  5. log4j-over-slf4j - enables migration from log4j logging to slf4j without any code changes
  6. jul-over-slf4j - enables migration from java util logging to slf4j without any code changes
  7. osgi-over-slf4j - enables migration from osgi logging to slf4j without any code changes


        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>99-empty</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.0.11</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.0.11</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-access</artifactId>
            <version>1.0.11</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.5</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
            <version>1.7.5</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jul-to-slf4j</artifactId>
            <version>1.7.5</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>osgi-over-slf4j</artifactId>
            <version>1.7.5</version>
            <scope>runtime</scope>
        </dependency>

Thursday, June 6, 2013

Spring MVC setup using Java Config

Add following config in the web.xml. The following config registers Spring listener. The listener knows that the configuration is based on Java Config by context param "contextClass". The context param "contextConfigLocation" tells the starting configuration class.
 <context-param>
  <param-name>contextClass</param-name>
  <param-value>
   org.springframework.web.context.support.AnnotationConfigWebApplicationContext
  </param-value>
 </context-param>

 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>com.project.config.ApplicationConfiguration</param-value>
 </context-param>

 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
Sample configuration class. Note the "@Configuration" which tells that this class is a configuration class. The below configuration will scan package com.project and look for @Configuration, @Service, @Repository, @Component annotated class and create beans. Note that @Controller is excluded as I like to keep that separate in dispacther servlet context (explained later in the article). Also "WebConfiguration.class" is excluded as it will be used in the dispatcher servlet context.
 @Configuration
 @ComponentScan(basePackages = "com.project", excludeFilters = { @Filter(value = WebConfiguration.class, type = FilterType.ASSIGNABLE_TYPE),
   @Filter(value = Controller.class) })
 public class ApplicationConfiguration {
 }
Add following config in the web.xml. The following config registers a dispatcher servlet. The dispatcher servlet routes urls to the respective controller. In this example urls ending with ".do" will be handled by Spring MVC.

The servlet knows that the configuration is based on Java Config by init param "contextClass". The init param "contextConfigLocation" tells the starting configuration class.
 <servlet>
  <servlet-name>SpringDispatcher</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
   <param-name>contextClass</param-name>
   <param-value>
    org.springframework.web.context.support.AnnotationConfigWebApplicationContext
   </param-value>
  </init-param>
  <init-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>com.project.server.config.WebConfiguration</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
  <servlet-name>SpringDispatcher</servlet-name>
  <url-pattern>*.do</url-pattern>
 </servlet-mapping>
Sample configuration class. Note the "@Configuration" which tells that this class is a configuration class. The below configuration will scan package "com.project" and look for @Configuration, @Component annotated class and create beans. Note that @Service, @Repository are excluded as I like to keep that separate in application context (see above). Also "ApplicationConfiguration.class" is excluded as it will be used in the application context.
 @Configuration
 @ComponentScan(basePackages = "com.project", excludeFilters = { @Filter(value = Service.class), @Filter(value = Repository.class),
   @Filter(value = ApplicationConfiguration.class, type = FilterType.ASSIGNABLE_TYPE) })
 @EnableWebMvc
 public class WebConfiguration {
 }

Wednesday, June 5, 2013

Spring MVC - HTTP Status 406

If you have encountered following errors with Spring MVC returning JSON response using @ResponseBody -

  1. On the broswer when accessing a resource -> HTTP Status 406 - The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers.
  2. In the logs -> org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation

Then here is the explanation and solution -

Say for example you have this controller -
@Controller
public class TestController {
    @RequestMapping(value = "/test")
    public @ResponseBody Test test() {
        return new Test();
    }
}
The Test POJO -
public class Test {
    private String name;

    protected String getName() {
        return name;
    }
}
Notice that the POJO has only one getter and that too protected.

You will get the mentioned errors due to the above reason.

The POJO which is getting returned as @ResponseBody must have at least one public getter.

Monday, December 28, 2009

Execute stored procedure in spring with return value and out parameters

Following code example shows how to execute stored procedure in spring with return value and out parameters. The comment along with the code explains the usage.


import java.math.BigDecimal;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;

public class StoredProcedureExampleDAO extends SimpleJdbcCall {

public JdbcDequeueTicketDAO(final JdbcTemplate jdbcTemplate) {
super(jdbcTemplate);
// Here declare all the IN and OUT parameters defined for the stored
// procedure
declareParameters(new SqlParameter("CountryCode", Types.VARCHAR),
new SqlOutParameter("CountryName", Types.VARCHAR));
// Register the stored procedure name
withProcedureName("getCountryName");
// This ensures the stored procedure return value also gets populated
// in the returned Map with key "return".
withReturnValue();
}

public final String getCountryName(final String countryCode) {
// Map to send the IN params values.
Map inParams = new HashMap();
inParams.put("CountryCode", countryCode);

// Map for the OUT params and return value.
Map outParams = null;
try {
outParams = execute(inParams);
} catch (Throwable t) {
throw new DataAccessException("Failed to get the country name", t);
}
if (null != outParams) {
BigDecimal returnValue = (BigDecimal) outParams.get("return");
// The logic of getCountryName stored procedure is that its
// returns 1 if execution is successful otherwise returns 0.
if (null != returnValue && 1 == returnValue.intValue()) {
// On success read the CountryName value
String countryName = (String) outParams.get("CountryName");
return countryName;
}
}
throw new DataAccessException("Failed to get the country name");
}

}

Tuesday, December 15, 2009

Logging using Aspect Oriented Programming

Most of the time while debugging I like to see the values of the incoming parameters and what is the returned value. The only solution is to use Eclipse debugger but some times its always not possible to run eclipse debugger. For example, the application is running in some environment where you cannot connect or sometimes you want to check quickly by just switching on DEBUG level logging.

Today I used Aspect Oriented Programming (AOP) to log incoming parameters and return value of a method execution. There are multiple ways but I like the following approach -

Ensure that required log4j and aspect jars are in the classpath of your project. The log4j is properly configured and gets initialized. If don't want to use log4j then in the MethodLogger class replace the log4j related code with whatever you require.

First create the following annotation which will be used against those methods for which logging is required -


public @interface LogMethod {
}


Now create following Aspect class in your source code. The comments explain the logic.


import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

// The Aspect annotation makes this class an Aspect
@Aspect
public class MethodLogger {

// The Before annotation ensures beforeMethod is called before the
// execution of a method annotated by LogMethod.
@Before(value = "@annotation(LogMethod)")
public void beforeMethod(JoinPoint joinPoint) throws Throwable {
// This ensures that the logger is of the actual class. If %c
// pattern is used in log4j then the class name of the actual
// method will print.
Logger logger = Logger.getLogger(joinPoint.getTarget().getClass());
if (logger.isDebugEnabled()) {
StringBuilder builder = new StringBuilder();
// Here we print the name of the method
builder.append(joinPoint.getSignature().getName());
builder.append("(");
// Here we print the values of the method arguments
appendArgumentValues(builder, joinPoint.getArgs());
builder.append(")");

logger.debug(builder.toString());
}
}

// The AfterReturning annotation ensures afterReturningMethod
// is after the execution of a method annotated by LogMethod.
@AfterReturning(value = "@annotation(LogMethod)", returning = "returnValue")
public void afterReturningMethod(JoinPoint joinPoint, Object returnValue)
throws Throwable {
Logger logger = Logger.getLogger(joinPoint.getTarget().getClass());
if (logger.isDebugEnabled()) {
StringBuilder builder = new StringBuilder();
builder.append(joinPoint.getSignature().getName());
builder.append("(");
// This prints the method argument class type
appendArguments(builder, joinPoint.getArgs());
builder.append("):");
// This prints the return value of the method. Incase of void
// it prints null
builder.append(returnValue);

logger.debug(builder.toString());
}
}

private void appendArguments(StringBuilder builder, Object[] objects) {
for (Object obj : objects) {
builder.append(obj.getClass().getName()).append(",");
}

if (objects.length > 0) {
builder.deleteCharAt(builder.length() - 1);
}
}

private void appendArgumentValues(StringBuilder builder, Object[] objects) {
for (Object obj : objects) {
builder.append(obj).append(",");
}

if (objects.length > 0) {
builder.deleteCharAt(builder.length() - 1);
}
}
}

Friday, November 13, 2009

SAXParser usage code sample

How to Parse XML in Java is always a tricky question. There different types of parsers available mainly - DOMParser (JDOM, Dom4j, XOM, etc.), SAXParser (Xerces, Piccolo, etc) and StAXParser (XPP3, Woodstox, Aalto, etc). Depending upon the nature and requirement of the project you need to select the type of parser.

Normally StAX Parsers also known as Pull Parsers are the fastest in terms of processing any size XML. The implementations available today don't support XSD validations. Some implementations support DTD validation only. StAX parsers also provide API to create an XML.

SAX Parsers also know as Push Parsers are the next best in terms of performance. Most of the implementations support XSD as well as DTD validations.

DOM Parsers are also fast but have memory overhead as it builds the whole XML tree in memory. Most of the implementations support XSD as well as DTD validations. The benefit of DOM is when you need to play with small size XMLs, need to read back and forward, change the XML and output new XML, etc. DOM parser also comes with good API support to traverse the XML compared to the handler implementation one need to do in case of SAX and StAX Parsers.

I required to parse a huge XML file and also validate against the defined XSD. I choose SAX parser because DOM have memory overhead and StAX doesn't support XSD validation. I have used Sun JDK6 provided Xerces implementation of SAX parser.

Here is the code snippet which parse the XML as well as validate. The comments in the code explains the functionality.


import java.io.File;
import java.io.IOException;
import javax.xml.XMLConstants;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SAXXMLValidator {
private SAXParser saxParser;

public SAXXMLValidator(String schemaFilePath) throws SAXException,
ParserConfigurationException {
// Creates a schema factory object for the XSD validation
SchemaFactory schemaFactory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

// schemaFilePath is the abosulte path, you can use any other way of providing the file.
Schema schema = schemaFactory.newSchema(new File(schemaFilePath));
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();

// Set validating as false as this only validates against the DTD mentioned in the XML document.
saxParserFactory.setValidating(false);

// If your XSD uses namespace then set this to true otherwise you will get error like this "cvc-elt.1: Cannot find the declaration of element 'project'"
saxParserFactory.setNamespaceAware(true);

// Provide the schema to the factory for the parser to validate the XML
saxParserFactory.setSchema(schema);

// Creates a SAXParser and its thread safe so best to initialize all this in Constructor to save creation cost at the time of call
saxParser = saxParserFactory.newSAXParser();
}

public void validate(String xmlFilePath, DefaultHandler defaultHandler)
throws SAXException, IOException {
// xmlFilePath is the abosulte path, you can use any other way of providing the file.
// Extend the DefaultHandler to create your own handler to parse the XML and collect the errors as DefaultHandler already implements ErrorHandler.
saxParser.parse(new File(xmlFilePath), defaultHandler);
}

public static void main(String[] args) {
try {
// I am using maven xsd and pom to test the code
SAXXMLValidator saxxmlValidator = new SAXXMLValidator(
"D:\\maven-v4_0_0.xsd");
saxxmlValidator.validate("D:\\pom.xml", new DefaultHandler());
} catch (SAXException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Friday, October 30, 2009

Configure Log4j for a web application on Apache Tomcat

Today I stumbled upon a problem of configuring log4j for a web application on Apache Tomcat. The problem is where to keep the log4j.xml and how initialize the logging system. One way is to keep the log4j.xml anywhere and change the Tomcat startup script to add -Dlog4j.configuration=<log4j.xml file path> but I do not want to depend on a change in Tomcat startup script.

I tried all the possible places but it did not work. I realized unless I define the log4j.configuration system parameter it will not work. I then looked at log4j api and found DOMConfigurator class which initializes the log4j system from log4j.xml.

Here is what I done to keep all configurations inside my application.

Create a listener class as shown below to initialize the log4j using the log4j.xml deployed with your application.


import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;

public class Log4jInitializationListener implements ServletContextListener {
public Log4jInitializationListener() {
}
public void contextInitialized(ServletContextEvent servletContextEvent) {
DOMConfigurator.configureAndWatch(servletContextEvent.getServletContext().getInitParameter("log4jXMLFilePath"));
Logger logger = Logger.getLogger(Log4jInitializationListener.class);
logger.debug("Log4j working");
}

public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}


Add these entries to your web.xml. Here we are defining a parameter to configure the log4j.xml file path and registering the above created listener.

<pre>
<context-param>
<param-name>log4jXMLFilePath</param-name>
<param-value>WEB-INF/classes/log4j.xml</param-value>
</context-param>
<listener>
<listener-class>Log4jInitializationListener</listener-class>
</listener>
</pre>

Start the application to confirm log4j is working. I have used the following log4j configuration so here it creates a server.log file.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
<appender name="RollingFileAppender" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="server.log"/>
<param name="MaxFileSize" value="100MB"/>
<param name="MaxBackupIndex" value="10"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %l - %m%n" />
</layout>
</appender>
<root>
<priority value="debug"/>
<appender-ref ref="RollingFileAppender"/>
</root>
</log4j:configuration>

Friday, June 19, 2009

Project Euler Problem 5

Problem 5

2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.

What is the smallest number that is evenly divisible by all of the numbers from 1 to 20?


public class ProblemFive {
public static void main(String[] args) {
// Any number will be always divisible by 1
// To be divisible by 2 it has to be an even number
// Number will be greater than or equal to at least 20
int start = 20;

while (true) {
int i = 3;

for (; i <= 20; ++i) {
if (0 != (start % i)) {
break;
}
}

if (i >= 20) {
break;
}

start += 2;
}

System.out.println(start);
}
}

Monday, June 15, 2009

Project Euler Problem 4

Problem 4

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 99.

Find the largest palindrome made from the product of two 3-digit numbers.

The solution is to multiply each three digit number and check if its a palindrome or not.


public class ProblemFour {
public static void main(String[] args) {
int palindrome = 9009;

for (int i = 999; i > 99; --i) {
for (int j = i; j > 99; --j) {
int product = i * j;

if (isPalindrome(String.valueOf(product)) &&
(product > palindrome)) {
palindrome = product;
}
}
}

System.out.println(palindrome);
}

public static boolean isPalindrome(String data) {
char[] array = data.toCharArray();
int reverseIndex = array.length - 1;
int index = 0;

while (index < reverseIndex) {
if (array[index] != array[reverseIndex]) {
return false;
}

++index;
--reverseIndex;
}

return true;
}
}

Hibernate OneToMany annotation mapping using JoinTable

Hibernate OneToMany annotation mapping using JoinTable

Recently I explored Hibernate OneToMany annotation mapping using JoinTable.

Consider an Airline entity having list of Airports. The mapping between the two is stored in a JoinTable airline_airports.

CREATE TABLE airline(
code char(2) PRIMARY KEY NOT NULL,
name varchar(50) NOT NULL
);

CREATE TABLE airport(
code char(3) PRIMARY KEY NOT NULL,
name varchar(50) NOT NULL
);

CREATE TABLE airline_airport(
airline_code char(2) NOT NULL,
airport_code char(3) NOT NULL,
CONSTRAINT PRIMARY PRIMARY KEY (airline_code,airport_code)
);

ALTER TABLE airline_airport ADD CONSTRAINT airline_airport_ibfk_1
FOREIGN KEY (airline_code) REFERENCES airline(code) ON DELETE NO ACTION ON UPDATE NO ACTION;

ALTER TABLE airline_airport ADD CONSTRAINT airline_airport_ibfk_2
FOREIGN KEY (airport_code) REFERENCES airport(code) ON DELETE NO ACTION ON UPDATE NO ACTION;

First of all we need to create Hibernate Entities for Airline and Airport using annotations. Notice the annotations defined for airports attribute of Airline class. This is where we are defining the relationship between Airline and Airport.

@Entity
@Table(name = "airline")
public class Airline implements Serializable {
@Id
@Column(name = "code")
private String code;
@OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
@JoinTable(name = "airline_airport", joinColumns = @JoinColumn(name = "airline_code")
, inverseJoinColumns = @JoinColumn(name = "airport_code")
)
private List airports;

public String getCode() {
return code;
}

public void setCode(String code) {
this.code = code;
}

public List getAirports() {
return airports;
}

public void setAirports(List airports) {
this.airports = airports;
}
}

@Entity
@Table(name = "airport")
public class Airport implements Serializable {
@Id
@Column(name = "code")
private String code;
@Column(name = "name")
private String name;

public String getCode() {
return code;
}

public void setCode(String code) {
this.code = code;
}

public String getName() {
return name;
}

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

Create an Airline object and add a list of Airlines. When you will save the airline object, hibernate will persist all the data in airline, airport and airline_airport table.

If you don't use the cascade annotation then ii will not save the data in airport table. This means it will fail to insert record in airline_airport table if an airport is not already in the airport table.

Thursday, May 21, 2009

Apache cxf using annotations and integration with Spring

Today I will show you how you can create a webservice using Apache CXF version 2.2.1. I will be building this webservice on top of my previous application.

Create a interface AirlineManager to expose methods over webservice. The create method takes airline code and name to create a Airline record in database. Annotation @WebService tells that this is a interface for webservice.

package com.travel;

import javax.jws.WebService;

@WebService
public interface AirlineManager {
public void create(String code, String name);
}

Implement the above webservice interface. We are using AirlineDao created in earlier post. Notice the @WebService(endpointInterface = "com.travel.AirlineManager") which tells that this implementation is for AirlineManager interface.

package com.travel;

import com.travel.dao.AirlineDao;
import javax.jws.WebService;

@WebService(endpointInterface = "com.travel.AirlineManager")
public class AirlineManagerImpl implements AirlineManager {
private AirlineDao airlineDao;

public AirlineManagerImpl(AirlineDao aAirlineDao) {
airlineDao = aAirlineDao;
}

@Override
public void create(String code, String name) {
airlineDao.create(code, name);
}
}

Add this in the spring-context.xml. Here we are importing some cxf beans, defining bean AirlineManagerImpl and creating airlineManagerService webservice.

<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-http-jetty.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

<bean id="airlineManager" class="com.kaleconsultants.travel.AirlineManagerImpl">
<constructor-arg><ref bean="airlineDao"/></constructor-arg>
</bean>

<jaxws:endpoint id="airlineManagerService" implementor="#airlineManager" address="/AirlineManagerService" />

Add this in your web.xml.

<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>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

Deploy the application in tomcat and your webservice is ready. You can check the wsdl http://host:port/travel/AirlineManagerService?wsdl.

To test the webservice, you need to create a client. You can use wsdl2java available in the bin directory of cxf.

Execute this command, this will generate the wsdl stubs.
wsdl2java http://host:port/travel/AirlineManagerService?wsdl

Write a client like this and there you go.......

package com.travel;

public class ClientTest {
public static void main(String[] args) {
AirlineManagerImplService service = new AirlineManagerImplService();
AirlineManager airlineManager = service.getAirlineManagerImplPort();
airlineManager.create("IC", "Indian");
}
}

Wednesday, May 20, 2009

Hibernate integration with Spring

In my last post Basic Hibernate Annotations example, I wrote about a simple hibernate example. Today I will take that example forward and show you how you can integrate hibernate with Spring. I used Spring version 2.5.6.SEC01.

Create spring-context.xml file. We define a spring datasource, hibernate session factory, hibernate template(spring wrapper api of hibernate session), transaction manager. Bean airlineDao is configured to use annotation based transaction handling. The "<tx:annotation-driven/>" actually enables Spring container to execute methods under transaction, if transaction annotations are used.

<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/travel"/>
<property name="resourceRef" value="true" />
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource"><ref bean="dataSource"/></property>
<property name="configLocation"><value>classpath:hibernate.cfg.xml</value></property>
<property name="configurationClass"><value>org.hibernate.cfg.AnnotationConfiguration</value></property>
</bean>

<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
</bean>

<tx:annotation-driven/>

<bean id="airlineDao" class="com.travel.dao.AirlineDao">
<property name="hibernateTemplate"><ref bean="hibernateTemplate"/></property>
</bean>
</beans>

Create AirlineDao class. Notice the @Transactional (readOnly = true) annotation which brings the execution of this class under transaction. The create method have (readOnly = false) because in this method we are actually updating the table.

package com.travel.dao;

import com.travel.domain.Airline;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

@Transactional (readOnly = true)
public class AirlineDao extends HibernateDaoSupport {
@Override
@Transactional (readOnly = false)
public void create(String code, String name) {
Airline airline = new Airline();
airline.setCode(code);
airline.setName(name);
getHibernateTemplate().save(airline);
}
}

Add the below xml in your web.xml. This Spring ContextLoaderListener initializes the spring beans defined in file spring-context.xml (we created above).

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/spring-context.xml</param-value>
</context-param>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Create a simple servlet to test the DAO. The execution of this servlet will create a new airline record in airline table.

package com.travel.servlet;

import com.kaleconsultants.travel.dao.AirlineDao;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class AirlineServlet extends HttpServlet {
private static final long serialVersionUID = 2409603422056073641L;

protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {

String code = request.getParameter("code");
String name = request.getParameter("name");
ApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
AirlineDao airlineDao = (AirlineDao) context.getBean("airlineDao");
airlineDao.create(code, name);
}
}

Monday, May 18, 2009

Basic Hibernate Annotations example

As part of my POC, today I developed a simple hibernate annotations based example. To run this example, you need JDK 5.0 or higher and hibernate 3.2.0.GA or above. I am using JDK 1.6, MySql 5.1, Tomcat 6.0.18 and Hibernate 3.3.1.GA.

Create hibernate.cfg.xml file. This file should be available in the classpath at runtime. I developed this example as part of a web application and I am using a datasource defined in my container. See my earlier post on How to configure a datasource in Tomcat


<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.datasource">java:comp/env/jdbc/travel</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="show_sql">true</property>
<mapping class="com.travel.domain.Airline"/>
</session-factory>
</hibernate-configuration>


This example needs following table in your database.


CREATE TABLE airline (
code char(2) PRIMARY KEY,
name varchar(50) NOT NULL,
created timestamp DEFAULT NOW() NOT NULL
);


Create HibernateUtil class which provides Hibernate session to interact with database. new AnnotationConfiguration().configure() looks for hibernate.cfg.xml in the classpath, so make sure to deploy the file in WEB-INF/classes directory.


package com.travel.hibernate.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

public class HibernateUtil {
private static final SessionFactory sessionFactory;

static {
try {
sessionFactory = new AnnotationConfiguration().configure()
.buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}

public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}


Airline class maps with the airline table we created above. Notice the annotations used to define the mapping.


package com.travel.domain;

import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "airline")
public class Airline implements Serializable {
private static final long serialVersionUID = 6864693643526282786L;
@Id
@Column(name = "code")
private String code;
@Column(name = "name")
private String name;
@Column(name = "created")
private Date createdTime;

public String getCode() {
return code;
}

public void setCode(String code) {
this.code = code;
}

public String getName() {
return name;
}

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

public Date getCreatedTime() {
return createdTime;
}
}


Simple servlet to test the application. I used the hibernate code directly in my servlet for simplicity. You should define one DAO layer to encapsulate the hibernate code. To test acccess your servelt use url like http://host:port/travel/AirlineServlet?code=LH&name=Lufthansa


package com.travel.servlet;

import com.travel.domain.Airline;
import com.travel.hibernate.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class AirlineServlet extends HttpServlet {
private static final long serialVersionUID = 2409603422056073641L;

protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
SessionFactory session = HibernateUtil.getSessionFactory();
Session sess = session.getCurrentSession();
Transaction tx = sess.beginTransaction();
// Get the airline code and name
String airlineCode = request.getParameter("code");
String airlineName = request.getParameter("name");
// Create Airline object
Airline airline = new Airline();
airline.setCode(airlineCode);
airline.setName(airlineName);
// Save the record in database
sess.save(airline);
tx.commit();
session.close();
}
}

Friday, May 15, 2009

Project Euler Problem 3

Problem 3

The prime factors of 13195 are 5, 7, 13 and 29.

What is the largest prime factor of the number 600851475143 ?

The solution is to find a factor and check if its a prime number. Since we need largest prime factor, run the for loop in reverse direction. Also a prime factor of a number cannot be greater than the square root of the number.


public class ProblemThree {
public static void main(String[] args) {
long range = (long) Math.sqrt(600851475143L);

for (long i = range; i > 1; --i) {
if ((0 == (number % i)) && isPrimeNumber(i)) {
System.out.println(i);

break;
}
}
}

public static boolean isPrimeNumber(long number) {
long halfRange = number / 2;

for (long i = 2; i <= halfRange; ++i) {
if (0 == (number % i)) {
return false;
}
}

return true;
}
}

Wednesday, May 13, 2009

Project Euler Problem 2

Today I got some time to look at Euler Problem 2.

Problem 2

Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

Find the sum of all the even-valued terms in the sequence which do not exceed four million.

The solution is to run a loop to find the next term in Fibonacci series. Check the evenness of the term and add to the sum.


public class ProblemTwo {
public static void main(String[] args) {
int firstTerm = 0;
int secondTerm = 1;
int newTerm = 0;
int sum = 0;

while (secondTerm <= 4000000) {
newTerm = firstTerm + secondTerm;

if (0 == (newTerm % 2)) {
sum += newTerm;
}

firstTerm = secondTerm;
secondTerm = newTerm;
}

System.out.print(sum);
}
}

Monday, May 11, 2009

Project Euler Problem 1

Recently I came across Project Euler web site. This is what the site has to say

"Project Euler is a series of challenging mathematical/computer programming problems that will require more than just mathematical insights to solve. Although mathematics will help you arrive at elegant and efficient methods, the use of a computer and programming skills will be required to solve most problems. The motivation for starting Project Euler, and its continuation, is to provide a platform for the inquiring mind to delve into unfamiliar areas and learn new concepts in a fun and recreational context."

I quickly registered to check what kind of mathematical problems are asked. I couldn't resist myself to start solving the problems. I chose Java to solve the problems as this is the only language I know ;)

Problem 1

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.

The solution is very simple and the code is self explanatory.

public class ProblemOne {
public static void main(String[] args) {
int result = 0;

for (int i = 1; i < 1000; ++i) {
if ((0 == (i % 3)) || (0 == (i % 5))) {
result += i;
}
}

System.out.println(result);
}
}

Wednesday, May 6, 2009

.equals Vs == in Java

Recently a Java developer asked for help in a J2EE application. He was stuck in a bug for the past two days. The development environment was Windows, Eclipse IDE and Tomcat server. He was using old mill fashion of debugging by adding System.out.println in his code. Before anything else I asked him to setup debugger in Eclipse. The debugger made his life easy and helped him quickly figure out the problem area. But he couldn't understand why a particular if condition not behaving correctly. As you can guess from the title of this blog, it was the same age old problem of == and .equals().

In Java == is used to compare variables of primitive data types (byte, short, int, long, float, double, boolean, char). If == is used to compare two objects then it compares the object reference and not the values. An object in Java stores the memory reference where the object data is stored. In order to compare the values you need to use object1.equals(object2). Lets learn the difference with simple example -

String s1 = new String("test");
String s2 = new String("test");

Here we have defined two String objects s1 and s2. Value of both the variable is same "test", so we expect the variables to be equal.

if (s1 == s2) {
  System.out.println("Strings are equal");
} else {
  System.out.println("Strings are not equal");
}

Surprised to see that it prints "Strings are not equal". Well its correct as both s1 and s2 are referring to two different memory references.

if (s1.equals(s2)) {
  System.out.println("Strings are equal");
} else {
  System.out.println("Strings are not equal");
}

The above code is correct way of comparing String values. This code will print "Strings are equal". Now consider this below code -

String s1 = "test";
String s2 = "test";

if (s1 == s2) {
  System.out.println("Strings are equal");
} else {
  System.out.println("Strings are not equal");
}

Another surprise, it prints "Strings are equal". Its because Java compiler does the optimization. Notice the way s1 and s2 are defined. In earlier code we used new String("test") which makes sure new object gets created. But in this code compiler uses the same reference to define the two variables.

== and .equals() usage holds true for objects of any class. Remember every Java class implicitly extends Object class. Most of the Java core classes like Integer, Long, Double, Boolean, etc have .equals() method implemented. For your own class don't forget to implement the .equals() otherwise .equals() will behave same as ==.