Spring Framework

30
Dec

SOAP Web-service by means of Spring-WS

Posted by eugene as Spring Framework, Web Services

Webservices

Once I’ve got a task to start developing of the web services and had the sources of a simple project without any explanation. The project, for sure couldn’t be laundched. What is Spring and how it works, I couldn’t also imagine. I also couldn’t find any adequate articles of developing the web services by means of Spring – neither Russian, nor English. I had to learn everything by myself, and it appeared all wasn’t so awful. And just recently I decided to see what new opportunities were added in Spring since then, and to update old services what entailed writing of this article.

This article is the guide of simple Web service development that uses SOAP protocol.

Thus we’ll write the simple service that accepts the username and sends a greeting and the current time on the server.

what will we need?

Preparation for work

Let’s create a new Web application project. In Eclipse this will be: “File => New => Dynamic Web Project”. I’ve called the project HelloService. Then let’s copy libraries from Spring, XMLBean, wsdl4j, commons-logging into the WEB-INF/lib project catalogue. If you wish you can add them to the server libraries in order not to move them with each application.

Creation the WSDL scheme

In fact, WSDL scheme is intended to describe the service. We won’t certainly create it manually. The scheme will be generated automatically by Spring, but more on that will be mentioned later.

Defining input and output

Input data:

  • String name

Output data:

  • Greeting string;
  • Current time.

Creating the description of input and output data

Let’s create HelloService.xsd file in the WEB-INF catalogue. This file will be necessary for generating WSDL scheme and creating the corresponding Java classes.

File contents:

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/HelloService" elementFormDefault="qualified">
  <element name="ServiceRequest">
    <complexType>
      <sequence>
        <element name="name" type="string" maxOccurs="1" minOccurs="1"/>
      </sequence>
    </complexType>
  </element>
  <element name="ServiceResponse">
    <complexType>
      <sequence>
        <element name="hello" type="string" maxOccurs="1" minOccurs="1"/>
        <element name="currentTime" type="time" maxOccurs="1" minOccurs="1"/>
      </sequence>
    </complexType>
  </element>
</schema>

The targetNamespace attribute is used namespace. I.e. all the created objects will be located in the org.example.hellpService package.

The ServiceRequest and ServiceResponse describe input and output data correspondly (request/answer).

The minOccurs and maxOccurs attributes define the number of repeats of the given component within one single element. If not to specify these options, then by default they are considered to be equal to 0. It’s necessary to specify minOccurs = 0 for the optional component. When the number of components is unlimited: maxOccurs = unbounded.

You can read about XML schemes in more details here.

Creating JavaBeans

Based on the created scheme we’ll create Java classes. To do this, create build.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<project name="imsjob" default="build" basedir=".">
<property name="WS_HOME" value="C:\AST\lib\standart"/>
<property name="encoding" value="UTF-8"/>
<path id="xbean.classpath">
    <fileset dir="${WS_HOME}">
      <include name="*.jar"/>
    </fileset>
  </path>
    <taskdef name="xmlbean" classname="org.apache.xmlbeans.impl.tool.XMLBean" classpathref="xbean.classpath" />
      <target name="init">
    <echo message="Start init"/>
  </target>
    <target name="build" depends="init">
    <xmlbean schema="HelloService.xsd" destfile="lib\helloservice.jar" classpathref="xbean.classpath"/>
  </target>
</project>

The WS_HOME parameter should point on the catalogue where XMLBeans located. HelloService.xsd is the path to the created scheme. lib\helloservice.jar is the created java-library.

Then let’s run Ant-build (I hope you’ve already installed it). In Eclipse you can run it so: right-clicking build.xml=> Run As => Ant Build. If via the command line: ant -buildfile build.xml. And then just wait for the build completion. After that, you can check the WEB-INF\lib project catalogue for the presence of the corresponding library (helloservice.jar).

Service realization

Create interface and service class

Service interface:HelloServiceImpl.java:

package org.example;
import java.util.Calendar;
public interface HelloService {
  public String getHello(String name) throws Exception;
  public Calendar getCurrentTime();
}

Service realization: HelloServiceImpl.java:

package org.example;
import java.util.Calendar;
import org.springframework.stereotype.Service;
@Service
public class HelloServiceImpl implements HelloService {
  public String getHello(String name) throws Exception {
    return "Hello, " + name + "!";
  }
  public Calendar getCurrentTime() {
    return Calendar.getInstance();
  }
}

I think there’s no need to comment the code. The only thing that people which haven’t met Spring before could have questions what is the @Service annotation. But I’ll talk about it a bit later.

Endpoint

Endpoint is the class which will be responsible for the processing of input requests (like the entry point).

Let’s create the HelloServiceEndpoint.java file:

package org.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.example.helloService.ServiceRequestDocument;
import org.example.helloService.ServiceRequestDocument.ServiceRequest;
import org.example.helloService.ServiceResponseDocument;
import org.example.helloService.ServiceResponseDocument.ServiceResponse;
 
@Endpoint
public class HelloServiceEndpoint{
  private static final String namespaceUri = "http://www.example.org/HelloService";
  private HelloService helloService;
  @Autowired
  public void HelloService (HelloService helloService) {
    this.helloService = helloService;
  }
    @PayloadRoot(localPart = "ServiceRequest", namespace = namespaceUri)
  public ServiceResponseDocument getService(ServiceRequestDocument request) throws Exception {
    ServiceRequestDocument reqDoc = request;
    ServiceRequest req = reqDoc.getServiceRequest();
    ServiceResponseDocument respDoc = ServiceResponseDocument.Factory.newInstance();
    ServiceResponse resp = respDoc.addNewServiceResponse();
 
    String userName = req.getName();
    String helloMessage = testNewService.getHello(userName);
    Calendar currentTime = testNewService.getCurrentTime();
 
    resp.setHello(helloMessage);
    resp.setCurrentTime(currentTime);
    return respDoc;
  }
}

So what is done here?

The @Endpoint annotation exactly defines that this class will process the input requests. namespaceUrl is the same namespace that was specified during the creation of xml scheme.

Now let’s go a bit back and remember about the @Service annotation. Without going into details in order not to overload the reader with the extra information, the annotation tells Spring to create the appropriate object. The @Autowired annotation serves for injection (automatic replacement) of the corresponding object. Certainly when building simple application there is no sense in using these annotations but I decided not to exclude them in this example.

Hence, let’s go forward. The @PayloadRoot annotation defines before the method by receiving of which request this method will be called. In our case, it’s a “ServiceRequest”.

In all the rest everything should be clear. Pay attention that ServiceRequest, ServiceResponse and so on are exactly those classes which have been created on the basis of our xml scheme.

Spring configuration of the service

Here is almost the completion. Let’s create the service-ws-servlet.xml.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:sws="http://www.springframework.org/schema/web-services"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 
  <context:component-scan base-package="org.example" />
  <sws:annotation-driven />
 
  <bean class="org.springframework.ws.server.endpoint.adapter.GenericMarshallingMethodEndpointAdapter">
<property name="marshaller" ref="marshaller" />
<property name="unmarshaller" ref="marshaller" />
  </bean>
 
  <bean id="marshaller" class="org.springframework.oxm.xmlbeans.XmlBeansMarshaller"/>
 
  <sws:dynamic-wsdl id="HelloService" portTypeName="service" locationUri="/HelloService" >
    <sws:xsd location="/WEB-INF/HelloService.xsd" />
  </sws:dynamic-wsdl>
</beans>

sws:annotation-driven – tells exactly about that annotations are used in this project. And context:component-scan points on the package where annotation searching will be performed, by the same time searching is performed in subpackages as well.

Both subsequent beans will always be constant. Their sense is to receive and to convert the request from XML into Java object and further reverse conversion.

sws:dynamic-wsdl is responsible for the automatic generation of WSDL-based document created by XML scheme. location points on the path to scheme. locationUrl is the address (relating to container) which will be available for WSDL scheme. In my case WSDL is available over the following address: http://localhost/HelloService/HelloService.wsdl.

Deployment descriptor

And finally, the last one. In the WEB-INF catalogue let’s modify and create the web.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
  <display-name>HelloService</display-name>
  <description>HelloService</description>
  <servlet>
    <servlet-name>service-ws</servlet-name>
    <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
    <init-param>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
    </init-param>
  <servlet-mapping>
    <servlet-name>service-ws</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>

I won’t describe this file, most of them you should know. In fact it shouldn’t change for simple projects. It’s worth to note that the servlet name should correspond to the file name of Spring configuration of the service-ws-servlet.xml service.

Then, let’s deploy the application on the server. Creation of the service is completed at this stage. If we haven’t missed anything, the service should function well.

The very first sign of correct performance is the created WSDL scheme. In order to check it, just go over the address of this scheme: (http://localhost/HelloService/HelloService.wsdl) and look: the xml file should be displayed there. If nothing displayed or any other error occurred, re-read the whole article and search what was done incorrectly.

For further verification, we need soapUI (I have version 3.0.1).

Let’s install and run it, and then create a new project: File => New soapUI Project.

In the Initial WSDL/WADL field insert the link to WSDL scheme: (http://localhost/HelloService/HelloService.wsdl).

Let’s open the necessary request in the created project.

request

In the Name field type the name and press the “Send request” button.

name

As a result we get the answer from the server with the greeting and current time.

answer

If something went wrong then read this article once again.

What’s next?

Then you should write client for the web service. But it’s the material for another article which could be probably written later if this material will be interesting for anyone.

24
Dec

Authorization on the website via API of social networks with integration into Spring Security

Posted by eugene as Spring Framework, Web Applications

I’ve decided to implement authorization (registration) on the prepared website and to identify users with the help of the social network developer instrument (Social Networks REST API) – tge subject is not far innovative, widely used and very easy to use. I won’t list all the benefits and convenience of using such functionality on their websites, but I want to admit that I am very happy not to remember passwords for each website (even I have a couple of standard used), not to engage in long and boring registration with sending mails and acknowledgements, and do not deal with captchas again and so on.

The API data functionality is rather primitive, simple technology and implementation is quite similar and simple. But when you familiarize with the technology, it is not only enough to have API documentation and social networking examples. In addition, as described in the topic, the used language is Java which automatically reduces the amount of useful information. And there’s no too much information in RU net either. You can follow the path of the least resistance and use the third-party RESTful products, but a) it doesn’t give full understanding of the process, and b) reduces the switching properties of the desired process; c) the third-party product research often can be more difficult that the development of its implementation. While ease of use of such third-party product can facilitate the development at times. However I’ve put the emphasis on making the most control over all processes in this review even at the expense of universality (we “fasten” specific functionality to the particular site, and only a few make the versatile product “for all life occasions” out of it). In addition, I am interested not only how to implement the authentication of users, but also to invent it into the project security system which is provided by the Spring Security 3 framework.

The used set of platforms and tools is: Spring Core 3.1, Spring MVC 3.1, Spring Security 3.1, Hibernate 4.1. The implementation project is foreig, therefore a set of introduced social networks is standard “for them” – Facebook, Twitter, Google+, Linkedin.

I want to admit that a ready “out of the box” project is available in the Spring package – Spring Social (for now is release 1.0.2) which is currently encapsulated in a wonderful Spring-framework product. Surely it would have been a professional solution but our task is to control everything and make the process as transparent for understanding as possible. And it’s not so good with Social itself.

1. Model.

I’ve chosen a little risky and controversial way, combining the user and POJO, and UserDetails, and Entity in the object. In terms of the programming approach this is wrong but: a) it’s very convenient; and b) saves the creation of severeal layers which saves us to make separate POJO+Entity, separately UserDetails and separately DTO which actually duplicates the content.

The proposed scheme of model construction looks like the following:

Model

I’ve identified two layers (AuthUser and DataUser) in order not to interfere with authorization logic with the business logic of the project: both the visitor and the manager and whoever else – will be authenticated the same but will have their own set of properties. For example, in my project there’re Jobseekers and Employers, the same way get to the website but they have completely different structure of the model.

As for the separation of structure within the layers, this is obvious – a set of the received fields from Facebook, Twitter and so on, and especially during the standard authorization, is so different that to create the entire terribly stretched structure for everything is just silly and in terms of building a database – redundant. As per scalability, when adding a new service provider the work with such a structure would be extremely uncomfortable.

Below are the listings of some objects, and also the used enum classes.

AuthUser.java:

@ Entity
    @ Table(name = "auth_user")
    @ Inheritance(strategy = InheritanceType.JOINED)
    public class AuthUser implements Serializable, UserDetails {
        @ Id
        @ Column(name = "id")
        @ GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
 
        @ Column(name = "identification_name", length = 64, nullable = false)
        private String identificationName;
 
        @ Enumerated(EnumType.STRING)
        @ Column(name = "type", nullable = false)
        private AuthorityType type;
 
        @ Column(name = "binary_authorities", nullable = false)
        private Long binaryAuthorities;
 
        @ Column(name = "enabled", nullable = false, columnDefinition = "tinyint")
        private Boolean enabled;
 
        @ Transient
        private Set<Authority> authorities;
 
        @ OneToOne(fetch = FetchType.LAZY, orphanRemoval = true)
        @ Cascade({CascadeType.ALL})
        @ JoinColumn(name="user_id")
        private User user;
 
        @ Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            authorities = EnumSet.noneOf(Authority.class);
            for (Authority authority : Authority.values())
            		if ((binaryAuthorities & (1 << authority.ordinal())) != 0)
                    authorities.add(authority);
            return authorities;
        }
        public void setAuthority(Set<Authority> authorities) {
            binaryAuthorities = 0L;
            for (Authority authority : authorities)
                binaryAuthorities |= 1 << authority.ordinal();
        }
        @ Override
        public String getPassword() {
            return type.name();
        }
        @ Override
        public String getUsername() {
            return identificationName;
        }
        @ Override
        public boolean isAccountNonExpired() {
            return true;
        }
        @ Override
        public boolean isAccountNonLocked() {
            return true;
        }
        @ Override
        public boolean isCredentialsNonExpired() {
            return true;
        }
 
        //getters/setters
    }

AuthorityType.java:

public enum AuthorityType implements Serializable {
        SIMPLE, FACEBOOK, TWITTER, GOOGLE, LINKEDIN;
    }

Authority.java:

public enum Authority implements GrantedAuthority {
        NEW_CUSTOMER, CUSTOMER, ADMINISTRATOR;
 
        @ Override
        public String getAuthority() {
            return toString();
        }
    }

FacebookAuthUser.java:

@ Entity
    @ Table(name = "facebook_auth_user")
    public class FacebookAuthUser extends AuthUser {
        @ Column(name = "first_name", length = 32)
        private String firstName;
 
        @ Column(name = "last_name", length = 32)
        private String lastName;
 
        @ Column(name = "email", length = 64)
        private String email;
 
        @ Column(name = "token", length = 128)
        private String token;
 
        //any number of available properties
        //getters/setters
    }

TwitterAuthUser.java:

@ Entity
    @ Table(name = "twitter_auth_user")
    public class TwitterAuthUser extends AuthUser {
        @ Column(name = "screen_name", length = 64)
        private String screenName;
 
        @ Column(name = "oauth_token", length = 80)
        private String oauthToken;
 
        @ Column(name = "oauth_token_secret", length = 80)
        private String oauthTokenSecret;
 
        //any number of available properties
        //getters/setters
    }

SimpleAuthUser.java:

@ Entity
    @ Table(name = "simple_auth_user")
    public class SimpleAuthUser extends AuthUser {
        @ Column(name = "password", length = 40, nullable = false)
        private String password;
 
        @ Column(name = "uuid", length = 36, nullable = false)
        private String uuid;
 
        @ Override
        public String getPassword() {
            return password;
        }
 
        //getters/setters
    }

As you can see, it’s not all enough without the slightest “magics”:

  • I don’t want to do one more structure (table) for storing user roles and to miss the opportunity to assign a user multiple roles changing a set of roles for another one is weird. Therefore I store a binary representation of the set of roles in the database, and I feed the set to Spring Security. The main thing is to remember to make a transformation while reading from the database. Ideologically it’s not correct to hold the transformation mechanism in POJO, it is necessary to leave it in the controller or DAO, but let’s assume it costs of publication.
  • The type field (AuthorityType enum) – it doesn’t carry the special need rather to visualize data in the database, plus it’s easier to use user.getType() in the representation rather than investigate the belonging to one of the classes – user insteadof TwitterAuthUser, even though it’s not important.
  • The UserDetails interface requires to implement a number of methods. In particular, identificationName (and getUsername()) is the field that stores the identifiers: FacebookID for Facebook, TwitterID for Twitter, nickname or email for the standard authorization. The getPassword() method in my case returns that same type, further it will be used by Spring Security in order to form hash cookies in the RememberMe mechanism. In order to improve the project security in every class you can redefine this method by assigning the secure data to it, as I’ve done this in the SimpleAuthUser class. For others it can be tokens or secret tokens. What to do next with the methods and potentially corresponding to them isAccountNonExpired, isAccountNonLocked, isCredentialsNonExpired properties – to decide as appropriate of using such data, in this review I don’t use them drowning return true.

As you can see in the scheme and code, I’ve decided to use the lazy dependency between the objects of different layers, even though they are interrelated as “one-to-one”. There’re two objectives: 1) AuthUser often twitches by framework in the controller and view, and there’s no great desire to pull the dependent structure all over itself, moreover it can be quite extended and massive (I have almost 5-6 EAGER dependencies in the Jobseeker tables of the project, not counting LAZY – these are both phone numbers, and address, and proffessions and so on), that’s why in my opinion the safe side will not prevent. 2) you shouldn’t forget that these layers are related to different logics layers: AuthUser is twitching by the Spring Security framework, and in parallel the changes can occur in DataUser, and there’s no much desire to engage in constant tracking and updating. I agree that the decision is dispute and it does not claim to be definitive. Perhaps it is necessary to link the contrary, thus the listed problems will be gone, but the business logic, you can always pull the authorization bean. It’s left up to the developers.

What’s related to the DataUser class and the dependent these are the simple POJO classes, directly DataUser contains common for all properties (e.g. id, firstName, lastName, email, location) and the rest expand it by adding the specific for them properties (it’s impractical to show the listings).

2. Controller.

Basically in terms of authentication and authorization there’s no much difference, and verious network providers predispose these terms in their own way. However, I clearly distinguish two concepts in this report – registration and the authorization itself or input (both are based on the authorization in the social network provider). For example, when participating on forum or submitting comments you simply should log in – whether it is the first entry or the hundredth. In my division for registration and basic authorization I am chasing the need to create a user model in the application for registartion. And while it might be easier to implement – at the entrance check – whether such person exists or not – and create the user structure in case of the first entry. But a) there exists a standard registration and it’s logical to make visual division “here is one thing and there another one” (notorious usability); b) how it’s not disappointing but API of the social networks are not agreed to provide information about their clients – for example, Facbook API provides email, name, gender, location; Twitter API provides screen_name, which may not necessarily be “a name or surname”, doesn’t provide email (they have a position to clearly distinguish reality and virtuality); Google+ API provides name, last name, email but nothing about location; LinkedIn API – name, last name, gender, location but doesn’t provide email. Since my project is very closely tied to the personal visitor data (project for the recruiting company), together with the registration I point to the need to fill in some fields (initially except the Facebook users all had to specify something, now is simplified and such need exists only for Twitter users, though I do not exclude a complete failure and the filling of fields will be simply just needed, for example when trying to get into the “zone”). Therefore my implementation is a bit overblown, though it only helps to understand better the mechanism of authentication.

I want to recall that it’s necessary to create your own application in every social network and to use its settings for work (or testing). This is developers.facebook.com/apps for Facebook, dev.twitter.com/apps for Twitter, code.google.com/apis/console for Google+, www.linkedin.com/secure/developer for LinkedIn. When creating an application there exist three important parameters which are available in every provider – key (API key, Consumer key, Client ID), secret key (App Secret, Consumer Secret, Client Secret, Secret key) and the redirect address (say, until recent time some providers’ localhost redirect didn’t work properly, but for now all is tested – all work with the address type of http://localhost:8080/myproject). There you can configure other settings, including the logo of the application, however, Linkedin requires the SSL link to the image (strange wish).

Facebook and Google+ have been using new OAuth 2 protocol, Twitter and LinkedIn are still on the older OAuth protocol (Google+ also supported the first OAuth version till the 20th of April, 2012). Due to my descretion (although I can’t imagine that there could be another opinion) it’s immeasurably easier and more convenient to work with OAuth 2, however, despite the fact that it’s quite popular, it still hasn’t been approved as standard. The concept of its work is rather primitive (the most popular scheme).

pic2

Thus, a user clicks one of the registration buttons on the web page:

capt

(and I don’t leave any “extra” functionality on the page, just a button with the address like www.myproject.com/registration/facebook and so on), the request will get into the controller (for Facebook).

@ RequestMapping(value = "/registrate/facebook", method = RequestMethod.POST)
    public ModelAndView facebookRegistration() throws Exception {
        return new ModelAndView(new RedirectView(FACEBOOK_URL + "?client_id=" + FACEBOOK_API_KEY +
            + "&redirect_uri=" + FACEBOOK_URL_CALLBACK_REGISTRATION +
            + "&scope=email,user_location&state=registration", true, true, true));
    }

The scope parameters can be found at developers.facebook.com/docs/authentication/permissions (for Twitter – dev.twitter.com/docs/platform-objects/users, Google+ – developers.google.com/accounts/docs/OAuth2Login#userinfocall, LinkedIn – developer.linkedin.com/documents/profile-fields), I’ve put only the couple of examples. The redirect_uri domain must match the registered address of the date application. state is the “free” parameter which I use as the semaphor for the further actions – registration, signin, autosignin.

Then the user is being redirected to the root Facebook authorization page where it will allow the application to use its data, and if the resolution are going out of the basic scopes, they will be listed in the authentication window.

After authorization our controller with the FACEBOOK_IRL_CALLBACK_REGISTRATION mapping gets a call (in any client’s decision – authenticate, cancel, return). Spring MVC allows us to filter the requests by mapping at once (in this case here is the mapping of my project):

@ RequestMapping(value = "/callback/facebook", method = RequestMethod.GET)
    public class FacebookController extends ExternalController implements Constants {
        @ RequestMapping(value = "/registration", params = "code")
        public ModelAndView registrationAccessCode(@ RequestParam("code") String code, HttpServletRequest request) throws Exception {
            String authRequest = Utils.sendHttpRequest("GET", FACEBOOK_URL_ACCESS_TOKEN, new String[]{"client_id", "redirect_uri", "client_secret", "code"}, new String[]{FACEBOOK_API_KEY, FACEBOOK_URL_CALLBACK_REGISTRATION, FACEBOOK_API_SECRET, code});
            String token = Utils.parseURLQuery(authRequest).get("access_token");
    String tokenRequest = Utils.sendHttpRequest("GET", FACEBOOK_URL_ME, new String[]{"access_token"}, new String[]{token})
            Map<String, Json> userInfoResponse = Json.read(tokenRequest).asJsonMap();
            String email = userInfoResponse.get("email").asString().toLowerCase();
            String id = userInfoResponse.get("id").asString();
            //verifying ... is new? is email in DB?
            //creating objects
            Customer customer = new Customer();
            customer.setEmail(email);
            //...
            customerer = (Customerer) userDAO.put(customer);
            FacebookAuthUser user = new FacebookAuthUser();
            user.setFirstName(firstName);
            //...
            user.setIdentificationName(id);
            user.setToken(token);
            user.setType(AuthenticationType.FACEBOOK);
            user.setEnabled(true);
            user.setAuthority(EnumSet.of(Authority.CUSTOMER));
            user.setUser(customer);
            authenticationDAO.put(user);
            return new ModelAndView(new RedirectView("/registrate.complete", true, true, false));
        }
 
        @ RequestMapping(value = "/registration", params = "error_reason")
        public ModelAndView registrationError(@ RequestParam("error_description") String errorDescription, HttpServletRequest request, HttpServletResponse response) {
            //return client to registration page with errorDescription
            return new ModelAndView(new RedirectView("/registrate", true, true, false));
        }
        //will signin and signinError
    }

For convenience and the unitary using, here is a couple of static methods of the Utils class used in this listing:

public static String sendHttpRequest(String methodName, String url, String[] names, String[] values) throws HttpException, IOException {
        if (names.length != values.length) return null;
        if (!methodName.equalsIgnoreCase("GET") && !methodName.equalsIgnoreCase("POST")) return null;
        HttpMethod method;
        if (methodName.equalsIgnoreCase("GET")) {
            String[] parameters = new String[names.length];
            for (int i = 0; i < names.length; i++)
                parameters[i] = names[i] + "=" + values[i];
            method = new GetMethod(url + "?" + StringUtils.join(parameters, "&"));
        } else {
            method = new PostMethod(url);
            for (int i = 0; i < names.length; i++)
                ((PostMethod) method).addParameter(names[i], values[i]);
            method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        }
        new HttpClient().executeMethod(method);
        return getStringFromStream(method.getResponseBodyAsStream());
    }
    public static Map<String, String> parseURLQuery(String query) {
        Map<String, String> result = new HashMap<String,String>();
        String params[] = query.split("&");
        for (String param : params) {
            String temp[] = param.split("=");
            try {
                result.put(temp[0], URLDecoder.decode(temp[1], "UTF-8"));
            } catch (UnsupportedEncodingException exception) {
                exception.printStackTrace();
            }
        }
        return result;
    }

Constants:

final public static String FACEBOOK_API_KEY = "XXXXXXXXXXXXXXXX";
    final public static String FACEBOOK_API_SECRET = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    final public static String FACEBOOK_URL = "https://www.facebook.com/dialog/oauth";
    final public static String FACEBOOK_URL_ACCESS_TOKEN = "https://graph.facebook.com/oauth/access_token";
    final public static String FACEBOOK_URL_ME = "https://graph.facebook.com/me";
    final public static String FACEBOOK_URL_CALLBACK_REGISTRATION = SITE_ADDRESS + "/callback/facebook/registration";
    final public static String FACEBOOK_URL_CALLBACK_SIGNIN = SITE_ADDRESS + "/callback/facebook/signin";

Everyone can use JSON libraries up to its own discretion, I used the mjson library (http://sharegov.blogspot.com/2011/06/json-library.html) – small, convenient and without serialization.

As you can see, the process is simple and should not cause any special problems. I’d like to note that Facebook provides the location parameter and its value can be “pulled” to Google Maps API (by following http://maps.googleapis.com/maps/api/geocode/json) and to get geolocation in the convenient form (due to the standards of Google Maps). It’s clear it can be only in case the customer specified not only the location country in his account in Facebook.

The registration in Google+ is performed the same way, with the only difference that the callback URL in their system should be fully identical to that specified in the application settings. Thus, all the redirects will get only only to one mapping. It’s convenient to use the returned state parameter for the separation of processes.

@ RequestMapping(value = "/callback/google", method = RequestMethod.GET)
    public class GoogleController extends ExternalController implements Constants {
        @ RequestMapping(value = {"/", ""}, params = "code")
        public ModelAndView googleProxy(@ RequestParam("code") String code, @ RequestParam("state") String state, HttpServletRequest request, HttpServletResponse response) throws Exception { ... }
 
        @ RequestMapping(value = {"/", ""}, params = "error")
        public ModelAndView googleErrorProxy(<hh user=RequestParam>("error") String error, <hh user=RequestParam>("state") String state, HttpServletRequest request) throws Exception { ... }
    }

The other actions, except of the addresses and the returned parameters are identical.

Otherwise the thing is going with the authorization over the OAuth protocol (Twitter and LinkedIn). I’ve gone through the whole chain of authentication but it’s very uncomfortable because of the forming of request with tokens – they should be “glued” packed by base64 in a special way, to add the timing parameters and to make other manipulations. And what’s the most surprising – the sections for social network developers do not reflect these processes. Though this is a standard, so the count is performed due to the standard approach. In any case authorization in this way is implemented “manually” and it is not of the interest for the development of your own application. I suggest to use other free libraries that facilitate this task. For example, there exists a library specifically for Twitter – twitter4j.jar. I used the scribe-java library (http://github.com/fernandezpablo85/scribe-java) which is distributed on the terms of MIT license. The package contains work with Digg API, Facebook API, Flickr API, Freelancer API, Google API, LinkedIn API, Skyrock API, Tumblr API, Twitter API, Vkontakte API, Yahoo API and two dozens of some others.

The registration process for Twitter with the usage of the scribe library will look in the following way. The client request controller for authorization from the registration page:

@ RequestMapping(value = "/registrate/twitter", params = "action", method = RequestMethod.POST)
    public ModelAndView twitterRegistrationJobseeker(HttpServletRequest request) throws Exception {
        OAuthService service = new ServiceBuilder().provider(TwitterApi.class)
            .apiKey(TWITTER_CONSUMER_KEY).apiSecret(TWITTER_CONSUMER_SECRET)
            .callback(TWITTER_URL_CALLBACK_REGISTRATION).build();
        Token requestToken = service.getRequestToken();
        request.getSession().setAttribute("twitter", service);
        request.getSession().setAttribute("request_token", requestToken);
        return new ModelAndView(new RedirectView(service.getAuthorizationUrl(requestToken), true, true, true));
    }

Twitter callback controller:

@ RequestMapping(value = "/callback/twitter", method = RequestMethod.GET)
    public class TwitterController extends ExternalController implements Constants {
        @ RequestMapping(value = "/registration", params = "oauth_verifier")
        public ModelAndView registrationAccessCode(@ RequestParam("oauth_verifier") String verifier, HttpServletRequest request, HttpServletResponse response) throws Exception {
            OAuthService service = (OAuthService) request.getSession().getAttribute("twitter");
            Token accessToken = service.getAccessToken((Token) request.getSession().getAttribute("request_token"), new Verifier(verifier));
            OAuthRequest oauthRequest = new OAuthRequest(Verb.GET, TWITTER_URL_CREDENTIALS);
            service.signRequest(accessToken, oauthRequest);
            Map<String, Json> userInfoResponse = Json.read(oauthRequest.send().getBody()).asJsonMap();
            String twitterId = userInfoResponse.get("id").asString();
            //verifying ...
            Customer customer = new Customer();
            customer.setFirstName((String) request.getSession().getAttribute("pageValueFirstName"));
            //...
            customer = (Customer) userDAO.put(customer);
            TwitterAuthUser user = new TwitterAuthUser();
            user.setAuthority(EnumSet.of(Authority.CUSTOMER));
            user.setIdentificationName(twitterId);
            //...
            user.setOauthToken(accessToken.getToken());
            user.setOauthTokenSecret(accessToken.getSecret());
            user.setType(AuthenticationType.TWITTER);
            user.setUser(customer);
            authenticationDAO.put(user);
            return new ModelAndView(new RedirectView("/registrate.complete", true, true, false));
        }
 
        @ RequestMapping(value = "/registration", params = "denied")
        public ModelAndView registrationError(HttpServletRequest request) {
            //response does not contain the error text
            return new ModelAndView(new RedirectView("/registrate", true, true, false));
        }
        //will signin and signinError
    }

Once again, all is easy and affordable. Registration via LinkedinAPI is performed in a quite the same way.

And the last – registration in a standard way. Standard – hence it’s standard, I won’t show the source code, will only note that we create an object of the SimpleAuthUser type inherited from AuthUser:

    SimpleAuthUser user = new SimpleAuthUser();
        user.setAuthority(EnumSet.of(Authority.NEW_CUSTOMER));
        user.setEnabled(false);
        user.setIdentificationName(email);
        user.setPassword(passwordEncoder.encodePassword(password, email));
        user.setType(AuthenticationType.SIMPLE);
        user.setUser(customer);
        user.setUuid(uuid);
        authenticationDAO.put(user);

For this case the NEW_CUSTOMER authority needed – registered user needs confirmation of registration (standard practice), and that’s why a) it has a different role; b) it’s not allowed for authorization in Spring Security (enabled = false).

Authorization on the website

A simple spring application-context-security.xml:

<security:global-method-security secured-annotations="enabled" jsr250-annotations="enabled" pre-post-annotations="enabled" proxy-target-class="true"/>
 
    <security:http auto-config="true" use-expressions="true">
        <security:intercept-url pattern="/**" access="permitAll"/>
        <security:form-login login-page="/signin"/>
        <security:logout invalidate-session="true" logout-success-url="/" logout-url="/signout"/>
        <security:remember-me services-ref="rememberMeService" key="someRememberMeKey"/>
    </security:http>
 
    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider ref="authenticationProvider"/>
    </security:authentication-manager>
 
    <bean id="authenticationProvider" class="myproject.security.CustomAuthenticationProvider"/>
 
    <bean id="rememberMeService" class="myproject.security.RememberMeService">
<property name="key" value="someRememberMeKey"/>
<property name="userDetailsService" ref="userDetailsService"/>
    </bean>
 
    <bean id="userDetailsService" class="myproject.security.CustomUserDetailsManager"/>
    <bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder"/>

CustomUserDetailsManager.java:

public class CustomUserDetailsManager implements UserDetailsService {
        @ Resource private AuthenticationDAO authenticationDAO;
 
        @ Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            return authenticationDAO.findAuthUser(username);
        }
    }

CustomUserAuthentication.java:

public class CustomUserAuthentication implements Authentication {
        private String name;
        private Object details;
        private UserDetails user;
        private boolean authenticated;
        private Collection<? extends GrantedAuthority> authorities;
 
        public CustomUserAuthentication(UserDetails user, Object details) {
            this.name = user.getUsername();
            this.details = details;
            this.user = user;
            this.authorities = user.getAuthorities();
            authenticated = true;
        }
 
        @ Override
        public String getName() {
            return name;
        }
        @ Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return authorities;
        }
        @ Override
        public Object getCredentials() {
            return user.getPassword();
        }
        @ Override
        public Object getDetails() {
            return details;
        }
        @ Override
        public Object getPrincipal() {
            return user;
        }
        @ Override
        public boolean isAuthenticated() {
            return authenticated;
        }
        @ Override
        public void setAuthenticated(boolean authenticated) throws IllegalArgumentException {
            this.authenticated = authenticated;
        }
    }

CustomAuthenticationProvider.java

(the class is completely clueless, but the interface inheritant AuthenticationProvider should be fed to Spring Security, but the nearest PreAuthenticatedAuthenticationProvider doesn’t fit in meanning):

public class CustomAuthenticationProvider implements AuthenticationProvider {
        @ Override
        public Authentication authenticate(Authentication authentication) throws AuthenticationException {
            //тут могут быть доп. проверки
            return authentication;
        }
 
        @ Override
        public boolean supports(Class<?> authentication) {
            return PreAuthenticatedAuthenticationToken.class.isAssignableFrom(authentication);
        }
 
        public Authentication trust(UserDetails user) {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            Authentication trustedAuthentication = new CustomUserAuthentication(user, authentication.getDetails());
            authentication = authenticate(trustedAuthentication);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            return authentication;
        }
    }

And perhaps the most “narrow” place of security organization is the implementation of the RememberMe mechanism. Basically, everything is already organized so that the work of the RememberMe service fully corresponds to the TokenBasedRememberMeServices implementation, with the only clarification: all the data for automatic client authentication are located in our database, however there can be a situation when the user has already registered on the website and then removed his account on the used social network. And the result is conflict – we authorize the user but in fact he doesn’t exist, i.e. the basic authentication principles by using the third-party services are disrupted. Hence, when the RememberMe mechanism works out we should check the automatically logging client. Such mechanisms are present in every API network provider but we should “intrude” in the work of Spring RememberMe in order to perform the test at the right stage. Unfortunately, it’s not possible to expand some class (the required method is set as final in AbstractRememberMeServices), that’s why you need to completely redefine the class. My way is more cumbersome, I went from the end, abd the trivial human laziness doesn’t permit us to remodel it into the simplier version. I completely redefined the AbstractRememberMeServices class including the TokenBasedRememberMeServices class code, and by adding a couple of strings into the public Authentication autoLogin(HttpServletRequest request, HttpServletResponse response) method – after checking the values in the method but before the actual authentication I’ve put a check method call of the client “reality existance”.

Class<? extends ExternalController> controller = externalControllers.get(user.getPassword()); 
    if (controller != null && !controller.newInstance().checkAccount(user)) return null;

And before, I define the static list in the constructor:

private Map<String, Class<? extends ExternalController>> externalControllers;
 
    public CustomRememberMeService() {
        externalControllers = new HashMap<String, Class<? extends ExternalController>>(){{
            put(AuthenticationType.FACEBOOK.name(), FacebookController.class);
            put(AuthenticationType.TWITTER.name(), TwitterController.class);
            put(AuthenticationType.GOOGLE.name(), GoogleController.class);
            put(AuthenticationType.LINKEDIN.name(), LinkedinController.class);
        }};
    }

(this code implementation won’t affect the operation of RememberMe for standard authentication).

And a little easier method implies the replacement of the REMEMBER_ME_FILTER filter to its own where you should put the same code after the mentioned above autoLogin method call, but before the direct authentication. It is less expensive and to code and more logical to understand, however, it requires the intervention of the configuration file. Which way to go – everyone will decide himself, but the second one, in my opinion, is more ideologically “clear”.

Also you should clarify about ExternalController and checkAccount(user) call. All my callback-controllers extend the ExternalController class:

And each controller redefines this only method. For example, in regards to Facebook it’s:

public boolean ?heckAccount(UserDetails user) throws Exception {
        FacebookAuthUser facebookUser = (FacebookAuthUser) user;
        String authRequest = Utils.sendHttpRequest("GET", FACEBOOK_URL_ME, new String[]{"access_token"}, new String[]{facebookUser.getToken()});
        Map<String, Json> tokenInfoResponse = Json.read(authRequest).asJsonMap();
        return tokenInfoResponse.get("error") == null && tokenInfoResponse.get("id").asString().equalsIgnoreCase(facebookUser.getIdentificationName());
    }

and for Twitter:

public boolean checkAccount(UserDetails user) throws Exception {
        TwitterAuthUser twitterUser = (TwitterAuthUser) user;
        OAuthService service = new ServiceBuilder().provider(TwitterApi.class).apiKey(TWITTER_CONSUMER_KEY).apiSecret(TWITTER_CONSUMER_SECRET).build();
        OAuthRequest oauthRequest = new OAuthRequest(Verb.GET, TWITTER_URL_CREDENTIALS);
        service.signRequest(new Token(twitterUser.getOauthToken(), twitterUser.getOauthTokenSecret()), oauthRequest);
        String response = oauthRequest.send().getBody();
        Map<String, Json> info = Json.read(request).asJsonMap();
        return info.get("id").asString().equalsIgnoreCase(twitterUser.getIdentificationName());
    }

and so on.

And the authentication itself (login, sign in) is very similar to the registration. The user visits the page, clicks “Login” and he is being redirected to authentication:

The only thing is that I transfer the “signin” or “autosignin” parameter to the server, depending on the case if the “enter automatically” option is checked. Then all is happenning in a similar scenario with the registration, only the parameter and callback URL are changing and I put away all scope and permission – we need to get only the client ID and hist tokens. After the appropriate checks in the controller methods I suggest you to overwrite tokens into the database. And though, for example, Facebook didn’t change the client token during my tests, and Google+ does this every time. I don’t know how often the “change” happens, that’s why the overwrite is performed after eacb access_token receiving (in fact while each non-automatic authentication of the provider).

And the most important thing – the direct user authentication in Spring Security (definitely after all the checks for the correspondance and verification of rights from API provider), on the example of the Facebook controller:

@ RequestMapping(value = "/signin", params = "code")
    public ModelAndView signInAccessCode(@ RequestParam("code") String code, @ RequestParam("state") String state, HttpServletRequest request, HttpServletResponse response) throws Exception {
        String accessRequest = Utils.sendHttpRequest("GET", FACEBOOK_URL_ACCESS_TOKEN, new String[]{"client_id", "redirect_uri", "client_secret", "code"}, new String[]{FACEBOOK_API_KEY, FACEBOOK_URL_CALLBACK_SIGNIN, FACEBOOK_API_SECRET, code});
        String token = Utils.parseURLQuery(accessRequest).get("access_token");
        Map<String, Json> userInfoResponse = Json.read(Utils.sendHttpRequest("GET", FACEBOOK_URL_ME, new String[]{"access_token"}, new String[]{token})).asJsonMap();
        FacebookAuthUser user = (FacebookAuthUser) authenticationDAO.findAuthUser(userInfoResponse.get("id").asString(), AuthenticationType.FACEBOOK);
        if (user == null) {
            //something went wrong ...
            return new ModelAndView(new RedirectView("/signin", true, true, false));
        } else {
            if (!token.equals(user.getToken())) {
                user.setToken(token);
                user = (FacebookAuthUser) authenticationDAO.put(user);
            }
            Authentication authentication = customAuthenticationProvider.trust(user);
            if (state.equalsIgnoreCase("autosignin")) customRememberMeService.onLoginSuccess(request, response, authentication);
            else customRememberMeService.logout(request, response, authentication); //???????? ???? RememberMe
            return new ModelAndView(new RedirectView("/signin.complete", true, true, false));
        }
    }

Now the client will be automatically logged in when the flag is checked for auto logging in. Hence, if there’s no flag, the logout method call will erase cookies in the RememberMe service (it doesn’t do anything else). By the way, going over the “/logout” link takes the authentication off and cleans cookies automatically. This is overseen by the corresponding line in the Spring Security config above.

Using of the given method can be “atthached” for the standard authentication as well: after going through the checks (finding user in the table, matching password hash and so on) we manually authenticate him:

Authentication authentication = customAuthenticationProvider.trust(user);
    if (autosignin) customRememberMeService.onLoginSuccess(request, response, authentication);
    else customRememberMeService.logout(request, response, authentication);

There’s no difference in usage. The only thing is that while the RememberMe mechanism works out, there’ll be no external checks, in fact, it fully coincides with the work of the TokenBasedRememberMeServices service.

Then using of authentication is similar to using of general roles in Spring Security, with the only difference that you cannot use the @Secured(«CUSTOM_ROLE») annotation, it’s intended for the standard roles (though there’s a mechansim for redefining). But Spring Security has another mechanism – using of the same annotations as @PreAuthorize, @PostFilter: @PreAuthorize(«hasRole(‘ADMINISTRATOR’)»), @PreAuthorize(«hasRole({‘CUSTOMER’, ‘ADMINISTRATOR’})»). You should only specify it in the Spring Security config in the security:global-method-security parameter.

In same way you can use the benefits and opportunities of Spring Security in the view (in JSP). For example:

<%@ taglib prefix="core" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
    ...
    <sec:authorize access="isAuthenticated()">
        <div id="userBox">
            <span>Welcome, <sec:authentication property="principal.user.firstName"/>!</span>
        </div>
    </sec:authorize>

Such constructions allow not to transfer a model from the controller into the view, but to leave the model extract mechanism for the view (it will request for the model to DAO by itself).

Also you can use the jsp-scriplets on jsp-pages (though there’re getting lots of rivals in scriplets using, basically out of the “bean’s – to bean, caesar’s – to caesar” position, developer is programming, coder and/or designer is working on designing, but this is a moot thing, personally me is not the supporter of either one or the other concept – yes, ugly, yes, sometimes very convenient):

<%@ page import="org.springframework.security.core.context.SecurityContextHolder" %>
    <%@ page import="myproject.auth.AuthUser" %>
    <%	Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        AuthUser authUser = null;
        if (!(principal instanceof String)) authUser = (AuthUser) principal; %>
    ...
    <input type="text" <%= authUser == null ? "" : "disabled=\"disabled\"" %> name="your_name" value="<%= authUser == null ? "" : authUser.getUser().getFirstName()%>"/>
    ...
    <% if (authUser == null) { %>
        <div id="recaptcha_widget">
            <div id="recaptchaContainer">
    ...
            </div>
        </div>
    <% } %>

The above code only reflects the opportunities of the security context usage, but it doesn’t pretend for any meaningful logics.

I want to focus on the “narrow” place caused by the lazy dependency between the authentication object and its parameters (object-Principal): without improvements both bunches of code will call Runtime Exception while opening as the user field (calling of the getUser() method) will contain an object with all the fields by default, filled out as null. Using of the OpenSessionInView pattern without the additional extra-loading of the dependent object will not help in this case as there are different HTTP sessions. Therefore it is necessary either to load the dependent object once at boot o, but it is contrary to the approach because of which the lazy connection has been assigned – the object will be loaded and no change in dependent object will update the downloaded one, in this case it is easier to set the EAGER-connection. I’ve resolved this in authenticationDAO by replacing the basically used sessionFactory.getCurrentSession() for opening a new session: SessionFactoryUtils.openSession(sessionFactory). Perhaps this is not the most economical solution in terms of memory but I haven’t questioned myself yet and didn’t dived in depth for the current problem. I consider that by setting the check for validation of the current session you can refuse from the filter and the OpenSessionInView interceptor, in fact by replacing its work.

There’s a bit more text than you need, there are probably exist questionable or even wrong moments but I have tried to reflect the decision of the difficulties encountered during the implementation of the put-up mechanism.

30
Sep

The example of using of Hibernate as JPA Provider in conjunction with the Spring Framework

Posted by eugene as Hibernate, Spring Framework

It’s no secret that Hibernate is the “de facto” standard in the ORM-world. At the same time the production “de jure” standard is JPA – it’s also difficult to argue. Moreover, starting with the 3.6.* version Hibernate fully supports JPA standard (of different versions) and it means that there is a possibility to develop on the basis of production standard, not refussing from the favourite instrument. Nevertheless there are few compact and light examples for understanding in the network which illustrate this possibility, especially when it’s about the conjunction with Spring Framework. The article will be devoted exactly to it (to conjunction of Spring + Hibernate as JPA).

Introduction

As I’ve written above there are not so many examples, most often these will be the examples of work of Spring + Hibernate, or Spring + JPA, or Hibernate as JPA provider, etc.

The most simple and available description of using Hibernate JPA you’ll find right in distributive {HIBERNATE_HOME}/documentation/quickstart/en-US/html/hibernate-gsg-tutorial-jpa.html (the exact example is located here:{HIBERNATE_HOME}/project/documentation/src/main/docbook/quickstart/tutorials/entitymanager/). Since in my article it’s taken as a basis and it’s extremely desirable by the time you need these lines to read you have already acknowledged this example.

[FYI:]SpringSource has a separate project which supplements the opportunities of the basic Spring ORM and focused on the support of JPA – Spring Data JPA: http://static.springsource.org/spring-data/data-jpa/docs/1.1.0.RC1/reference/html/

We’ll concentrate on the conjunction variant of Spring Framework + JPA where Hibernate is represented in the role of JPA realization. Consequently we’ll need the last (at the moment of writing the article) versions of Spring Framework 3.1 and Hibernate 4.0.1.

Background

Download the source code examples (http://it.vaclav.kiev.ua/wp-content/uploads/2012/02/spring-jpa-hib-example.zip), deploy the archive and import the project into Eclipse (or any other IDE up to you). Then open the {spring-jpa-hib-example}/lib/readme.liblist.txt file and having learnt the list of necessary libraries, add them into {spring-jpa-hib-example}/lib/. Except of the several libraries you’ll find them in the Spring and Hibernate libraries respectively.

The additional libraries which you’ll need for work with the example:

For the ease of demonstration we’ll use a slight “in-memory” database variant, namely HSQLDB. Please note that while guys from JBoss like H2, their colleagues from SpringSource prefer HSQLDB for the same purposes. In general, these databases are interchangeable in most cases but we’ll focus on HSQLDB as it’s much easier to configure in the context of Spring Framework.

So, all infrastructure issues are acknowledged – the sources are present, all the libraries are loaded and available for using, you can get started studying the example.

Studying the spring-jpa-hib-example project

As I’ve already written above, the example which is as the basis of it is supplied with Hibernate 4.0.1 in which the org.hibernate.tutorial.em.Event class is used as @Entity. I hope that you’ve already acknowledged with it. Otherwise – it’s time ot do it now! Moreover, we’ll not stop on it for details – this is POLO annotated accordingly.

Let’s review the modified by me persistence.xml:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">
 
    <persistence-unit name="org.hibernate.tutorial.jpa">
        <description>
            Persistence unit for the Spring JPA tutorial with Hibernate using as JPA provider
        </description>
 
        <!-- <class>org.hibernate.tutorial.em.Event</class> -->
 
        <properties>
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="create" />
        </properties>
 
    </persistence-unit>
 
</persistence>

As you can see this is the standard persistence.xml according to JPA v.2.0 in which there’s practically nothing except some lines which parameterize Hibernate. Even org.hibernate.tutorial.em.Event is commented out. Why this is done you’ll understand below. Special interest in this file you’ll find in persistence-unit – recall it as you’ll need it further in order to configure one of the Spring beans. Let’s review it:

application-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd">
 
    <context:annotation-config />
 
    <context:component-scan base-package="org.hibernate.tutorial.em" />
 
    <jdbc:embedded-database id="dataSource">
    </jdbc:embedded-database>
 
    <bean id="lcemf"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="loadTimeWeaver">
            <bean
                class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
        </property>
        <property name="dataSource" ref="dataSource"></property>
        <property name="persistenceUnitName" value="org.hibernate.tutorial.jpa" />
        <property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>
    </bean>
 
    <bean id="eventDao" class="foo.bar.dao.EventDaoImpl" />
</beans>

Let’s review it in parts putting down trivial things:

<context:component-scan base-package="org.hibernate.tutorial.em" />

This configuration fragment will allow Spring, in conjunction with Hibernate, to find the @Entity class itself. If you remember we’ve commented its declaration from persistence.xml.

<jdbc:embedded-database id="dataSource">
</jdbc:embedded-database>

And you’ve probably haven’t coped with this block despite the fact it appeared quite long time ago in Spring, the special attention it got in the last framework versions. This tag will allow you to automatically initialize the so-called “embedded database” where HSQLDB / H2 / DERBY can be used as that. Most of all HSQLDB is preferred in SpringSource but you can quickly enough go to any of it (how to do it? see chapter 13.8 Embedded database support, Spring Reference v.3.1). I’ll only add that this solution is not only used in production! It is designated for enlightment of prototypes creation and testing which we’ll use. After completion the “context rise” you’ll get not only ready “dataSource” beanbut the raised database in memory, fully ready for work.

<bean id="lcemf"
    class="org.springframework.orm.jpa.с">
    ...
    <property name="dataSource" ref="dataSource"></property>
    <property name="persistenceUnitName" value="org.hibernate.tutorial.jpa" />
    <property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence"/>
</bean>

And in this configuration block the magic of work with Hibernate is hidden as with the JPA provider in Spring. Not long time ago Spring represented set of XXXTemplate classes for simplifying work with different ORM, but starting from v.3.0 this practice has stopped the JpaTemplate class is already deprecated. Instead of it, there’re used several variants of EntityManagerFactoryBeans in the third string. We’ll use the most powerful of them, i.e. LocalContainerEntityManagerFactoryBean. As you can see from the context we transmit dataSource into it, persistenceUnitName and the class which implements the PersistenceProvider interface, in the case with the fourth Hibernate this is HibernatePersistence (Why haven’t guys from JBoss called it HibernatePersistenceProvider is still the puzzle for me, obviously they get some extra satisfaction to puzzle their users).

In the same time, in the Spring context we’re raising implementation of our dao: foo.bar.dao.EventDao, we’ll continue work with it literally in several seconds:

public interface EventDao {
 
    public abstract Collection<Event> loadEvents();
 
    public abstract void persistEvent(Event event);
 
}

Please find the implementation of this interface in the foo.bar.dao package. A little secret is also hidden in it which is not quite enough transparently represented in the Spring documentation.

private EntityManagerFactory emf;
 
@PersistenceUnit
public void setEntityManagerFactory(EntityManagerFactory emf) {
    this.emf = emf;
}

If you followed the train of thought attentively then you should have found that the EntityManagerFactory bean type in context hasn’t raised and in fact it couldn’t simply appear. Nevertheless we’ve created the LocalContainerEntityManagerFactoryBean instance and its conjunction with the @PersistenceUnit annotation allows Spring to get EntityManagerFactory and to implement its injection into our DAO.

All the further work with Hibernate from the Spring Framework environment is now done transparently, as with the JPA realization:

In order to make sure in the example efficiency, find the {spring-jpa-hib-example/test} / foo.bar.dao.EventDaoImplTest class and run it as a JUnit-test (required to use JUnit v.4.*).

@Test
public void testBasicUsage() {
 
    EventDao eventDao = this.context.getBean(EventDaoImpl.class);
    Collection<Event> events = eventDao.loadEvents();
    log.info("Events count: " + events.size());
    log.info(events);
 
    // checking that there are no any events in fresh db schema
    assertEquals(eventCnt, events.size());
 
    // create and persist new event
    eventDao.persistEvent(new Event( "Our very first event!", new Date() ));
    eventCnt++;
 
    events = eventDao.loadEvents();
    log.info("Events count: " + events.size());
    log.info(events);
 
    // checking that there is only one event that has been created recently
    assertEquals(eventCnt, events.size());
}

If the test completed successfully, then it means you’ve got raised Hibernate as the JPA provider in context of Spring.

In the following editions I’ll get you acquainted with not less interesting Spring Framework opportunities.

17
Jul

A bit of magics from AspectJ

Posted by eugene as Spring Framework

Probably you’ve already coped with such a concept as AOP – aspect-oriented programming.

Usually they recall it when say about the use of declarative transactions, about verifying of access rights or about the realization of logging.

But these are not the only areas of AOP use.

I want to show yet couple of areas of using from the real projects:

  • Modification of the source code for realization of the additional opportunities.
  • Compulsory check of the contract between the modules.

Modification of the source code for realization of the additional opportunities

Let’s suppose that you have a module in the application which represents the necessary functionality. Everything is alright with the module except the one – all its methods can throw the verifying exceptions that leads to deterioration of the code readability as instead of the simple method calling:

service.doUsefulThing();

our call turns into

try {
        service.doUsefulThing();
    } catch ( FirstServiceException e) {
        processException(e);
    } catch ( SecondServiceException e) {
        processException(e);
    }

An additional problem is that the amount of 10+ modules in the module is as huge that it leads to the case that the try/catch blocks throw the code. The resolvoing with using of the Callback pattern also will lead to the code throwing.

Resolving the problem with the using of AOP

Resolving of this problem was the following – what if using the opportunities of AOP you’ll transform the verifying exception into non-verifying? So, we could avoid of the boring verification on the exceptions in our code, and for processing the exceptions (as we’ll always process it simulteneously) it’ll be enough to use processing of the exception on the upper level of abstraction.

For more elegant resolvation it’s decided to add our own annotation with the help of which it’s necessary to mark the method which uses the service from the ‘bad’ module.

package com.blogger.atamanenko;
 
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.RetentionPolicy;
 
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
@Inherited
public @interface SuppressExceptions {
}

And also the aspect which would have done all the necessary functionality for us:

public aspect ExceptionSupressingAspect {
 
        declare soft :ServiceException:  execution(@com.blogger.atamanenko.annotation.SuppressExceptions * *.*(..));
 
}

This aspect gives exactly the following: ‘Mitigates’ the ServiceExceptionexception exception for the method which is marked by the @SuppressExceptions annotation.

The example of using:

@SuppressExceptions
    protected Entity findEntity(final Identifiable id) {
        return entityService.findById(id);
    }

Compulsory check of the contract between the modules

Often we should forcibly require the implementation of some architectural restrictions, for example, the controllers should work only with the services and it’s restricted for them to directly request to the database.

For implementation of such verifications you can also use the opportunities of AOP.

Let’s suppose that the service module in our application pulls DTO outside for work, hiding the classes of the model by the time. In order to obviously ban the access to the classes and methods of the model we should create an aspect which would have call the compilation error while breaching the restriction.

aspect ForbidAccessToModelAspect {
 
//      Full prohibition of access to model:
        pointcut accessModel(): call(* com.blogger.atamanenko.app.model..*.*(..));
        declare error: accessModel() : "Illegal call to model";
 
}

After declaring such an aspect we’ll get the compilation error that would obviously lead to implementation of the architectural restriction.

If you need to allow access to the package from the other one, then we can modify our aspect by the following way:

aspect ForbidAccessToModelAspect2 {
 
        pointcut accessModel(): call(* com.blogger.atamanenko.app.model.**.*(..));
 
        // Allow access to model from specific package for methods and constructors
        pointcut allowAccessModelFromSpecificPackage(): withincode(* com.blogger.atamanenko.app.allowedpackage..*.*(..));
        pointcut allowAccessModelFromSpecificPackage2(): withincode(com.blogger.atamanenko.app.allowedpackage..*.new(..));
 
        // forbid usage from any other methods.
        declare error: accessModel() &amp;&amp; !(allowAccessModelFromSpecificPackage() || allowAccessModelFromSpecificPackage()):"Illegal call to Model from forbidden package";
 
}

Such aspect which is created in our module will restrict us to use the classes of the model from all the packages except of com.blogger.atamanenko.app.allowedpackage.

Application assembly

Aspect file should be put into the src/main/aspect floder and for application assembly it’s necessary to use AspectJ compiler and not the standard Oracle Java Compiler.

The example of the configuration for Apache Maven:

    org.codehaus.mojo
    aspectj-maven-plugin
    ${aspectj-maven-plugin.version}
 
        1.6
 
 
                org.springframework
                spring-aspects
 
 
        true
 
 
 
process-sources
 
                compile
                test-compile

Conclusion

That is all. I deliberately did not start describing the aspects of the language constructs as they are described in the Aspect guide in details.

17
Jul

Using of BeanPostProcessor on the example of logging

Posted by eugene as Spring Framework

Today I want to tell you how to make the initialization of the logger in the class with the using of annotations and BeanPostProcessor. Very often we initialize the logger as follows:

public class MyClass {
    private static final Logger LOG = LoggerFactory.getLogger(MyClass.class);
}

I’ll show how to make so that you’ll be able to do the following:

@Log
private Logger LOG;

First of all you should declare the annotation:

@Retention(RUNTIME)
@Target(FIELD)
@Documented
public @interface Log {
    String category() default "";
}

Secondly you should write your own BeanPostProcessor which would have set the logger for us:

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
 
@Component
public class LoggerPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
 
    @Override
    public Object postProcessBeforeInitialization(final Object bean, final String beanName) {
        ReflectionUtils.doWithFields(bean.getClass(), new FieldProcessor(bean, beanName), new LoggerFieldFilter());
        return bean;
    }
 
    private static class FieldProcessor implements ReflectionUtils.FieldCallback {
        private final Object bean;
        private final String beanName;
 
        private FieldProcessor(Object bean, String beanName) {
            this.bean = bean;
            this.beanName = beanName;
        }
 
        @Override
        public void doWith(Field field) throws IllegalAccessException {
            Log loggerAnnot = field.getAnnotation(Log.class);
 
            // Sanity check if annotation is on the field with correct type.
            if (field.getType().equals(org.slf4j.Logger.class)) {
                // As user can override logger category - check if it was done.
                String loggerCategory = loggerAnnot.category();
                if (StringUtils.isBlank(loggerCategory)) {
                    // use default category instead.
                    loggerCategory = bean.getClass().getName();
                }
                Logger logger = LoggerFactory.getLogger(loggerCategory);
                ReflectionUtils.makeAccessible(field);
                field.set(bean, logger);
            } else {
                throw new IllegalArgumentException(
                    "Unable to set logger on field '" + field.getName() + "' in bean '" + beanName +
                        "': field should have class " + Logger.class.getName());
            }
        }
    }
 
    private static class LoggerFieldFilter implements ReflectionUtils.FieldFilter {
        @Override
        public boolean matches(Field field) {
            Log logger = field.getAnnotation(Log.class);
            return null != logger;
        }
    }
}

If you use log4j or commons-logging, not sfl4j, then you should a bit rectify the code inside the doWith method. On the way this code shows the example of using the org.springframework.util.ReflectionUtils class.

10
Jul

Using of Javassist for generating proxy in Spring Framework

Posted by eugene as Spring Framework

It is well known that the cglib project has had been long in the abandoned state, also when working with it there appear some problems described below. The most popular alternative for this project is javassist. It is used in such projects as JBoss AS, Hibernate, Weld…

But it hasn’t yet appeared in Spring only. The replacement of the cglib library used to generate the proxy objects with the javassist will be implemented in version 3.1 according to the project plan. In the same task I’ve attached three classes and couples of patches which allow to finally change your approach to Javassist.

To enable Javassist you need to attach these three classes to my project – JavassistAopProxy, JavassistAopProxyFactory and JavassistApplicationContext. Then, instead of the spring realization of ApplicationContext use org.springframework.aop.framework.JavassistApplicationContext. If you are not creating it directly and use org.springframework.web.context.ContextLoaderListener configured in web.xml then you will need to add the following lines into the same web.xml:

<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.aop.framework.JavassistApplicationContext</param-value>
</context-param>
17
Jun

The attributes of the servlet request in Spring MVC

Posted by eugene as Spring Framework

In the article about the GET/POST parameters in the Spring MVC servlets there was shown how to access the parameters passed by the POST method. There was also an example of a class to parse the query line. Using of this class is convenient, if it;s not desirable to include the foreign libraries.

I’ll remind that for getting a list of the POST parameters it’s necessary to calculate the query line from the input thread and convert it into the set of parameters. In the simple web-applications where processing of the request is held in one or two handlers / controllers, you can use this method without any tricks. But what if the query in the web-application goes via several handlers, including the interceptor, controller, view, each of which is necessary to gain access to the parameters of POST? Obviously that reading the lines from the input thread and transforming it into the analysis of the parameters will take too much time in this application. How to make so that you can read and convert only one time? Tthe ability to set arbitrary attributes of the request can help in this case (HttpServletRequest).

The setAttribute(String name, Object value) and getAttribute(String name) methods are used for setting and getting the attributes, as well as listings of names of attributes getAttributeNames(). Attribute values will be available during the entire life cycle of the request since the installation of an attribute. The query itself properly follow all the processors. Note that the attribute names are recommended to be set in the same style as the package java names, for example, com.company.project.attribute. In this case the following mask attribute names are reserved – java. *, Javax. * And com.sun. *.

Thus, we can read and convert the query line only once into the parameters set – at the beginning of the life cycle of a query, to set the request attribute and then to use it whenever necessary.

In my point of view, a good way to implement this is to use the so-called interceptors (Interceptor), which can process the request in the early stages, including before entering it into the controller. Creation of an interceptor goes beyond this, you can read about it, for example, here.

Here is the brief example of how you can implement all of the above. QueryString is the class from the previous article.

Interceptor

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		// Read the parameters line from the input thread
		String postQS = "";
		try {
			do {
				String tmp = request.getReader().readLine();
				if (tmp != null && tmp.length() != 0) {
					postQS += tmp;
				} else {
					break;
				}
			} while (true);
		} catch (IOException e) {
			e.printStackTrace();
		}
		// Transforming the line into set of parameters and set the attribute
		QueryString qs = new QueryString(postQS);
		request.setAttribute("com.my_company.my_project.QueryString", qs);
		return true;
	}

Next, we simply extract this attribute from the request and work with it.

The request processing after interceptor

	// Retrieve the attribute value
	QueryString qs = (QueryString) request.getAttribute("com.my_company.my_project.QueryString");
	// Get the 'some' parameter value
	String someValue = qs.getParameter("some");
17
Jun

How to befriend Hibernate with Spring and to provide the transaction management via @nnotations

Posted by eugene as Hibernate, Spring Framework

How to befriend Hibernate with Spring and to provide the transaction management via @nnotations

The large and complex task completed at work, and you’d like to digress a bit before the resolution of the next one and to share something with you, dear readers. Today’s post will be the series like “ones for the kids.” Let’s talk about a bunch of Spring-Hibernate, the DAO layer and dynamic transaction management.

SpringFramework is quite complicated and interesting thing. In particular, it includes the org.springframework.orm.hibernate3 package, which provides the interaction between SpringFramework and Hibernate ORM.

Let’s create a simple console application (not to bother with defining servlets and other overhead’s), which writes something into the database.

Accordingly, first of all we’ll define the entity with which we work. Let’s call it casually: MyEntity.

The code essentially looks like this:

package com.scriptkiddieblog.example.entity;
 
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.hibernate.annotations.GenericGenerator;
 
@Entity
public class MyEntity implements Serializable {
 
	private static final long serialVersionUID = 382157955767771714L;
 
	@Id
	@Column(name = "uuid")
	@GeneratedValue(generator = "system-uuid")
	@GenericGenerator(name = "system-uuid", strategy = "uuid")
	private String id;
 
	@Column(name = "name")
	private String name;
 
	public MyEntity() {
	}
 
	public MyEntity(String id, String name) {
		this.id = id;
		this.name = name;
	}
 
	public String getId() {
		return id;
	}
 
	public void setId(String id) {
		this.id = id;
	}
 
	public String getName() {
		return name;
	}
 
	public void setName(String name) {
		this.name = name;
	}
}

I’ll remind you that the @Entity, @Id, etc. annotations are related to JPA and replace Hibernate-mapping.

We won’t work with the entity directly but through DAO. Using of DAO is one of the established patterns of work with SpringFramework. Having defined the bean that implements DAO you can easily inject it into the beans that implement the business logic of the application, and thus completely separate the business logic from data manipulation. Our DAO will be implemented via the following interface:

package com.scriptkiddieblog.example.dao;
 
import com.scriptkiddieblog.example.entity.MyEntity;
 
public interface IEntityDao {
 
	public void save(MyEntity entity);
}

For the example, we’ll define a single method – save which will retain the entity into the database. DAO implementation is rather primitive:

package com.scriptkiddieblog.example.dao;
 
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.scriptkiddieblog.example.entity.MyEntity;
 
public class EntityDao extends HibernateDaoSupport implements IEntityDao {
 
	public void save(MyEntity entity) {
		getHibernateTemplate().save(entity);
	}
}

We inherit from the HibernateDaoSupport class which encapsulates the work with the Hibernate Session, and Hibernate Session Factory gives us a simple API to interact with Hibernate. I recommend an article that explains how to properly organize the DAO layer in your application.

Now let’s go to the classes which will implement the business logic. In our case, the business logic will be simple – we’ll just save the entity.

ImyEntityService interface:
 
package com.scriptkiddieblog.example.services;
 
import com.scriptkiddieblog.example.entity.MyEntity;
 
public interface IMyEntityService {
 
	public void saveEntity(MyEntity entity);
}
</pre
Implementation — MyEntityService class:
<pre lang="Java">
package com.scriptkiddieblog.example.services;
 
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.scriptkiddieblog.example.dao.IEntityDao;
import com.scriptkiddieblog.example.entity.MyEntity;
 
@Transactional(readOnly = true)
public class MyEntityService implements IMyEntityService {
 
	private IEntityDao dao;
 
	public void setDao(IEntityDao dao) {
		this.dao = dao;
	}
 
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
	public void saveEntity(MyEntity entity) {
		dao.save(entity);
	}
}

This class is the most interesting thing in our program. We need to wrap the saveEntity method in the transaction. There is the @Transactional annotation for this purpose to which you can annotate a method or a class. The behavior of the transaction is set by the parameters of this annotation. The main parameter is readOnly which points to the possibility or impossibility of modifying the state of the database and propagation which sets the strategy for the transaction (not to create a transaction, create new, join to the existing one, etc.). In addition to these parameters you can specify a timeout, the isolation level, classes and types of exceptions where it’s both required and not to do rollback.

More information about the parameters and their values can be found in the official guide for SpringFramework.

Actually, now we have to consider the configuration of Spring-context which will be stored in the applicationContext.xml file. The file will be considered in parts, in small portions. First of all, let’s create the “fish” of the file:

<?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:aop="http://www.springframework.org/schema/aop" 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.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
 
</beans>

Pay attention! It is important to register all namespaces and the path to the schemes correctly, otherwise the configuration will simply not be parsed.

So first, let’s add the necessary configuration files into the context, in this case – jdbc.properties where we will store the settings for connecting to DBMS.
The SpringFramework class contains the org.springframework.beans.factory.config.PropertyPlaceholderConfigurer class for the work with the configuration files. The layout will be as follows:

	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="jdbc.properties" />
	</bean>

Then you should determine the data source – the bridge between DBMS and Hibernate. I prefer to use this wonderful apache.commons.dbcp library for this.

	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
	</bean>

Once identified the source of the data, it’s time to describe the factory that will build the Hibernate-sessions.

There is the org.springframework.orm.hibernate3.LocalSessionFactoryBean class for it. We’ll describe this bean as follows:

	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:/hibernate.cfg.xml" />
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
			</props>
		</property>
	</bean>

All specific settings of Hibernate will be stored in the hibernate.cfg.xml file, the dialect – in the jdbc.properties file. Note that since we define the mapping by annotations, then the org.hibernate.cfg.AnnotationConfiguration class should work with such configuration.

We are connected to the database and the Hibernate-session is created. It’s time to point the application that it needs to dynamically manage the transaction. What is meant by “dynamically manage transactions?” This means that we do not need to write code that creates/closes/rolls back the transaction and to place it wherever you need. We need only to pass the HibernateTransactionManager class some rules of creation/completion of the transactions, and the rest it will take upon itself.

It’s clear that all this stuff works through AOP. The rule is a correspondence between the method and type of the transaction being created. This means that when we enter into the method (just before the start of implementation of the method code) – you need to create a transaction, and before leaving the method (after implementation of the the last statement of the method instruction) – commit the transaction. Well, and additionally you can describe due to which types of exceptions the transaction should be rolled back.

There are two basic ways of defining the rules: using of the Spring AOP notation in the Spring xml-configs, and using of annotations in Java-code. Each method has its advantages and disadvantages, but that’s the topic of another article. We’ll consider how to manage transactions using the annotations.

To manage a transaction in Spring there is a namespace tx where is defined, in particular, the tx:annotation-driven directive including the mechanism for transaction management via annotations. You can read about the parameters of this directive in section 9.5.6. of the document.

Let’s define the transaction manager as follows:

	<tx:annotation-driven transaction-manager="txManager" />
	<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
	</bean>

What remains to be determined are beans for the DAO layer and the business logic layer:

	<bean id="entityDAO" class="com.scriptkiddieblog.example.dao.EntityDao">
<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	<bean id="entityService" class="com.scriptkiddieblog.example.services.MyEntityService">
<property name="dao" ref="entityDAO" />
	</bean>

Finally I’ll give the example of the Main class code which runs the application:

package com.scriptkiddieblog.example;
 
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.scriptkiddieblog.example.entity.MyEntity;
import com.scriptkiddieblog.example.services.IMyEntityService;
 
public class Main {
 
	public static void main(String[] args) {
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		IMyEntityService service = (IMyEntityService) ctx.getBean("entityService");
		MyEntity entity = new MyEntity();
		entity.setName("Pavel");
		service.saveEntity(entity);
	}
}

The code is not complicated. First, we load the application context, then we get tge required bean from the context (in this case – “entityService”. Well, and then we use the bean according to the intended purpose — by means of it, save the entity to the database.

Actually, I think that the configuration via annotations is simpler than xml, and it’s even easier to read. In general, the interaction of beans could be also configured the bean with the help of annotations, Spring allows this for quite long time. On the topic of configuring Spring-beans through annotations, please read the articles on habrahabr: this and this.

Now you know how to connect DBMS and Hibernate to SpringFramework, to prpvide the dynamic transaction management, to describe the DAO layer and to connect DAO to the business logic. In fact, we have created the “fish” of the application and now we can indefinitely increase its functionality.

UPD 23.02.2011: Source code of the example (Maven-Project, GitHub).

12
Jun

HandlerInterceptor in Spring

Posted by eugene as Spring Framework

Sometimes you need the definite operation to be placed on each request, as for example to pull out the number of records in the database for placement on the page, or check the permissions, or yet a lot of options.

I saw the application written in Spring, which had one base class for all controllers, which performs such functionality. But in fact, there is such a thing as Handler interceptor in Spring.
Bean, implementing this interface can be specified in the URLs mappings and it will be invoked for each request. Better not even implement an interface HandlerInterceptor,and derive a class HandlerInterceptorAdapter, because it has a plug for all methods, and it’s only enough to override the appropriate method. But these methods are the following:

boolean preHandle (request, response, handler)

Performed before the implementation of the controller. The handler object is the controller itself which runs in the next order. Returns true if you can continue, or false if the overall work is already done (for example, returned the error about the lack of rights).

postHandle (request, response, handler, modelAndView)

If you need to do something after the controller implementation, but before the issuance of View (i.e. the page for the issue has not been generated). It makes sense if the controller we have issued returned an error or a redirect in such case, for example, no longer have to pull out the number of objects in the database. Or you can override something after the controller.

afterCompletion (request, response, handler, exception)

Called after the execution and issuance of all pages to the user. Will be invoked only if the controller worked out, if our method preHandle before issuing returned false, and hence the controller is not called, then this method is not called. If an error occurs, it will be in the attribute exception. The method is useful if you need to release any resources.

As an example, I will expand the instance with the calculator, and will add the counter of pages opening:

public class Counter extends HandlerInterceptorAdapter {
    private int start = 0;
    private int step = 1;
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        start += step;
        request.setAttribute("count", start);
        return true;
    }
    public void setStart(int start) {
        this.start = start;
    }
    public void setStep(int step) {
        this.step = step;
    }
}

add the following into our spring.xml:

<bean id="Counter" class="example.simplespring.ctrl.Counter" >
    </bean>

and extend urlMapping:

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
                <ref bean="Counter"/>
            </list>
        </property>
<property name="mappings">
<props>
<prop key="/calc.html">Calc</prop>
            </props>
        </property>
    </bean>

That’s all. Now, if we will add somewhere on the page

Counter: ${count}

then the number of pages openings will be placed here.

So the core sense is that when we constantly need something to prepare for the issuance of the user, then we do our HandlerInterceptors for each case and add them to the list of mapping addresses interceptors.

12
Jun

Using of Struts Tiles + Spring Framework

Posted by eugene as Spring Framework

One of the features of Struts Framework, besides of MVC for the web was a tag Tiles library which is going with it. Tiles possess with lots of possibilities, but most important that they help to make the inheritance of pages.

Yes, as well as the objects, define the basic techniques in the root, and in the ancestors override something and add the new one. Herewith, the library can be used separately from the Struts, it is perfectly integrated into the Spring Framework.
How can the JSP page structure look like with no tiles?

[header include]
[page body]
[footer include]

Well, there’s nothing complicated, just a typical PHP style. Now, let’s say in the header we have some changes such as a picture section, connects additional css, JavaScript, or something else.

That’s where it all begins: in the header is written terrible logic of covering the entire project, which depending on the address, what is beginning to turn on / off at inklyude transferred to different settings to make it all work, etc. Getting a bit uncomfortable.

Tiles would have looked in another way in it, the main template:

Header begin
Picture with [address]
[insert add. code]
Header end
[insert page body]
footer

and then, on the other pages, we write the header that inherit the parent, and that it replaces the address of the image, the body of the page, and sometimes extra сode.

The default values of these fields are configured in the configuration file, tiles, and can be empty.

That’s how it would look like in the form of JSP code:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="/tags/struts-tiles" prefix="tiles" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
      <title><tiles:getAsString name="title"/></title>
      <tiles:getAsString name="head" />
  </head>
  <body onload="<tiles:getAsString name="onLoad"/>">
<div id="header">
      MySuperPuperSite!
<h1><tiles:getAsString name="title"/></h1>
</div>
 
      <tiles:getAsString name="body" />
<div id="footer">
      copyrights, about the author or what there is needed on the bottom of the page
      </div>
 
  </body>
</html>

This is now

The page that wants to inherit it as follows:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="/tags/struts-tiles" prefix="tiles" %>
<tiles:insert definition="layout.root" flush="false">
  <tiles:put name="title">About site</tiles:put>
  <tiles:put name="body" direct="true">
     Any text
  </tiles:put>
</tiles:insert>

You can view this as the inheritance of pages, we are overriding methods only in the object, but here are bunches of html.

Setting of tiles in spring

<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles.TilesConfigurer"
          lazy-init="false">
<property name="factoryClass">
       <value>org.apache.struts.tiles.xmlDefinition.I18nFactorySet</value>
   </property>
<property name="definitions">
<list>
           <value>/WEB-INF/tiles.xml</value>
       </list>
   </property>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
    lazy-init="false">
<property name="requestContextAttribute"><value>requestContext</value></property>
<property name="viewClass">
        <value>org.springframework.web.servlet.view.tiles.TilesView</value>
    </property>
</bean>

Add custom jsp tag configuration in web.xml:

<jsp-config>
    <taglib>
       <taglib-uri>/tags/struts-tiles</taglib-uri>
       <taglib-location>/WEB-INF/struts-tiles.tld</taglib-location>
    </taglib>
</jsp-config>

Setting up links of the Tiles names to files

There is one catch: jsp obtained directly won’t work if they are specified in theModelAndView controller. Here is only indicated the tile identifier, and the pages themselves are configured in WEB-INF/tiles.xml (it is in our case, but generally in a filethat is specified in the value of the bean definitions tilesConfigurer).

It must be a solution I’ve found some of the following form:

<?xml version="1.0"?>
 <!DOCTYPE tiles-definitions PUBLIC
       "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN"
       "http://jakarta.apache.org/struts/dtds/tiles-config_1_1.dtd">
<tiles-definitions>
    <definition name="layout.error" path="/tiles/common/errorLayout.jsp"/>
    <definition name="layout.simple" path="/tiles/common/simpleLayout.jsp">
<put name="head" value=""/>
    </definition>
    <definition name="common.header" path="/tiles/common/header.jsp"/>
    <definition name="common.footer" path="/tiles/common/footer.jsp"/>
    <definition name="/index" path="/index.jsp"/>
    <definition name="user/login" path="/user/login.jsp"/>
    <definition name="404" path="/errors/404.jsp"/>
</tiles-definitions>

where name is the name of the tile, and path is the path to the existing jsp. And we have to prescribe all the pages in this way that is very uncomfortable, especially annoying when the name and path are actually the same (for both the index and user / login, differs only in that I was too lazy to write .jsp in name).

In general, something like that.