web.xml
Filestruts.xml
FileSo far, we know how to make a web app using servlet classes and JSP files, and we know how to use libaries in our code. We’ve built our web apps using the following approach:
web.xml
file maps URLs to servlet classes.doGet()
and doPost()
functions to handle requests.This approach will work, and if you’re happy with this setup, that’s completely okay! You don’t need to learn about Struts or other frameworks to get stuff working. But if you’re annoyed by things like parsing multiple URLs to handle them in the same servlet class or sharing data between servlets, or if you’re planning on working on a bigger professional project, then you might want to learn about frameworks like Struts.
A software framework is code that was written by other people, that you can use to help organize your own code. If you think that sounds similar to a software library, you aren’t wrong! There is a blurry line between what counts as a framework versus what counts as a library, but the way I look at it is:
If you’re using a library, you’re still using the overall setup and flow of whatever language you’re programming in: you’re using a main()
method, or a servlet class with a doGet()
function, for example. Compare that to a framework, which sits in between the underlying flow of the language and your code. So instead of writing your code inside a doGet()
function, you’ll write your code inside whatever function the framework provides. That’s probably a little confusing right now, but hopefully it will make more sense by the end of this tutorial, which introduces a framework called Struts.
A Struts web app looks like this:
stuts.xml
file maps URLs to action classes.The idea is that Struts allows us to simplify our code, because we don’t have to deal with the “low level” URL mapping and servlet classes.
Go to the Struts download page and download the latest version of Struts. You only need the “Essential Dependencies” version. That gives you a .zip
file, which you can unzip anywhere. (I put mine on my desktop for now.)
By now you’re probably pretty familiar with this step. Either create a directory for your web app (if you’re using the command line to compile and run stuff), or create a project in Eclipse. Copy the .jar
files from the folder you just unzipped into the WEB-INF/libs
folder of your web app directory, like we covered in the libraries tutorial.
web.xml
FileNext, we need to write a web.xml
file that tells our server to let the Struts framework handle all of the requests:
<web-app
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
This sets up a filter that sends every URL to the Struts framework. This is how Struts “sits between” the server and your code. Now when the server receives a request, it will send that request to Struts, and Struts will then send it to our action classes, which we’ll talk about… right now.
Instead of servlets, Struts uses action classes that allow you to write code that runs when the server receives a request from a user. Here’s an example action class:
import com.opensymphony.xwork2.ActionSupport;
public class HelloWorldAction extends ActionSupport{
private String messageToDisplay;
@Override
public String execute(){
messageToDisplay = "Happy coding!";
return ActionSupport.SUCCESS;
}
public String getMessage(){
return messageToDisplay;
}
}
This class extends the ActionSupport
class, similar to how a servlet extends the HttpServlet
class. It overrides the execute()
function, which Struts automatically calls when it receives a request. This function contains any “business logic” required to fulfill a request, and it returns a String
value. In this case, it returns the predefined ActionSupport.SUCCESS
value, which behind the scenes is a value of "success"
but could be anything you want. This helps Struts know which view to show, which we’ll see in a second.
This also defines a getMessage()
function, which you can use from a JSP view. More on that in a second.
It’s also worth noting that with a servlet class, you only ever have one instance of a class, which is called from multiple threads. But in Struts, a new instance of your action class is created for every request. (Hint: try to add a visitCount
variable to your action class that you increment every time the page is loaded.)
Notice that our action class doesn’t render any HTML. This is because we should use a JSP file to render HTML. Here’s an example JSP file:
hello.jsp
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html>
<html>
<head>
<title>Hello World Struts</title>
</head>
<body>
<h1>Hello World</h1>
<p><s:property value="message" /></p>
</body>
</html>
Hopefully you’re already familiar with JSP (if not check out the JSP tutorial), but this code contains a couple new things:
First, the <%@ taglib prefix="s" uri="/struts-tags"%>
line imports the Struts taglib, which gives us extra Struts functionality in JSP. We then use that taglib in the <s:property value="message" />
line. This property
tag looks for a function named getXYZ()
, where XYZ
is whatever you supply in the value
attribute. In other words, this tag ends up calling the getMessage()
function in our action class. This allows us to separate our logic from our view, while still easily passing data to be rendered.
There are a bunch of other Struts tags you can use in your JSP files. Read more about them here.
struts.xml
FileFinally, we need to map the requests that Struts receives to the action classes and JSP views we want to use. We do that using a struts.xml
file, which is a little bit like the web.xml
file except it tells Struts what to do.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<package name="helloworld" namespace="/" extends="struts-default">
<action name="hello" class="HelloWorldAction">
<result name="success">WEB-INF/jsp/hello.jsp</result>
</action>
</package>
</struts>
This might seem confusing at first, but let’s take it piece by piece:
<struts>
is the top-level element that will contain other elements.<package>
defines a group of action classes. How you group them is up to you.name
allows you to name your group. This can be anything you want.namespace
specifies the first part of the URL to map. In this case we’re using /
, which means our URLs are relative to the top of our domain.extends
tells Struts to hook up its default behaviors to our code.<action>
maps an action class to a URL.name
specifies the rest of the URL, which it combines with the namespace
attribute to create a URL to map. In this case the URL will be /hello
.class
specifies the action class whose execute()
function should be called when a user requests the mapped URL.<result>
tells Struts which JSP view should be rendered depending on what value is returned from the execute()
function.name
maps to a value returned from the execute()
function. This matches the value in our action class.<result>
tag specifies a path to a JSP file that should be used to render the view when the action class returns a value that matches the name
attribute.Your struts.xml
file can contain multiple <package>
elements, which can contain multiple <action>
elements, which can contain multiple <result>
elements. When a request is made, Struts finds the action class that matches the URL, and calls its execute()
function. It then finds the result that matches the value returned from that function, and renders the view using that JSP file.
The struts.xml
file needs to be in the same directory as your code, not in the top of the WEB-INF
folder! So if you’re using the console to compile everything, it should be in the classes
directory; and if you’re using Eclipse then it should be in the src
directory.
Now we should be able to run our web app just like we’ve been running all of our other web apps. If you’re using the console, then copy the web app directory into the Jetty folder. If you’re using Eclipse, then just push the run button.
When we visit http://localhost:8080/hello, we should see this:
This tutorial introduced you to the basics of using Struts. My goal was to give you just enough background so you can start doing your own research into using the more advanced features that Struts offers. The Struts website contains a ton of guides that you’re now ready to read through.
Struts acts as a “middle man” between your code and the underlying Java EE code. The idea is that Struts should make it easier to do stuff, but it also requires you to “think in Struts” when writing code. For example, Struts has its own way of doing things: getting form input, handling sessions, etc. This can be a bit of a “re-learning” process, where you have to figure out “the Struts way” of doing something.
In the end it’s up to you whether you want to keep using servlet classes or use a framework like Struts.
Learn how to use the Struts framework to make advanced web apps.
Happy Coding is a community of folks just like you learning about coding.
Do you have a comment or question? Post it here!
Comments are powered by the Happy Coding forum. This page has a corresponding forum post, and replies to that post show up as comments here. Click the button above to go to the forum to post a comment!