JavaBeat

  • Home
  • Java
    • Java 7
    • Java 8
    • Java EE
    • Servlets
  • Spring Framework
    • Spring Tutorials
    • Spring 4 Tutorials
    • Spring Boot
  • JSF Tutorials
  • Most Popular
    • Binary Search Tree Traversal
    • Spring Batch Tutorial
    • AngularJS + Spring MVC
    • Spring Data JPA Tutorial
    • Packaging and Deploying Node.js
  • About Us
    • Join Us (JBC)
  • Privacy

Introduction to Struts Actions

July 21, 2007 by Krishna Srinivasan Leave a Comment

1) Introduction

Action classes will be defined to handle requests. Actions exists between the Model and View of an application. This article will cover all of the standard actions and the helper methods of the Action class. The struts-config.xml file designates the Action classes that handle requests for various URLs. The Action objects do

  • Invoke the appropriate business
  • Data-accesslogic
  • Store the results in beans
  • Designate the type of situation (missing data, database error etc.)

The struts-config.xml file then decides which JSP page should apply to that situation. Generally Actions do

  • Invoke business rules
  • Return Model objects to the View to display.

Actions also prepare error messages to display in the View. We can also create utility actions. Utility actions can be linked to other actions using action chaining. This allows us to extend the behavior of an action without changing an action or having deeply nested class hierarchies of actions.
Actions have a life cycle similar to servlets. They are like servlets and they’re multithreaded. We must be careful when working with member variables of an action because they are not thread safe. Struts has a servlet called the ActionServlet. The ActionServlet inspects the incoming request and delegates the request to an action based on the incoming request path. The object that relates the action to the incoming request path is the Action Mapping. Our actions are part of the Struts Controller.

2) Using Action classes

Typically There are 3 steps to create an Action

  1. Create an action by subclassing org.apache.struts.action.Action

    [code lang=”java”]
    import org.apache.struts.action
    public class ExampleAction extends Action { … } [/code]

  2. Override the execute() method : This is the method where we define the behavior of the current action. It contains business logic and the way to next action. The general structure of the execute() method is as follows:

    [code lang=”java”] public ActionForward execute(ActionMapping mapping,
    ActionForm form,
    HttpServletRequest request,
    HttpServletResponse response) throws IOException, ServletException [/code]
    The Action Mapping contains everything configurable in the action element of the Struts config file. The ActionForm represents the incoming request parameters. The HttpServletRequest references the current request object. No compulsary use for HttpServletResponse. The execute() method returns an ActionForward. The ActionForward is the logical next View or the logical next step.

  3. Configure the Action in the Struts config file. As follows

    [code lang=”html”] <action
    path="/ExampleAction "
    type="ExampleAction ">
    <forward name="success" path="/Example.jsp"/>
    </action> [/code]

  4. The path attribute specifies the incoming request path that this action will handle.Here we have the Major Classification of Struts Actions.

    • org.apache.struts.actions
    • Forward Action
    • IncludeAction
    • SwitchAction
    • DispatchAction
    • IncludeDispatchAction

Here mainly we are going to discuss about the above 5 actions.

3) ForwardAction

This is an Action that forwards to the context-relative URI specified by the parameter property of our associated ActionMapping. This can be used to integrate Struts with other business logic components that are implemented as servlets or JSP pages, but still take advantage of the Struts controller servlet’s functionality such as processing of form beans. To configure the use of this Action in our struts-config.xml file, create an entry like this:

[code lang=”xml”] <action
path="/saveSubscription"
type="org.apache.struts.actions.ForwardAction"
name="subscriptionForm"
scope="request"
input="/subscription.jsp"
parameter="/path to processing servlet" /> [/code]
This one will forward control to the context-relative URI specified by the parameter attribute. Steps to use ForwardAction:

  • Using the html:link tag with the action attribute, add a link to the JSP page that points to the action.
  • Create an Action Mapping in the Struts configuration file that uses the ForwardAction with the parameter attribute to specify the JSP path.

Let’s consider, we have a JSP page that has a direct link to another JSP page:

[code lang=”html”] <html:link page="/example.jsp">Home< /html:link>[/code]
Now we want to change the html:link tag to link to an action. Because we already have a link, simply change it as follows:

[code lang=”html”] <html:link action="home">Home</html:link>[/code]
All we did is, removing the page attribute and adding an Action attribute that points to the home action. Now, we have to create the home action mapping. To add an action mapping to the home action that we referenced in our html:link tag, use this code:

[code lang=”html”] <action
path="/home"
type="org.apache.struts.actions.ForwardAction"
parameter="/example.jsp" /> [/code]

3.1) Forward Attribute
ForwardActions get used quite a bit-so much so that the Struts configuration file includes support for them. So rather than doing this:

[code lang=”html”] <action
path="/home"
type="org.apache.struts.actions.ForwardAction"
parameter="/ example.jsp"/> [/code]
we can do this:

[code lang=”html”] <action
path="/home"
forward="/example.jsp"/>[/code]

4) IncludeAction

This is an Action that includes the context-relative URI specified by the parameter property of our associated ActionMapping. This can be used to integrate Struts with other business logic components that are implemented as servlets or JSP pages, but still take advantage of the Struts controller servlet’s functionality such as processing of form beans. To configure the use of this Action in our struts-config.xml file, create an entry like this:

[code lang=”xml”] <action
path="/saveSubscription"
type="org.apache.struts.actions.IncludeAction"
name="subscriptionForm"
scope="request"
input="/subscription.jsp"
parameter="/path to processing servlet"> [/code]

which will include the context-relative URI specified by the parameter attribute. This shorter form uses the include attribute:

[code lang=”html”] <action
path="/legacy"
include="/legacy/roar"
input="/form/userForm2.jsp"
name="userForm"
parameter="/legacy/roar"
validate="true"
scope="request"/>[/code]
The difference between the IncludeAction and the ForwardAction is that we need to use the IncludeAction only if the action is going to be included by another action or JSP. Therefore, if we have code in our JSP that looks like this:

[code lang=”html”] <jsp:include page="/someWebApp/ someModule/someAction.do " /> [/code]
The action could not use a ForwardAction because it would forward control to the new action rather than including its output within the output of the JSP-or throw a nasty IllegalStateException if the output buffer was already committed.

5) SwitchAction

This is a standard Action that switches to a new module and then forwards control to a URI within the new module. Valid request parameters for this Action are:

  • page – Module-relative URI (beginning with “/”) to which control should be forwarded after switching.
  • prefix – The module prefix (beginning with “/”) of the module to which control should be switched. Use a zero-length string for the default module. The appropriate ModuleConfig object will be stored as a request attribute, so any subsequent logic will assume the new module.

Say we have a web application that uses Struts. Struts has two modules: the default module and an admin module, both shown below:

[code lang=”html”] <servlet>
<servlet-name>action</servlet-name>
<servlet-class>
org.apache.struts.action.ActionServlet
</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml </param-value>
</init-param>
<init-param>
<param-name>config/admin</param-name>
<param-value>/WEB-INF/struts-config-admin.xml </param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet> [/code]
The init parameter config/admin defines the admin module. The config init parameter defines the default module. Now, let’s say we have an action in the default module that edits users and we want to delegate the display of those users to an action in the admin module. Perform the following steps:

  • First, map a SwitchAction into the default moduleas shown here:
    [code lang=”html”] <action
    path="/switch"
    type="org.apache.struts.actions.SwitchAction">
    </action>[/code]
  • Now, we can set up a forwardin the action that edits the users as follows:
    [code lang=”html”]
    <action
    path="/userSubmit"
    attribute="userForm"
    input="/form/userForm.jsp"
    name="userForm"
    scope="request"
    type="action.UserAction">
    <forward name="success" path="/switch.do?page=/listUsers.do&prefix=/admin"/>
    </action> [/code]

This forward passes two request parameters. The page parameter specifies the module relative action. The second parameter specifies the prefix of the module. We don’t have to use forwards to use the SwitchAction; any JSP can link to the SwitchAction to move to any module. The listUser.do action is not defined in the default module; it’s defined in the admin. The forward in this example forwards to the action at the path /admin/listUsers.do. The listUser.do is defined in /WEB-INF/struts-config-admin.xml, and the userSubmit. do action is defined in /WEB-INF/struts-config.xml.

6) DispatchAction

This is an abstract Action that dispatches to a public method that is named by the request parameter whose name is specified by the parameter property of the corresponding ActionMapping. This Action is useful for developers who prefer to combine many similar actions into a single Action class, in order to simplify their application design. To configure the use of this action in our struts-config.xml file, create an entry like this:

[code lang=”xml”] <action
path="/saveSubscription"
type="org.apache.struts.actions.DispatchAction"
name="subscriptionForm"
scope="request"
input="/subscription.jsp"
parameter="method"/> [/code]
which will use the value of the request parameter named “method” to pick the appropriate “execute” method, which must have the same signature of the standard Action.execute method. For example, we might have the following three methods in the same action:

  • Public ActionForward delete(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception
  • Public ActionForward insert(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception
  • Public ActionForward update(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception

and call one of the methods with a URL like this:

[code] http://localhost:8080/myapp/saveSubscription.do?method=update[/code]
It should be noted that we don’t have to use the DispatchAction to group multiple actions into one Action class. We could just use a hidden field that we inspect to delegate to member() methods inside of our action. On the other hand, we could use the action element’s parameter attribute and decide which method to invoke based on the value of the parameter attribute.
The DispatchAction uses a hidden request parameter to determine which method to invoke. Thus, subclasses of the DispatchAction have many methods with the same signature of the execute() method. The name of the hidden request parameter specifies the name of the method to invoke. We specify the name of the hidden parameter by using the parameter attribute of the action element.
Rather than having a single execute() method, we have a method for each logical action. The DispatchAction dispatches to one of the logical actions represented by the methods. It picks a method to invoke based on an incoming request parameter. The value of the incoming request parameter is the name of the method that the DispatchAction will invoke.
All of the other mapping characteristics of this action must be shared by the various handlers. This places some constraints over what types of handlers may reasonably be packaged into the same DispatchAction subclass. If the value of the request parameter is empty, a method named unspecified is called. The default action is to throw an exception. If the request was cancelled, the custom handler cancelled, will be used instead. We can also override the getMethodName method to override the action’s default handler selection. Here is an example that groups multiple actions into one action.

  • Create an action handlerclass that subclasses DispatchAction:
    [code lang=”java”] public class UserRegistrationMultiAction extends DispatchAction { … } [/code]
  • Create a method to represent each logical related action:
    [code lang=”java”] public ActionForward processPage1(ActionMapping mapping,
    ActionForm form,
    HttpServletRequest request,
    HttpServletResponse response) throws Exception
    {
    …
    }
    public ActionForward processPage2(ActionMapping mapping,
    ActionForm form,
    HttpServletRequest request,
    HttpServletResponse response) throws Exception
    {
    …
    } [/code]
    These methods have the same signature other than the method name of the standard Action method.
  • Create an Action Mapping for this action handler using the parameter attributeto specify the request parameter that carries the name of the method that we want to invoke:
    [code lang=”html”] <action
    path="/userRegistrationMultiPage1"
    type="strutsTutorial.UserRegistrationMultiAction"
    name="userRegistrationForm"
    attribute="user"
    parameter="action"
    input="/userRegistrationPage1.jsp">
    …
    </action>

    <action
    path="/userRegistrationMultiPage2"
    type="strutsTutorial.UserRegistrationMultiAction"
    name="userRegistrationForm"
    attribute="user"
    parameter="action"
    input="/userRegistrationPage2.jsp">
    …
    </action>[/code]
    Based on this code, the DispatchAction that we created uses the value of the request parameter named method to pick the appropriate method to invoke. The parameter attribute specifies the name of the request parameter that is inspected by the DispatchAction.

  • Pass the action a request parameter that refers to the method we want to invoke. The userRegistrationPage1.jsp contains this hidden parameter:
    [code lang=”html”] <html:hidden property="action" value="processPage1"/>
    while the userRegistrationPage2.jsp contains this hidden parameter:
    <html:hidden property="action" value="processPage2"/> [/code]

    This implementation sends a hidden field parameter instead that specifies which method to invoke.

6.1) LookupDispatchAction

This is an abstract Action that dispatches to the subclass mapped execute method. This is useful in cases where an HTML form has multiple submit buttons with the same name. The button name is specified by the parameter property of the corresponding ActionMapping. To configure the use of this action in our struts-config.xml file, create an entry like this:

[code lang=”xml”] <action
path="/test"
type="org.example.MyAction"
name="MyForm"
scope="request"
input="/test.jsp"
parameter="method"/>[/code]
which will use the value of the request parameter named “method” to locate the corresponding key in ApplicationResources. For example, we might have the following ApplicationResources.properties:

[code lang=”java”] button.add=Add Record
button.delete=Delete Record [/code]
And our JSP would have the following format for submit buttons:

[code lang=”html”] <html:form action="/test">
<html:submit property="method">
<bean:message key="button.add"/>
</html:submit>
<html:submit property="method">
<bean:message key="button.delete"/>
</html:submit>
</html:form> [/code]
Our subclass must implement both getKeyMethodMap and the methods defined in the map. An example of such implementations are:

[code lang=”java”] protected Map getKeyMethodMap() {
Map map = new HashMap();
map.put("button.add", "add");
map.put("button.delete", "delete");
return map;
}
public ActionForward add(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
// do add
return mapping.findForward("success");
}
public ActionForward delete(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
// do delete
return mapping.findForward("success");
}[/code]
If duplicate values exist for the keys returned by getKeys, only the first one found will be returned. If no corresponding key is found then an exception will be thrown. We can override the method unspecified to provide a custom handler. If the submit was cancelled, the custom handler cancelled will be used instead.
For this example, we use the registration form to use the LookupDispatchAction. We will add two buttons. One button will be labeled Save; this button will save the user to the system. The second button will be called Remove to use the LookupDispatchAction, perform the following steps:

  • Create an action handler class that subclasses LookupDispatchAction:
    [code lang=”java”] public class UserRegistrationAction extends LookupDispatchAction {…} [/code]
  • Next, we create a method to represent each logical related action: save and remove:
    [code lang=”java”] public class UserRegistrationAction extends LookupDispatchAction
    {
    private static Log log = LogFactory.getLog(UserRegistrationAction.class);

    public ActionForward remove( ActionMapping mapping,
    ActionForm form,
    HttpServletRequest request,
    HttpServletResponse response) throws Exception
    {
    log.debug("IN REMOVE METHOD");
    return mapping.findForward("success");
    }

    public ActionForward save(ActionMapping mapping,
    ActionForm form,
    HttpServletRequest request,
    HttpServletResponse response) throws Exception
    {
    /* Create a User DTO and copy the properties from the userForm */
    User user = new User();
    BeanUtils.copyProperties(user, form);
    DataSource dataSource = getDataSource(request, "userDB");
    Connection conn = dataSource.getConnection();
    try {
    /* Create UserDAO */
    UserDAO dao = DAOFactory.createUserDAO(conn);
    /* Use the UserDAO to insert the new user into the system */
    dao.createUser(user);
    } finally {
    conn.close(); }
    return mapping.findForward("success");
    }
    }[/code]
    The two action methods, save and remove, have identical signatures to the standard Action.execute() method except for the method name.

  • Implement the getKeyMethodMap()method to map the resource keys to method names:
    [code lang=”java”] protected Map getKeyMethodMap() {
    Map map = new HashMap();
    map.put("userRegistration.removeButton", "remove");
    map.put("userRegistration.saveButton", "save");
    return map;
    } [/code]
  • Create an action mapping for this action handler using the parameter attribute to specify the request parameter that carries the name of the method we want to invoke:
    [code lang=”html”] <action
    path="/userRegistration"
    type="strutsTutorial.UserRegistrationAction"
    name="userRegistrationForm"
    attribute="user"
    input="/userRegistration.jsp"
    parameter="action" >
    …
    <forward name="success" path="/regSuccess.jsp" />
    <forward name="failure" path="/regFailure.jsp" />
    </action> [/code]
    Here we specify the parameter to the action. This has a similar meaning to the DispatchAction. Essentially, this means the LookupDispatchAction inspects the label of the button called action. The label will be looked up from the resource bundle, the corresponding key will be found, and the key will be used against the method map to find the name of the method to invoke.
  • Set up the messages in the resource bundle for the labels and values of the buttons. Inside our resource bundle, add the following two entries:
    [code lang=”java”] userRegistration.removeButton=Remove
    userRegistration.saveButton=Save[/code]
    Here the keys are the same keys we used in the getKeyMethodMap.
  • Use the bean:messagetag to display the labels of the button and associate the buttons with the name action:
    [code lang=”html”] <%@ taglib uri="/tags/struts-html" prefix="html"%>
    <%@ taglib uri="/tags/struts-bean" prefix="bean"%>
    …
    <html:submit property="action">
    <bean:message key="userRegistration.removeButton"/>
    </html:submit>
    …
    <html:submit property="action">
    <bean:message key="userRegistration.saveButton"/>
    </html:submit>
    … [/code]
    The final result depends on the user clicks.

7) Some More Actions and Action Helper Methods

Some more actions are there. Those are

  • BaseAction: BaseAction is provided as an intermediate class for shared funtionality between Action and any stock implementation provided in this package.
  • DownloadAction: This is an abstract base class that minimizes the amount of special coding that needs to be written to download a file.
  • EventDispatchAction: An Action that dispatches to to one of the public methods that are named in the parameter attribute of the corresponding ActionMapping and matches a submission parameter.
  • LocaleAction: Implementation of Action that changes the user’s Locale and forwards to a page, based on request level parameters that are set (language, country, & page).
  • MappingDispatchAction: An abstract Action that dispatches to a public method that is named by the parameter attribute of the corresponding ActionMapping.

The Action class contains many helper methods, which enable us to add advanced functionality to our Struts applications. Some of them are

  • Action saveTokenand isTokenValid: Make sure that a form is not submitted twice
  • Action saveMessages and getResources: Display dynamic messages that are i18n-enabled
  • Action isCancelled: Allow users to cancel an operation
  • Action getLocale and setLocale: Allow users to change their locale.

also read:

  • Struts 2 Tutorials
  • Struts Interview Questions
  • Struts and Spring Integration

8) Summary

Herewith we discussed in detail about the Struts Actions named: ForwardAction, IncludeAction, SwitchAction and DispatchAction in addition with LookupDispatchAction with some examples. Read it clearly and don’t get confused the functionalities.Try those examples and try to work with remaining actions also. I will come up in detail about the Action Class Helper Methods in my next article.

Filed Under: Struts Tagged With: Struts Actions

AJAX Support in Struts 2.0

June 9, 2007 by Krishna Srinivasan Leave a Comment

Ajax or Asynchronous JavaScript and XML was introduced by Jesse James Garrett in 2005. He is called the “Father of Ajax” .Ajax is a collection of concepts and technologies that allows richer and more interactive user interaction with the web applications. The Ajax engine allows the user’s interaction with the application to happen asynchronously — independent of communication with the server. So the user is never staring at a blank browser window and an hourglass icon, waiting around for the server to do something.

also read:

  • Struts 2 Tutorials
  • Struts Interview Questions
  • Struts and Spring Integration

Who is using AJAX

The most popular and the biggest user of AJAX is Google. Orkut, Gmail, the latest beta version of Google Groups, Google Suggest, and Google Maps — are Ajax applications Google mail, Google calendar and Google home page are some examples. In your Google mailbox the “loading” that is displayed in the top right corner is using these Ajax technologies. The new Yahoo homepage too uses some of these technologies. Another cool Ajax implemented website would be www.pageflakes.com Others are following suit: many of the features that people love in Flickr depend on Ajax, and Amazon’s A9.com search engine applies similar techniques.

The BackScreen of Ajax

In traditional webpages, the pages will be reloaded for each and every request. But in most of the cases only a part of the page will be processed. Hence such a page reload is unnecessary. Thus the usage of ajax plays a efficient role. In the webpages, that are using ajax, only the part of the page that has to be processed will be transferred to the web server and the processed data will be loaded in the page without a page reload.

AJAX internals

AJAX is not a single technology as mentioned earlier. It is important to remember that AJAX is not Java or .NET dependent.

Whatever be your back end code, you can use AJAX to communicate with it. People prefer AJAX for the high speed with which it works. It does it with three basic ways

  • Better utilization of browser cache
  • Batching up of network requests in a single packet to reduce network latency issues
  • Decreasing the workload on the server by not requiring it to process the entire page

Where can we use AJAX

Forms:
Web based forms are slow. AJAX can definitely improve the performance of web-based formsUser Communication:
User communications like chat pages, voting’s and ratings can be done efficiently using AJAX
News:
RSS feed is another popular concept where AJAX can be used
Data Manipulation:
This includes some sort of filtering data, selecting names from one combo box to another, sorting data, invoking the suggest criteria or a hint

Defining Ajax

As we have seen an introduction to AJAX, let us try to define it. Ajax isn’t a technology. It’s really several technologies, each flourishing in its own right, coming together in powerful new ways. Ajax incorporates:

  • Standards-based presentation using XHTML and CSS;
  • Dynamic display and interaction using the Document Object Model;
  • Data interchange and manipulation using XML and XSLT;
  • Asynchronous data retrieval using XMLHttpRequest;

And JavaScript binding everything together.
So, how does AJAX does this sending request and getting response from the backend server??

Using the XML Http Request object.

XML Http Request object

The XML HttpRequest was introduced by Microsoft in Internet Explorer 5.0. Recently , Mozilla and apple have included support for this in their web browsers(Firefox and Safari).This object is the fundamental basis for Ajax. Microsoft implementation is different from that of other web browsers, so when you create this object in your code, you need to do a typical browser check.

For Internet Explorer, we can create this object using,

Var req = new ActiveXObject(“Microsoft.XMLHTTP”);

For firefox and safari,

Var req = new XMLHttpRequest();

Struts and Ajax in Action

As we have seen enough of the theory behind the working of Ajax in struts let us see an example. Simple example is loading a drop down depending on the selected item in another drop down. We need to populate the characters in a “showcharacters” dropdown when a particular TV Show is selected in the “showTVShow” drop down using AJAX. Let us see the Ajax request response cycle for this scenario.

Fig 1.1 Ajax Request Response Cycle

Step 1: Create a jsp page (“tvshow.jsp”)

Let us take three TV shows which I like.”Lisse Maguire”,” That’s so Raven” and “Dhoom Machallo Dhoom”. We need to populate the characters dropdown as and when the TV Show dropdown value changes , so we decide to call the javascript in the “onchange()” of the select box.

[code lang=”html”] <html:form action="showCharacters.do">
TV Show:
<html:select property="TVShowSelect"
onchange="retrieveURL(‘ showCharacters.do?tvShow=’ + this.value);">
<html:option value="Lissie Maguire"> Lissie Maguire </html:option>
<html:option value="That’s so Raven"> That’s so Raven </html:option>
<html:option value="Dhoom machale"> Dhoom machale </html:option>
</html:select>
<br>
Characters: <span id="characters"></span>
</html:form> [/code]

Here we are sending a URL to the Java script function.

[code lang=”java”] “’ showCharacters.do?tvShow=’ + this.value”[/code]

We are appending the selected item with the URL as a query string. We can also just send the Url and append the form contents in the java script.

Step:2 Making the AJAX Call to the Server

In the java script we need to create a XML HttpRequest object

[code lang=”java”] function retrieveURL(url)
{
if (window.XMLHttpRequest)
{
// Non-IE browsers
req = new XMLHttpRequest();
req.onreadystatechange = processStateChange;
try {
req.open("GET", url, true);
} catch (e) {
alert(e);
}
req.send(null);
} else if (window.ActiveXObject) { // IE

req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange = processStateChange;
req.open("GET", url, true);
req.send();
}
}
}[/code]

Within the retrieveURL() method, the line req.onreadystatechange = processStateChange (note: no brackets) tells the browser to call the processStateChange() method once the server sends back its response. This method (now standard in AJAX) also determines whether it should use the Internet Explorer (ActiveX) or Netscape/Mozilla (XmlHttpRequest) object to ensure cross-browser compatibility.

Now when the XMLHttpRequest object is created , we ask the browser to call the processstatechange method when we get the response from the server.

Step 3: Configure action path in struts-config

This is the same old struts functioning.

“’showCharacters.do” is configured in the struts-config.xml

struts-config.xml

[code lang=”xml”] <action path="/showCharacters " type="ShowTVAction" validate="false" >
<forward name="success" path="/pages/showCharacters.jsp" />
</action>[/code]

Step 4: Write the action class

The action class has to get the value selected in the TVShow dropdown and Get the appropriate list of characters using the function getCharacters(String tvShow) .

[code lang=”java”] public class ShowTVAction extends Action {

public ActionForward execute(ActionMapping mapping, ActionForm inForm, HttpServletRequest request, HttpServletResponse response) throws Exception {

// Get a list of characters associated with the select TV show
String tvShow = (String)request.getParameter("tvShow");
if (tvShow == null) {
tvShow = "";
}
ArrayList characters = getCharacters(tvShow);
request.getSession().setAttribute("characters", characters);
response.setContentType("text/html");
return mapping.findForward("success");
} // End execute()

// This method returns a list of characters for a given TV show. If no TV
// show is selected, i.e., initial page view, am empty ArrayList is returned.

private ArrayList getCharacters (String tvShow) {

ArrayList al = new ArrayList();

if (tvShow.equalsIgnoreCase("Lissie Mcguire")) {
al.add("Lizzie Mcguire");
al.add("Mathew Mcguire");
al.add("Miranda");
al.add("Gordon");
}

if (tvShow.equalsIgnoreCase("That’s so Raven ")) {
al.add("Raven");
al.add("Chelse”);
al.add("Orlanda");
al.add("Victor Backstor");
al.add("Cory Backstor");
}

if (tvShow.equalsIgnoreCase("Dhoom machale ")) {
al.add("Priyanka");
al.add("Koyel");
al.add("Nehal");
al.add("Aadhiraj");
al.add("Maleni");
}

return al;

} // End getCharacters()

} // End class[/code]

Then it sets the Appropriate characters in the session and returns the keyword “success” Thus the control passes to showCharacters.jsp

Step 5: Write the contents you need to reload in the characters drop down (“ShowCharacters.jsp”)

In the showCharacters.jsp we load the contents of the characters drop down by taking their values from the session. Remember to add the tag libraries and surround the code with a form tag.

ShowCharacters.jsp

[code lang=”html”] <html:select property="TVShowSelect">
<logic:present name="characters">
<%ArrayList ch = (ArrayList) request.getSession().getAttribute("characters");
String[] s = new String[ch.size()];
ch.toArray(s);
for(int i=0;i<s.length;i++)
{%>
<html:option value ="<%=s[i] %>" ></html:option>
<%} %>
</logic:present>
</html:select>[/code]

Thus the showCharacters.jsp is the response from the Back end server. Once the response form the server is got by the browser. It calls the processStateChange() method

Step 6: Updating the Web Page with the AJAX Response

So far, we have looked at the JavaScript to do the AJAX call (listed above) and the Struts Action, ActionForm, and JSP (mostly the same, with the addition of tags). To complete our understanding of the Struts-AJAX project, we need to look at the following JavaScript function that is responsible for updating the current web page when the results from the server are received.

processStateChange(): The method name that we set before making the AJAX call. The XMLHttpRequest/Microsoft.XMLHTTP object calls this method once the server has completed sending back its response.

[code lang=”java”] function processStateChange() {
if (req.readyState == 4) { // Complete
if (req.status == 200) { // OK response
document.getElementById("characters").innerHTML = req.responseText;
} else {
alert("Problem: " + req.statusText);
}
}
}[/code]

Here readystate is checked .If it is equal to 4 , it means the response is completely received and the status of the response is checked to 200.

If everything fit in, the response is set as the innerHTML of the span “characters”. We can also give the response to a div.

Thus we have done a asynchronous call to the back end and got the response and set it to a span element. Only the contents of the span have been reloaded while the rest of the page remained there.

Flow of Control

By adding the above JavaScript code to our application, the following steps now happen on the server and on the browser.

  • The page loads as per a normal Struts application.
  • The user changes a dropdown value, triggering an onChange() event, which calls the retrieveURL() JavaScript function
  • This JavaScript function makes a (background) call to the Struts Action on the server
  • This JavaScript function also sets the name of a second JavaScript function, which will be called when the server response is finished. In this case, it is set to the processStateChange() method.
  • As expected, when the server response is finished, the processStateChange() method is called.
  • The JavaScript sets the response to a span in the page

New Features in Struts 2.0 for AJAX

One of the useful enhancements in Struts 2.0 is the introduction of AJAX Theme

The Ajax theme extends the xhtml theme with AJAX features. The theme uses the popular DOJO AJAX/JavaScript toolkit. The new AJAX features include:

  • AJAX Client Side Validation
  • Remote form submission support (works with the submit tag as well)
  • An advanced div template that provides dynamic reloading of partial HTML
  • An advanced a template that provides the ability to load and evaluate JavaScript remotely
  • An AJAX-only tabbed Panel implementation
  • A rich pub-sub event model
  • Interactive auto complete tag

The framework provides a set of tags to help you ajaxify your applications, on Dojo.

To use the Ajax tags you need to set the “theme” attribute to “Ajax”.Use the head tag to configure the page for the Ajax theme.

URL

The “href” attribute must contain a url built with the URL tag
Example:

[code] Initial Content[/code]

Set the “debug” attribute of the head tag to “true” to display debug information on the bottom of the page

Indicators

Use indicators to notify the user that a request is in progress. The indicator should be hidden when the page is loaded.

Dynamic Div

The div tag is a content area that can load its content asynchronously. The div tag can be forced to reload its content using topics. To define the topics that will trigger the refresh of the panel, use the “listenTopics” attribute. This tag will load its content when the page is loaded, unless “autoStart” is set to “false”.
While Dojo supports crossdomain XHR using IFrames, the S2 Ajax tags do not (yet)

This div will refresh every time the topics “/refresh0” or “/refresh1” are published:

to publish a topic use.

[code] dojo.event.topic.publish("/refresh”);[/code]

Retrieve Remote Data

The simplest way to use the div tag is to provide an href attribute. For example

What this does after the HTML page is completely loaded; the specified URL will be retrieved asynchronously in the browser. The entire contents returned by that URL will be injected in to the div and will update every minute after a two second delay: Include the attribute errorText in case the URL is not loaded

[code lang=”java”] errorText="Unable to contact weather server"[/code]

Submit

The submit tag can be used to update the content of its “targets” attribute with text returned from the asynchronous request. “targets” is a comma-delimited list of element ids. The “targets” attribute is optional.

Regular submit button that will update the content of div1:

Div 1

For using Submit button using an image add the attribute src

[code lang=”java”] src="${pageContext.request.contextPath}/images/struts-rocks.gif"[/code]

If the submit button is used inside a form (href is not required on this case), the form will be submitted asynchronously using
A submit button can be used to submit a form, even if it is outside the form, using “formId”, “formFilter” and “href”. Note that in this case “href” is required.

[code lang=”xml”] <input type="textbox" name="data" />[/code]

Anchor

The anchor tag, like the submit tag; can be used to update the content of its “targets” attribute with text returned from the asynchronous request. “Targets” is a comma-delimited list of element ids. The “targets” attribute is optional.

This anchor will update the content of div1 and div2 with text returned form “/AjaxTest.action”

Div 1
Div 2

Update divs If the anchor tag is used inside a form (href is not required on this case), the form will be submitted asynchronously:

[code lang=”xml”]
<input type="textbox" name="data" />
Submit form[/code]

Using the anchor tag to submit a form:

[code lang=”xml”]
<input type="textbox" name="data" />

Submit form[/code]

AJAX Client Side Validation

  • Ajax Validation requires DWR servlet being setup, Dojo and the Ajax theme being used.
  • In the Ajax theme, DWR is used for normal validation while Dojo handles everything else (widgets, XHR, browser JS events etc.)
  • In order for validation to function properly it is advised to use standard Struts Tags

Setup DWR

DWR could be setup by having the following dwr configuration (dwr.xml) at /WEB-INF/ directory. If it needs to be in other places.

[code lang=”java”] [/code]

A DWRServlet need to be registered with the web application as well. The following shows a typical web.xml with DWRSerlvet.

[code lang=”java”]
dwr
uk.ltd.getahead.dwr.DWRServlet

debug
true

<!– JavaServer Faces Servlet Configuration, not used directly –>

faces
javax.faces.webapp.FacesServlet
1

<!– JavaServer Faces Servlet Mapping, not called directly –>

faces
*.action

dwr
/dwr/*[/code]

Add a form attribute

Add the attribute validate to the. The validate=”true” option is set for thetag to enable onblur-triggered validation

[code lang=”java”] Validation – Basic[/code]

Now as usual have a form bean for this form with getters and setters and constructors, and configure the validation.xml for required fields

[code] You must enter a name1319
Only people ages 13 to 19 may take this quiz[/code]

Summary

This is a simple introduction to Ajax.Start implementing it and you will find it simple, easy and attractive. One can use it to do many different things. It all accounts your creativity. It is a good approach in many cases, but will not be appropriate in others. If reaching the maximum possible audience is your goal, you would want to stay away from this. If a user disabling scripting in their browser might be a concern (and your site wouldn’t be any good without it), this probably isn’t a good answer either. There are other reasons to stay away from it in some situations, but the bottom line is treat it like any other tool in your toolbox: it will be right for some jobs, maybe “not so” for others.

Filed Under: Struts Tagged With: AJAX, Struts 2.0

Struts 2.0 and Validations using Annotations

May 30, 2007 by Krishna Srinivasan Leave a Comment

This article provides an introduction to Struts 2.0 and its new Validation Features. Since Struts 2.0 is new, the first few sections of the article discusses in brief about the basics of Struts 2.0, its architecture and its various New Features. The rest of the article is dedicated towards explaining about the new Validation Features available. Struts is an Open-Source Web Application Framework that simplifies the creation of a Java Web Application. It is based on the Model-View-Controller 2 (MVC 2) Architecture which was originally found in a language called SmallTalk. The recent version of Struts is Struts 2.0 and it has borrowed most of the concepts in terms of architecture and functionality from two frameworks namely WebWork and XWork.

also read:

  • Struts 2 Tutorials
  • Struts Interview Questions
  • Struts and Spring Integration

Struts 2.0 – MVC Architecture

Struts 2.0 is based on MVC 2 Architecture. MVC is mainly concentrated in splitting the whole set of logic that happens in an Application into three different layers namely the Model, View and the Controller. In Struts 2.0, the Controller acts as a mediator between the View and the Model components. Whenever a request comes from a client, it is this Controller component who intercepts the request before being passed to Appropriate Handler.
Model represents the application data as well as the business logic that operates on the Data. Whenever the Framework routes the request to some Action class, the Action Class will do the Business Processing Logic which results in the State of the Application getting affected. After the application’s state is affected, the control is returned back to the Controller which determines which View to be Rendered to the Client Application.
View is the Display Surface given as a response back to the Client populated with values. Struts 2.0 is not restricted in having JSP as its only View. Any View Technolgy can be chosen to render the Client Surface. It can be JSP, Velocity, Freemaker, or even XSLT. Even a brand new View technology can be plugged-in easily to the Struts Framework.

The Flow of a Struts 2.0 Application

The following are the sequence of steps that will happen when a Html Client makes a request to a Web Application built on top of Struts 2.0

  • The Client (which is usually a Html Browser) makes a Request to the Web Application.
  • The Web Server will search for the Configuration Information that is very specific to the Web Application (taken from the web.xml file), and will identity which Boot-strap Component has to be loaded to serve the Client’s Request.
  • In Struts 2.0, this Component is going to be a Servlet Filter (whereas in Struts 1.0, the component is an Action Servlet).
  • The Filter Servlet then finds out the Action Class for this Request that is mapped in the Configuration File.
  • Before passing the Request to the Action class, the Controller passes the Request to a series of Interceptor Stack (explained later).
  • Then the Request Object is passed on to the corresponding Action Class.
  • The Action Class then executes the Appropriate Business Logic based on the Request and the Request Parameters.
  • After the execution of the Business Logic, a Result (“success” or “error”) is returned either in the form of String or in the form of Result Object back to the Controller.
  • The Controller uses the Return Result to choose which View to be rendered back to the Client Application.

Let us look into the details of the major steps that was listed above.

Filter Servlet Loaded and Invoked by the Framework

A client makes a Web Request by typing the URL of the Web Application that is hosted in the Web Server something like the following, where localhost is the Machine Name where the Web Server is running, 8080 is the Port Number and hello is the Application Context for the Web Application.

[code lang=”java”] http://localhost:8080/hello[/code]
Whenever a Request comes to a Web Application that is Struts 2.0 Enabled, the Web Server will search and load the Configuration Related Information that is very specific to the Application. In the case of a Struts 2.0 enabled Application, the Boot-Strap Component is going to a Filter Servlet. The Configuration Information about the Web Application will be maintained separately in web.xml file. Following is the Xml snippet taken from the web.xml file,
web.xml

[code lang=”xml”] <filter>
<filter-name>Struts2FilterServlet</filter-name>
<filter-class>
org.apache.struts.action2.dispatcher.FilterDispatcher
</filter-class>
</filter>

<filter-mapping>
<filter-name>Struts2FilterServlet</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>[/code]
The above Xml Code tells that whatever be the Request URI Pattern (which is indicated by /*) that comes from the Client, identify the Component named by Struts2FilterServlet which happens to be the class org.apache.struts.action2.dispatcher.FilterDispatcher.
The Identified Component is then instantiated and then passed with the Request Information.

Request Intercepted by Interceptors

Interceptors provide Pre-processing and Post-processing functionality for a Request or a Response object in a Web Application. For general information about Interceptors, readers can go through  this section on JavaBeat. A Request Object usually passes through a Series of Interceptors before actually reaching the Framework. Assume that some kind of Authentication and Authorization related stuffs have to be done before a Request Object is being passed to a particular Module. In such a case, we can have the Core Business Logic that does the functionality of authorizing the Client Request in an Interceptor called AuthenticationInterceptor which does the Pre-processing works. Implementing a Custom Interceptor like this is very simple in Struts 2.0. The class structure may look like this,
AuthenticationInterceptor.java

[code lang=”java”] package myinterceptors;

import com.opensymphony.xwork2.interceptor.*;

class AuthenticationInterceptor implements Interceptor{

public void init(){}

public void destroy(){}

public String intercept(ActionInvocation invocation) throws Exception{

// Get the value of user credentials from the Request and Validate it.

}
}[/code]
As we can see, writing a Custom Interceptor is as simple as writing a class that implements the Interceptor interface which is found in the com.opensymphony.xwork2.interceptor package. The method of interest is Interceptor.intercept() which has to be overriden along with the the appropriate business logic. Then the Custom Interceptor has to be made available to the framework
by adding information in the Configuration File (struts.xml) as shown below,
struts.xml

[code lang=”xml”] <struts>

…
<interceptors>
<interceptor name = "authentication"
class = "myinterceptors.AuthenticationInterceptor">
</interceptor>
<interceptors>
…

</struts>[/code]
Interceptors are configured into the Web Application in the struts.xml file with the help of  and entries. The name attribute is the alias name of the interceptor and it must be unique among the other set of Interceptor names.
The class attribute identifies the actual implementation class for an Interceptor. The advantages of interceptors is not only limited to this. Interceptors can participate in so many different activities, to name a few – providing Logging Information to an Application, providing Encryption Facilities for the user input that used to get transmitted across layers, etc.. . Struts 2.0 already comes with a bunch of Built-in Useful Interceptors.

Performing some Action for a Request

After passing through a series of Interceptors, now it is time for the Framework to determine what Action has to be done for the Request. The Mapping between a Request and its Corresponding Action is configurable in the Xml Configuration File.
Assume that in a Web Application, Regitration, Login and Logout represents the different set of actions. Let us have an assumptions that the operations are fairly complex, so that we tend to have individual classes for each of the operation. These things are configured in the struts.xml like the following,
struts.xml

[code lang=”xml”] <struts>

<action name = "Registration" class = "hello.RegistrationAction">
<action name = "Login" class = "hello.LoginAction">
<action name = "Logout" class = "hello.LogoutAction">

</struts>[/code]

The Action Class usually acts as a Model and executes a particular business logic depending on the Request object and the Input Parameters. In earlier versions of Struts (before Struts 2.0), an Action class is supposed to extend the org.apache.struts.Action class and has to override the Action.execute() method which takes four parameters. Following is the code snippet of an Action class before Struts 2.0,

MyAction.java

[code lang=”java”] package myactions;

import java.servlet.http.*;
import org.apache.struts.*;

class MyAction extends Action{

public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws java.lang.Exception {

// Do some business logic here.

}
}[/code]
In Struts 2.0, an Action class is made flexible as it can be a simple POJO Class. It means that the Action Class doesn’t need to extend some class or implement an interface. It can be as simple as possible, and the following code snippet proves the same,
MyAction.java

[code lang=”java”] package myactions;

import com.opensymphony.xwork2.*;

class MyAction extends Action{

public String execute(){
// Some logic here.
}

}[/code]
Here comes the big question!. Then how can an Action class is supposed to access the HttpServletRequest and the HttpServletResponse objects to get the needed information!!! At this stage it is worth to mention about the Aware-Related Interfaces here.
Suppose that an Action class wants to access the HttpServletRequest object. For this, it has to implement a special Aware Interface called ServletRequestAware and has to override the method setServletRequest(HttpServletRequest request) thereby storing it in an instance variable. So, the new modified action class becomes like this, MyAction.java

[code lang=”java”] package myactions;

import javax.servlet.http.*;

import com.opensymphony.xwork2.*;
import org.apache.struts2.interceptor.*;

class MyAction extends Action implements ServletRequestAware{

private HttpServletRequest request;

public String execute(){
}

public void setServletRequest(HttpServletRequest request){
this.request = request;
}
}[/code]
This above technique is basically an Inversion of Control. Inversion of Control is generally a Push Model which means that the data needed by the Application will be pushed by the Container or the Framework. In our case, we are making the Struts 2.0 Framework to call the method ServletRequestAware.setServletRequest(HttpServletRequest request) thereby populating the Request Object. Similar to this, there are Aware-Related Interfaces for Application, Servlet Request, Servlet Response, Parameters etc namely ApplicationAware, HttpServletRequestAware, HttpServletResponseAware,
ParameterAware respectively.

Rendering the Result back to the Client

As we can see from the method signature, the return type of the Action.excute() method is just a String. This return type defines the Logical Outcome of the Action or the Page. Actual Outcome or the Response of a Page is configurable in the Struts Configuration File. Say the Action class can return a logical ‘success’ which tells that the action has be successfully processed or ‘failure’ which sadly tells that some thing wrong has happened in the Application. Some Predefined Constants have been defined in theAction interface for the logical outcomes namely, Action.SUCCESS, Action.ERROR, Action.LOGIN, Action.INPUT and
Action.NONE. Consider the following code snippet,
MyAction.java

[code lang=”java”] package myactions;

public class MyAction{

public String execute(){

if (createOperation()){
return "create";
}else if (deleteOperation()){
return "delete";
}else if( readOperation()){
return "read";
}else if (writeOperation()){
return "write";
}
return "error";
}
}[/code]
The above method returns a bunch of Logical Outputs namely “create”, “delete”, “read” and “write”. The logical outcomes should have their Corresponding Mappings defined in the struts.xml like the following, struts.xml

[code lang=”xml”] <struts>
<action name = "MyAction" class = "myactions.MyAction">
<result name = "create">/myApp/create.jsp</result>
<result name = "delete">/myApp/delete.jsp</result>
<result name = "read">/myApp/read.jsp</result>
<result name = "write">/myApp/write.jsp</result>
</action>

</struts>[/code]

Struts.xml Configuration File

All the Configuration Related Information are externalized from a Web Application by maintaining them in a Xml File. The new Struts 2.0 Configuration Xml File is very Simple and Modular when compared with its older versions. Let us look into the structure of the Struts 2.0 Configuration File and the Core Elements within them in detail in the following sections.

Modularization of Configuration Files

The first nice feature is the File Inclusion Faciltity. Assume that in a very complex Web Application, there are multiple modules and each module is designated to be developed by a particular team. Similar to the Modularization of Work, the configuration file can also be made modular using the File Inclusion Facility. For the sake of simplicity, let the assume that there are three modules namely “admin”, “customer”, “employer” in a Web Application. We can define the three modules in three different Configuration Files,
and using the File Inclusion Facility, the three files can be directly included in the Main Configuration File. A Main Configuration File is nothing but a File that includes other Configuration Files. Examine the following code snippet,
Admin-Config.xml

[code lang=”xml”] <struts>
<!– Configuration Information Related to Admin Module –>
</struts>[/code]

Customer-Config.xml

[code lang=”xml”] <struts>
<!– Configuration Information Related to Customer Module –>
</struts>[/code]

Employee-Config.xml

[code lang=”xml”] <struts>
<!– Configuration Information Related to Employee Module –>
</struts>[/code]
All the above separate Configuration Files can be directly referenced or included in the Root Configuration File with the help of tag like the following,
Struts.xml

[code lang=”xml”] <struts>

<!– Other information goes here –>
<include file = "Admin-Config.xml"/>
<include file = "Customer-Config.xml"/>
<include file = "Employer-Config.xml"/>
<!– Other information goes here –>

</struts>[/code]

Grouping of Similar Actions inside a Package

Packages in Java are logically used to group similar Classes or Interfaces. Similary, there is a tag in Struts 2.0, which is used to Group Similar Actions along with Interceptors, Results, Exceptions etc. Following is the structure of the
package element,
Struts.xml

[code lang=”xml”] <struts>

<package name = "MyPackage1">

<interceptors>
</interceptors>

<global-results>
<global-results>

<action name = "MyAction1">
</action>

<action name = "MyAction2">
</action>

</package>

<package name = "MyPackage2">

<interceptors>
</interceptors>

<global-results>
<result name = "common-error">
/myApp/commons/commonError.jsp
</result>
<global-results>

<action name = "MyAction3">
<result name = "result1">
/myApp/myResult1.jsp
</result>
</action>

<action name = "MyAction4">
</action>

</package>

</stuts>[/code]
Assuming that MyAction1 and MyAction2 are someway related, they are grouped under a package called MyPackage1. All the declaration of Interceptors, Results and Exceptions within the Package MyPackage1 will be availabe only within the actions MyAction1 and MyAction2. Similarly all the definition of the Interceptors, Results and Exceptions within the package MyPackage2 will be applicable only for MyAction3 and MyAction4 action elements. Packages can also be extended through the means of extends attribute like the following,
Struts.xml

[code lang=”xml”] <struts>
…
<package name = "MySubPackage" extends = "MyBasePackage">
…
</package>
…
</struts>[/code]
Let us define what a Package Extension is and their advantages. Assume that there is a Package called P1 with interceptors I1 and I2, Results R1 and R2 and Exceptions E1 and E2. If we say some Package called P2 extends P1, then all the elements that are available in P1 becomes visible to Package P2. Package Extension is very similar to Class Inheritance which we normally see in any kind of Object Oriented Language.

Interceptors and Stack

As previously discussed, Custom Interceptors can be written and made immediately available in Application by configuring them in the Configuration File with the help of  tag. An Interceptor defined can be applied to a particlur Action (or a set of Actions) through the help of tag. Following Xml snippet will show this,
Struts.xml

[code lang=”xml”] <struts>

<package name = "MyPackage">

<interceptors>
<interceptor name="logger-interceptor"
class="myinterceptors.LoggingInterceptor">
</interceptor>

<action name = "MyAction">
<result name = "MyResult">
/myApp/Result1.jsp
</result>
<interceptor-ref name = "logger-interceptor"/>
</action>

</package>

</struts>[/code]
The above code defines an Interceptor called logger-interceptor identified by the class myinterceptors.LoggingInterceptor and the same is included for an action called MyAction with the help of tag. It is very common that a Set of Interceptors (often called Interceptor Stack) to be applied as a whole for one or more actions. Such a piece of functionality can be easily achieved with the help of  element.
struts.xml

[code lang=”xml”] <struts>

<package name = "MyPackage">

<interceptors>
<!–Some set of common interceptors for a particular action–>
<interceptor name = "A_I1" class = "MyA_I1">
<interceptor name = "A_I2" class = "MyA_I2">
<interceptor name = "A_I3" class = "MyA_I3">
<interceptor name = "A_I4" class = "MyA_I4">

<!–Another set of common interceptors –>
<interceptor name = "B_I1" class = "MyB_I1">
<interceptor name = "B_I2" class = "MyB_I2">
<interceptor name = "B_I3" class = "MyB_I3">
<interceptor name = "B_I4" class = "MyB_I4">
</interceptors>

<interceptor-stack name = "A">
<interceptor-ref name = "A_I1">
<interceptor-ref name = "A_I2">
<interceptor-ref name = "A_I3">
<interceptor-ref name = "A_I4">
</interceptor-stack>

<interceptor-stack name = "B">
<interceptor-ref name = "B_I1">
<interceptor-ref name = "B_I2">
<interceptor-ref name = "B_I3">
<interceptor-ref name = "B_I4">
</interceptor-stack>

<action name = "MyAction1">
<interceptor-ref name = "A"/>
</action>

<action name = "MyAction2">
<interceptor-ref name = "B"/>
</action>

</package>

</struts>[/code]
The above Xml snippet defines a series of interceptors with the help of  tag. Related Set of Interceptors to be added to an action element is then categorized with the help of  element. The categorized Interceptor Stack is then bound to an action element using the same sensible  tag. The framework is sensible here, it will find out the value for the name attribute. If the value is an interceptor name, then the corresponding intercept() method will be invoked, else if the value is an Interceptor-Stack, then all the interceptors within the stack are iterated in the same order as their definition and their intercept() method will be invoked.

Validation using Configuration Files and Annotations

Struts 2.0 comes with new set of Robust Validation Features. Most of the common Validation Activities related to a Web Application are taken care by the Framework itself which means that only less burden lies on the shoulders of a Developer. Following lists the most commonly used Validations in Struts 2.0,

  1. Integer Validation – Checks whether the value for a field is an integer and it falls
    within the integer range.
  2. Double Validation – Checks whether the value for a field is a double and it falls
    within the double range.
  3. Date Validation – Checks whether the value of the field is a Date value.
  4. Email Validation – Validates whether the input string is in appropriate email format
    (Eg: userName@someDomain.com).
  5. Url Validation – Ensures whether the value for a field is in appropriate URL Format.
  6. Required Validation – Checks for the emptiness of a field value.
  7. Required String Validation – Checks for the emptiness of a trimmed String value (not null)
  8. String Length Validation – Checks whether the given field value is of the specified length.
  9. Regex Validation – Ensures whether the field Value given matches the Regular Expression.

5.1) Validations Types based on Scope

Validation comes in two different flavors based on its Scope. A Scope defines whether a Validation is dedicated to a Single Field in a Page or it corresponds to a particular Action which may involve more than one fields along with some other constraints. Based on this, the following types are available.

  • Field Validation
  • Non-Field Validation

5.1.1) Field Validation

Validating a Field in a Page for correctness is a common situation for almost any Web Application. As mentioned this type of Validation is restricted to a particular field. Common cases may be validating the username and password field for emptiness. Both Xml-Based Validation or Annotation-Based Validation can be mentioned for the field elements. The following snippet code is an example of Field-Level Validation.
validation.xml

[code lang=”xml”] <field name="username">
<field-validator type="required">
<message>User name cannot be empty.</message>
</field-validator>
<field-name="username">

<field name="email_address">
<field-validator type="required">
<message>Email Address cannot be empty.</message>
</field-validator>

<field-validator type="email">
<message>
Enter the email id in proper format (eg: abc.def@xyz.com)
</message>
</field-validator>
</field>[/code]
The above Xml snippet essentially applies one Validation Rule to the username field and two Validation Rules to the email-address field. The type of the validation rule is specified by the attribute called type. In our case, the types represent the Required Validation (required) and the EMail Validation (email). Any number of validation rules can be attached to a field element with the help of  tag. Annotation-Based Validation for a field is also possible. The only requirement for the class is that the class that contains the fields representing the page (it can be an Action class too) must be marked with the @Validation annotation. Assume the Validation has to take place when the user submits the form. It is known that the Action.execute() method will be invoked as a result of this. So we can perform the field validations by marking the necessary Annotations against the method.
MyAction.java

[code lang=”java”] package myactions;

import com.opensymphony.xwork2.validator.annotations.*;

@Validation
public class MyAction{

@Validations(
emails = {
@EmailValidator(type = ValidatorType.SIMPLE,
fieldName = "email_address",
message = "Enter the email id in proper format (eg: abc.def@xyz.com)")
}

requiredFields = {
@RequiredFieldValidator(type = ValidatorType.SIMPLE,
fieldName = "email_address",
message = "Email Address cannot be empty.")},

@RequiredFieldValidator(type = ValidatorType.SIMPLE,
fieldName = "username",
message = "User name cannot be empty.")}
}
)
public String execute(){
// Other Logic goes here..
}

}[/code]
Instead of marking the whole Bunch of Validations on the Action.execute method(), there is another alternate way wherein which the Annotation-Based Validation can be applied on a Field-by-Field basis. Assume that username and password are the two properties inside the Action class, then the following type of Annotation is also possible.
MyAction.java

[code lang=”java”] package myactions;

import com.opensymphony.xwork2.validator.annotations.*;

public class MyAction{

private String username;
private String emailAddress;

@RequiredFieldValidator(type = ValidatorType.SIMPLE,
fieldName = "username",
message = "User name cannot be empty.")
public String getUsername(){
return username;
}

…

@RequiredFieldValidator(type = ValidatorType.SIMPLE,
fieldName = "email_address",
message = "Email Address cannot be empty.")
@EmailValidator(type = ValidatorType.SIMPLE,
fieldName = "email_address",
message = "Enter the email id in app. format(eg: abc.def@xyz.com)")
public String getEmailAddress(){
return emailAddress;
}
}[/code]

5.1.2) Non-Field Validation

Non-Field Validations are generally Application specific and they will be given implementation by the Application Developers. Example may be performing validations based one or more fields in a form along with some Application specific Business Logic. The only availabe Validation that comes along with Struts 2.0 in this category is the Expression Validation. Assume that in some Application an Employee is asked to enter his Dirth of Birth and the Joining Date. For sure, the Birth Date will be logically lesser than the Joining Date. We can enforce this kind of Validation Rule using Expression Validation as follows.
validation.xml

[code lang=”xml”] <field name = "date_of_birth">
</field>

<field name = "joining_date">
</field>

<validator type = "expression">
<param name="expression">
date_of_birth lt joining_date
</param>
<message>
Warning: DOB(${date_of_birth}) is greater than Joining Date(${joining_date})
</message>
</validator>[/code]
The first noticeable thing in the above Xml snippet is that the type of the Validation is identified as expression. The param tag is used to specify the constraint to be applied for the Validation. Here the constraint is very simple which tells that the Date of Birth for an Employee must be lesser that his Joining Date in the Organisation. Also notice, how actually the value of the field is taken to display error messages ($field_name). If the user enters 10/10/2000 for the DOB field and 10/10/1960 in the Joining Date Field, then the message “Warning: DOB(10/10/2000) is greater than the Joining Date(10/10/1960)” will be flashed in the User Browser.

Validation Types based on Implementation

If we look at another angle based on how Validations are Configured or Implemented, they can be classified into two categories namely,

  • Declarative Validation
  • Programmtic Validation.

Declarative Validation

If the Validation Logic for a particular Field or for an Entire Action is specified either in the Xml File or through Annotations, then it is called Declarative Validation. Whatever Validation we are seeing till now are Declarative Validations only. The idea behind Declarative Validation is that during the Deployment time of the Web Application itself, the Framework or the Container will be in a suitable position to map the set of fields participating in Validations against their Validation Rules.

Programmatic Validation

Not at all times, the Built-in Validations provided by the Framework will be sufficient. At times, there will be a situation to perform a Complex Validation Logic that is very specific to an application. For example situation may occur wherein, a single value of a field can be validated based on the content of some other text-fields along with some values fetched from the Database. In such a case, we can implement the Validation Logic directly into the Code. The following code snippet shows that,
MyAction.java

[code lang=”java”] package myactions;

import com.opensymphony.xwork2.*;

public class MyAction extends ActionSupport{

public void validate(){
String stockSymbol = getStockFieldValue();

if ((stockSymbol == null) || (stockSymbol.trim().length == 0) ){
addFieldError("stock_field", "Stock Symbol cannot be empty");
}

boolean result = validateStockSymbolFromDb(stockSymbol);
if (!result){
addActionError("Invalid Stock Symbol");
}
// Other Code goes here.
}
}[/code]
If an Application is going to provide Manual Validation, then it has to implement two interfaces namely Validateable and ValidationAware interfaces in the com.opensymphony.xwork2 package. The core logic for the Custom Validation must be done within the Validateable.validate() method. ValidationAware Interface is used to collect the Error Messages that are related to fields or to a general Action. Fortunately, as expected, Struts 2.0 provides Default Implementation for both these interfaces in the
ActionSupport class. So it is wise to extend this class for performing any Validation Logic without redefining every methods available in the Validation Interfaces.

Our sample Action class extends ActionSupport class to get all the Basic functionality for Storing and Retrieving Error Messages. Two types of Error Messages are available in the ValidationAware interface. One is the Field-level Messages and the other thing is the Action-Level Messages. Convinient methods are available for populating and retreiving both these messages. Methods addActionError(String message) and addFieldMessage(String fieldName, String message) are used to populate the error messages to an internal Collection. To retrive the Error Messages getActionErrors() and getFieldErrors() are used. To check whether errors have occured in a page use hasActionErrors() and hasFieldErrors() methods.

The sample code essentially checks the value of the stock symbol obtained from the field and checks for its emptiness. If not, it is populating the field-level error message by calling the addFieldMessage("..."). It then make Database Calls to ensure whether the Stock Symbol is valid. If not, an Action Level Error message is populated in the code by calling addActionEror("...");

Conclusion

Though Struts 2.0 has more new features to its credit, this article just provides only the basic piece of information. It walked-through about how Struts 2.0 fits into the Bigger MVC2 Architecture. Then the Flow of the Client Request into the Struts Framework is explained in detail. Following that, some samples regarding the structure of a Struts Configuration File. Then the second section primarily focusses on the new Struts Validation Features with the various types of Validations that can be performed on field components.

Filed Under: Struts Tagged With: Struts 2.0

What’s new in Struts 2.0? – Struts 2.0 Framework

April 12, 2007 by Krishna Srinivasan Leave a Comment

Introduction

In this article we will talk about the new features in Struts 2.0. Over the years, every developers believes that struts is the best and simple framework to implement. Since last two years, more new frameworks come to the market and the use of Struts is declined. Lack of updation in the Struts framework is the main reason for developers choosing alternative framework. To answer this, Struts team comes with the Struts 2.0, an integration of Struts 1.0 with Webwork. Here we will look into the prominent features in the new framework.

also read:

  • Struts 2 Tutorials
  • Struts Interview Questions
  • Struts and Spring Integration

Action classes

An Struts 2 Action may implement an Action interface, along with other interfaces to enable optional and custom services. Struts 2 provides a base ActionSupport class to implement commonly used interfaces. Albeit, the Action interface is not required. Any POJO object with a execute signature can be used as an Struts 2 Action object.

Threading Model

Struts 2 Action objects are instantiated for each request, so there are no thread-safety issues. (In practice, servlet containers generate many throw-away objects per request, and one more object does not impose a performance penalty or impact garbage collection.)

Testability

Struts 2 Actions can be tested by instantiating the Action, setting properties, and invoking methods. Dependency Injection support also makes testing simpler.

Servlet Dependency

Struts 2 Actions are not coupled to a container. Most often the servlet contexts are represented as simple Maps, allowing Actions to be tested in isolation. Struts 2 Actions can still access the original request and response, if required. However, other architectural elements reduce or eliminate the need to access the HttpServetRequest or HttpServletResponse directly.

Harvesting Input

Struts 2 uses Action properties as input properties, eliminating the need for a second input object. Input properties may be rich object types which may have their own properties. The Action properties can can be accessed from the web page via the taglibs. Struts 2 also supports the ActionForm pattern, as well as POJO form objects and POJO Actions. Rich object types, including business or domain objects, can be used as input/output objects. The ModelDriven feature simplifies taglb references to POJO input objects.

Expression Language

Struts 2 can use JSTL, but the framework also supports a more powerful and flexible expression language called “Object Graph Notation Language” (OGNL).

Binding values into views

Struts 2 uses a “ValueStack” technology so that the taglibs can access values without coupling your view to the object type it is rendering. The ValueStack strategy allows reuse of views across a range of types which may have the same property name but different property types.

Type Conversion

Struts 2 uses OGNL for type conversion. The framework includes converters for basic and common object types and primitives.

Validation

Struts 2 supports manual validation via the validate method and the XWork Validation framework. The Xwork Validation Framework supports chaining validation into sub-properties using the validations defined for the properties class type and the validation context.

Control Of Action Execution

Struts 2 supports creating different lifecycles on a per Action basis via Interceptor Stacks. Custom stacks can be created and used with different Actions, as needed.

Filed Under: Struts Tagged With: Struts 2.0

Introductiion to Jakarta Struts

April 12, 2007 by Krishna Srinivasan Leave a Comment

Introduction

This article explores the Struts framework in depth and highlights the benefits Struts can bring to your development efforts. We believe that once you can “talk the talk” of web architecture and design, you will be better equipped to use Struts with your own applications.
With a sound overview of the Struts architecture in place, we outline the Struts control flow and the way it handles the request-response event cycle. A good understanding of this process makes it much easier to create applications that make the best use of the framework.

also read:

  • Struts 2 Tutorials
  • Struts Interview Questions
  • Struts and Spring Integration

Choosing a web application framework should not be a casual decision. Many people will use this book, and especially this chapter, as part of evaluating Struts for their project. Accordingly, we conclude this chapter with a candid look at the strengths and weaknesses of the Struts framework and address concerns regarding overall performance. Struts is designed for professional developers. To make informed decisions, professionals need to be aware of both a tool’s capabilities and its limitations.

A Greatt Desiign Pattttern – MVC

Part of MVC triad

A Model in MVC terms is a presentation-neutral arbiter of data. This data then can be tailored to support a given presentation, or tailored to represent application-specific data structures.

A View is a presentation-specific way of displaying data from a Model. There is a relationship between a Model and View such that changes in a Model are automatically reflected in any Views attached to it, and changes in the View-presented data are automatically pushed back to associated Models.

The controller coordinates activity Model and View, and for the application as a whole. Whereas Model and View can frequently be instances of off-the-shelf types, Controllers are typically custom written to an application.

Fig 1, below depicts MVC design pattern. Here all different types of flows have been depicted, which whenever separated can lead to different implementations of MVC.

 

Types of MVC

MVC1 (Page-centric Architecture): There is no clear distinction between view and a controller. In Java terms, there is JSP page (view and partial controller) which itself controls Business logic (Model) that is why it is also called as page-centric architecture. Fig 2 below shows MVC1 implementation.

 

MVC2 (Servlet-centric architecture): MVC2 incorporates a clear separation of view and controller. A controller receives all the requests, retrieves data from a Model and forwards it to next view for presentation.

In Java terms, there is a central Servlet (Controller) which calls business logic (Model) and the forwards it particular JSP page (View) that is why it is also called servlet-centric architecture. Diagram below depicts MVC2 implementation.

 

Struts – An implementatiion of MVC2

As discussed in the previous section about MVC2, there is central controller associated with all views and models. Similarly, Struts has central controller called as ActionServlet, which receives requests from all the JSP Pages (View) and forwards them to appropriate Model called as Action and vice versa. To put it in Struts framework terms, org.apache.struts.action.ActionServlet is the backbone of all Struts applications. It is the main Controller that handles client request and determines which org.apache.struts.action.Action to call to process each received
request. This logic of associating a client request to particular Action, an ActionServlet takes from a configuration file called strus-config.xml.

Fig 3 below shows how Struts framework is the prefect implementation of MVC2.

Why Struts

Today’s web applications are critical components of the corporate mission. As always, development teams need to build applications in record time, but they have to build them right and build them to last.

Java web developers already have utilities for building presentation pages, such as JavaServer Pages and Velocity templates. We also have mechanisms for handling databases—JDBC and Enterprise JavaBeans (EJBs), for example. But what do we use to put these components together? We have the plumbing and the drywall … what else do we need?

One step back, three steps forward

In the late 1970s, when graphical user interfaces (GUIs) were being invented, software architects saw applications as having three major parts: the part that manages data, the part that creates screens and reports, and the part that handles interactions between the user and the other subsystems [Ooram]. In the early 1980s, the ObjectWorks/Smalltalk programming environment introduced this triumvirate as a development framework. In Smalltalk 80 parlance, the data system is dubbed the Model, the presentation system is called the View, and the interaction system is the Controller. Many modern development environments, including Java’s Swing, use this Model/View/Controller (MVC) architecture as the foundation of their own frameworks.

Java web developers already have capable tools, such as JDBC and JSP, for consulting the Model and creating the View, but where’s the Controller for our web applications?

Enter Struts

The centerpiece of Struts is an MVC-style Controller. The Struts Controller bridges the gap between Model and View. The framework also includes other missing pieces developers need to write scalable, leading-edge web applications. Struts is a collection of “invisible underpinnings” that help developers turn raw materials like databases and web pages into a coherent application.

A Big Picture

Figure lays out the Struts request-response process in a visual sequence. Let us walk through a description of the request-response. The numbers in parentheses refer to figure 5 where appropriate:

  • A client requests a path that matches the Action URI pattern (1).
  • The container passes the request to the ActionServlet.
  • If this is a modular application, the ActionServlet selects the appropriate module.
  • The ActionServlet looks up the mapping for the path.
  • If the mapping specifies a form bean, the ActionServlet sees if there is one already or creates one.
  • If a form bean is in play, the ActionServlet resets and populates it from the HTTP request.
  • If the mapping has the validate property set to true, it calls validate on the form
    bean .
  • If it fails, the servlet forwards to the path specified by the input property and this control flow ends.
  • If the mapping specifies an Action type, it is reused if it already exists or instantiated
  • The Action’s perform or execute method is called and passed the instantiated form bean (or null).
  • The Action may populate the form bean, call business objects, and do whatever else is needed.
  • The Action returns an ActionForward to the ActionServlet.
  • If the ActionForward is to another Action URI, we begin again; otherwise, it’s off to a display page or some other resource. Most often, it is a JSP, in which case Jasper, or the equivalent (not Struts), renders the page.

Struts….. fine–tuned further

The devil, as they say, is in the details. The synopsis and diagram in the prior sections do a good job of outlining the big picture but omit important details. Let’s drill down now and visit the finer points. Since this is HTTP, everything starts with an incoming request.

Request is received by our container

The backbone component of the Struts framework is the ActionServlet. Like all servlets, it lives in a container, such as Tomcat, Resin, or WebLogic. When the container boots, it reads a deployment descriptor (web.xml) that tells it which servlets to load. One of the standard servlet settings is the servlet mapping. The container uses this setting to decide which requests are sent to which servlet:
[code lang=”xml”] <servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>/do/*</url-pattern>
</servlet-mapping>[/code]
Here, we have asked the container to give our ActionServlet any request that matches the pattern /do/*. That would include /do/This or /do/That and /do/ something/Whatever.Many applications like to use suffix mapping instead:
[code lang=”xml”] <servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.*.do/url-pattern>
</servlet-mapping>[/code]
This URL pattern would likewise match this.do or that.do or /something/whatever.do. Any valid extension or prefix can be used; .do is simply a popular choice. When a request comes in with a path component that matches our servlet context, the container forwards it to our ActionServlet. Requests that do not match our pattern are not sent to the ActionServlet. A request matching *.jsp, for example, would be forwarded to the container’s JSP service, such as Jasper if you are using Tomcat or WebSphere. There may be other servlets in your applications that handle other patterns. Any pattern that does not match a servlet mapping is sent to the container’s default web server.

Request is received by our ActionServlet

When our ActionServlet receives a request, it runs the request through a gauntlet that processes the locale, mapping, form bean, and finally the Action. Some of these steps apply only to Struts 1.1 applications:

Process MultipartRequest. If this is a multipart request (a form with a Multipurpose Internet Mail Extension [MIME] attachment), the servlet wraps the request with a special handler, to avoid errors later in the process.

Process Path. The ActionServlet checks to see if this path is for an application module. If so the configuration for the appropriate module is selected. [Struts 1.1] Process Locale. By default, the ActionServlet will check to see if there is a standard locale object in the user’s session. If there is no locale object, the ActionServlet will put one there. This object can be used to provide a localized presentation for each user. Process Content and NoCache. The default MIME type and optional request headers are added to the response.

Process Mapping. The ActionServlet checks the ActionMappings for a mapping keyed to a path that matches the one we are processing. If one is not found, the ActionServlet forwards to the default (or “unknown”) Action, if one has been set, or generates a “bad request” error. If the mapping is found, it is placed into the request for future reference.
Process Roles. The ActionServlet checks to see if the user is authorized to access this action. [Struts 1.1]

Process ActionForm. The ActionServlet checks whether the mapping specifies an ActionForm. If it does, the servlet checks to see if one already exists in the specified scope. (The default is session.) If one does not exist, the ActionServlet creates one.

Process Populate. The ActionForm’s reset method is called, and then it is auto populated via reflection. Parameters that match the ActionForm’s properties are applied. Other parameters and properties are ignored.

Process Validate. The ActionForm’s validate method is called. If the method returns false, control is passed to the input property specified on the mapping, and the Action is not processed.

Process Forward or Include. If the ActionMapping specifies the forward or include attribute, control is transferred to another resource. Otherwise, the ActionServlet delegates the request to an Action object.

Process Action. If the mapping specifies an Action type, the servlet checks to see if one has already been instantiated. If it does not find one, the Action object is instantiated. There is only one Action object per class (the Singleton pattern), which handles all the requests for that Action through multithreading. The servlet calls the Action’s perform or execute method, passing the request, response, mapping, and any form bean. The Action executes whatever behavior is required, which may include:

Accessing a data system, such as a JDBC database

      • Creating objects in the request to be used by the view
      • Creating objects in the user session, if required
      • Updating session objects, such as the user’s locale, as needed
      • Performing any other business function required by the application
      • Handling exceptions and other error conditions
      • Sending a direct response or (most often) returning an ActionForward to
        the servlet

A business object that is invoked by the Action (the Business Delegate pattern) often handles some of this behavior, like accessing a database. The Action is there to handle any web-specific tasks, but any code that can be placed in a business object should be placed in a business object. The Action is a Controller class and should not be used to
handle your application’s core business logic.

The Action returns an ActionForward

When the Action completes, it returns an ActionForward. If the ActionForward is null, the ActionServlet assumes the response has been generated and does nothing. Otherwise, the ActionServlet reads the ActionForward and either redirects or forwards the request as appropriate.

If the request is another Action URI, the container will return the request to the ActionServlet. Otherwise, the container sends the request to another servlet or service. If the ActionForward is set for redirect, the request is sent back to the client with instructions to submit a new request to the specified location.

Jasper (or equivalent) renders a JavaServer Page

When the ActionServlet sends a request to a JSP, the request is handled by another service, such as Jasper. Typically, the Struts and other tag extensions are used to write the dynamic portions of the page. Sometimes a JSP template may be used so that the page is built up from other components. Most often, the dynamic data is passed to the page in the request context in a JavaBean. This is known as the View Helper pattern [Go3]. The tag extensions simply call methods on the JavaBeans that return the formatted data. How data is positioned on a page is considered part of the presentation logic. The format of the data itself is usually part of the business logic, so it is delegated to the bean. The Struts tags may also access view helpers provided by the framework. These include localized labels and prompts, error messages, and hyperlink paths. In addition, Struts tags can evaluate expressions, iterate through lists, and populate the controls in an HTML form.

Another servlet renders the response

After processing an Action, the request can be sent to any other servlet or service in the application. Other presentation systems, such as Velocity templates, can access framework resources through the servlet contexts.

Summary

Today’s developers need to build full-featured applications that can be maintained over time. Web application frameworks such as Struts solve common problems, so developers can focus on their application’s unique functionality. Frameworks are especially important when building web applications since the way HTTP and HTML work makes creating dynamic applications difficult.

Struts makes the most of the standard Java servlet API and has even become an informal compliance test for servlet containers. Struts also builds on the common design patterns, especially the MVC architectural paradigm. The framework encourages a “layered” design for applications. This design helps make applications both robust and scalable. A key part of the Struts architecture is the way it extends the flow of the base HTTP request-response cycle. The Struts controller manages the paths used by your application, helps to safely collect input from users, and can localize application messages— especially error messages. Struts is a performant solution. It will not hold your application back and usually frees resources that can be better used elsewhere. Of course, Struts has its flaws. Many of the classnames were hastily chosen during development and can be confusing; other areas could also be improved. Despite any drawback, Struts is easily the most popular web application framework available today.

Filed Under: Struts Tagged With: Struts Basics

  • « Previous Page
  • 1
  • …
  • 6
  • 7
  • 8

Follow Us

  • Facebook
  • Pinterest

As a participant in the Amazon Services LLC Associates Program, this site may earn from qualifying purchases. We may also earn commissions on purchases from other retail websites.

JavaBeat

FEATURED TUTORIALS

Answered: Using Java to Convert Int to String

What is new in Java 6.0 Collections API?

The Java 6.0 Compiler API

Copyright © by JavaBeat · All rights reserved