February 26, 2010

How to setup Spring Web Flow application

Spring web flow is solution for management of web application page flows. It's part of Spring web stack offering and works on top of Spring MVC. I have been working with the framework recently and had few troubles starting off with it. As a beginner to web flows, I had few hiccup ups. So, there is how to setup a minimal Spring web flow application.

This is not a tutorial for experts. What I am about to explain is just the basics and how to get going if you are starting with Spring web flow. You can begin with creation of a web application project using your Eclipse or Netbeans. You need to ensure that you have few jars:


  • Spring Web Flow (http://www.springsource.org/download#webflow). I used the version 2.0.8
  • ONGL (http://www.jarfinder.com/index.php/jars/versionInfo/433). I used version 2.6.7
  • I will assume you already have the Spring framework jars (I used version 2.5.6). I also used JSTL jars
The Spring web flow contains four jars. You need to add only the binding & webflow jars to the project.

Configuring the web.xml
There is no change in web.xml compared to a Spring MVC application. I just have my DispatcherServlet configured and other necessary configurations.

<servlet>
<servlet-name>swft1</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>        
</servlet>

<servlet-mapping>
<servlet-name>swft1</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
Configuring the application context
I have only one application context file and its named swft1-servlet.xml. Here is my configurations:
<bean id="handlerMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>/msgform.htm=flowController</value>        
</property>
</bean>

<bean id="flowController"
class="org.springframework.webflow.mvc.servlet.FlowController">
<property name="flowExecutor" ref="flowExecutor" />
</bean>

<flow:flow-executor id="flowExecutor" flow-registry="flowRegistry"/>

<flow:flow-registry id="flowRegistry">
<flow:flow-location id="msgform"
path="/WEB-INF/flows/simple-flow.xml" />
</flow:flow-registry>
Just like a Spring MVC application, I have a used the SimpleUrlHandlerMapping and mapped msgform.htm to flowController. The flowController is an instance of a specialized contoller class available as part of the web flow package. we will configure it with a property named flowExecutor. Flow executor drives the execution of the flow. And its configured with the tag flow-executor. We have a flow registry that holds all the flows for the application. Flows can be defined in multiple files and a registry is maintained. A flow registry is defined using the flow-registry tag as shown above. In our example, I have a single file defining the application flow. The location if the file is defined using the flow-location tag as shown above.

This is minimal the minimal configuration required! You will notice, that there is no view resolver. We will be making use of the default view resolver here. I will further explain this as we go.

Configuring the flow
A flow is described using XML files. And the flow file has to be registered in flow registry. In this example, We have only one file named simple-flow.xml:

<var name="msgObj" class="com.tpblog.web.models.Message"/>

<view-state id="start" model="msgObj" view="message.jsp">
<transition on="sendAction" to="success-state" />
</view-state>

<end-state id="success-state" view="success.jsp" commit="true" />
Please note that I have removed the root element of the xml. I have only used few features to keep it simple. Here we get a message from one screen and its displayed in another (web flow is NOT for these kinda stuff!!!). I have a msgObj that holds the message we type in the first screen (message.jsp). On clicking the submit button, we display success.jsp with the message.

In this flow, I have just two states; a view state and an end state. Notice that, I have specified the JSP files in the view attribute. Since,I am not using any view resolver, I need to specify the complete file name. The JSP files should also reside in the same folder as the flow configuration file. Once you have the basic application running, you can add features to it and modify it with other configurations.

For demo, I have a simple example of user login.In the next post, we will have a look at how to configure the view resolvers.

February 16, 2010

Consuming web service using Spring

With the adoption of SOA in companies, we have many web applications accessing web services which are local and external. My application currently interacts with web services built by other team with in the organization and also with third party. Java frameworks offer different ways to consume web services and we will have a look what spring framework has to offer.

Consuming web services with Spring is very simple. With Spring you will be able to configure a web service client using XML bean configuration. Spring takes care of creating the client stub when the applications starts. You can then access the web service from the Spring bean container.

Spring provides remoting support for web services via JAX-WS with the help of two factory beans, namely LocalJaxWsServiceFactoryBean and JaxWsPortProxyFactoryBean. I will use the latter as it returns a proxy that implements our business service interface. For this tutorial, I will take a public web service available at WebserviceX.NET. For demo, I have taken the whois lookup service. Here is our bean configuration:


<bean id="whoisService" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="wsdlDocumentUrl"  value="http://www.webservicex.net/whois.asmx?wsdl" />
<property name="namespaceUri"     value="http://www.webservicex.net" />
<property name="serviceName"      value="whois" />
<property name="portName"         value="whoisSoap" />
<property name="serviceInterface" value="com.spweb.services.WhoIsService" />
</bean>
Now, lets have a closer look at the bean configuration. I have defined five properties; wsdlDocumentUrl holds the WSDL URL for the web service we are going to consume. namespaceUri
defines the namespace, you can get this details from the WSDL file. Next comes the serviceName and portName of the web service. And the final property is the service interface. We will have to create the service interface so that we can interact with web service.

When the spring application starts, the bean gets created and we will be able to access the web service through this bean. To access, I injected the bean to one of my controller (I am using MVC) and call the necessary methods through my service interface. Now, lets have a look at our service interface. Its a simple java interface with some annotations and will have all the methods that we call. Here is our service interface:
@WebService(name = "whoisSoap",
targetNamespace = "http://www.webservicex.net")
public interface WhoIsService {

@WebMethod(operationName = "GetWhoIS",
action = "http://www.webservicex.net/GetWhoIS")
@WebResult(name = "GetWhoISResult", 
targetNamespace = "http://www.webservicex.net")
@RequestWrapper(localName = "GetWhoIS", 
targetNamespace = "http://www.webservicex.net",
className = "net.webservicex.GetWhoIS")
@ResponseWrapper(localName = "GetWhoISResponse", 
targetNamespace = "http://www.webservicex.net", 
className = "net.webservicex.GetWhoISResponse")
public String getWhoIs(@WebParam(name = "HostName", 
targetNamespace = "http://www.webservicex.net")String domain);
}
In order to work with web services, you need to study the WSDL file carefully. All the details come from this file. The first annotation is @WebService, which is used to define the interface as a service endpoint interface. In this case, I have specified the two properties namely, name and targetNamespace. The name property holds the name of wsdl:portType and targetNamespace holds the namespace of the the WSDL.

Next we declare methods which will be called. To tie these methods to the web service calls we use the @WebMethod annotation. The annotation specifies the operation name and action URL. Along with this, we also specify @WebResult,@RequestWrapper,@ResponseWrapper. These annotations provide information regarding request and response data types. The @WebParam is used to map the method parameters with the parameters of the web service.

Finally to consume the web service, I simple call the method as shown below:
if(whoService!=null) {
resultString = whoService.getWhoIs("hostname.com");
}
I do not create a instance of the service bean, instead it gets injected when the application starts. Here are few other points to note, I didn't use the Spring web service. The only jar dependency I had was saaj-impl apart from the spring framework's jars.

February 02, 2010

Access Control in ExtJS applications

When you implement large applications using Ext Js, you will definitely come across access control. Your application will have different type of users and you don't expect all users to have access to all features. Basically may have roles or groups defined for users and the big question is how do you implement it on to the front end of your application.

Before we proceed further you should remember an important point that permissions should be always be implemented on server side and JavaScript security is always secondary! This is because anybody with a JavaScript debugger and other web development tools can easily compromise the client side security. So, what is the use of adding client side security?

The client side security is used to improve user experience and abstract user so that he see only features or data that he have access to. So, the next question is how do we do it?

You will find many ways to implement the access control but the important point is avoiding unnecessary JavaScript logic to be downloaded when your access your application. At the same time, you can implement access control by avoiding code execution if its not available to the user.

Approach 1 : Permission Configuration
This is a simple approach wherein permission configurations is used to handle security. According to the role of the user who is accessing the application, a configuration class is dynamically built. This class is used to decide what the user can access and what not. When the user login to the application a JSON is created with list of accessible features.

Approach 2 : Control through Dynamic JavaScript
In this approach we will generate the JavaScript need for the user. Hence he will not get any code that he is not allowed to execute. When an user login to the application, his role or group to which he belongs to is determined. Using his role, the JavaScript is generated dynamically using a server side script (I used JSPs). The JavaScript file inclusion will look like:
<script type="text/javascript" src="scripts/application.jsp?role=${userRole}"></script>
Inside application.jsp, the administrator menu is only accessible if the user has the appropriate role.
<c:if test="${userRole=='ADMIN'}">

topMenuObject.add({id:'adminMenu',
text: 'Administrator',
handler: adminMenuHandler});
</c:if>

This approach has some disadvantages as well. The development can be little messy because you are coding JavaScript in JSP file. Also, there is an overhead created when you dynamically generate the JavaScript all the time. You will have to use caching mechanism in-order to reduce the overhead.

That's all for now. You are welcome to comment on these approaches and share other techniques if you have.

Read other ExtJS related articles!