第一节 需求定义
简单的需求如下图
<group id="_x0000_s1026" style="WIDTH: 423pt; HEIGHT: 405pt; mso-position-horizontal-relative: char; mso-position-vertical-relative: line" coordsize="8460,8100" coordorigin="1702,1985" editas="canvas"><lock aspectratio="t" v:ext="edit"></lock><shapetype id="_x0000_t75" coordsize="21600,21600" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><shape id="_x0000_s1027" style="LEFT: 1702px; WIDTH: 8460px; POSITION: absolute; TOP: 1985px; HEIGHT: 8100px" stroked="t" o:preferrelative="f" type="#_x0000_t75"><fill o:detectmouseclick="t"></fill><path o:connecttype="none" o:extrusionok="t"></path><lock v:ext="edit" text="t"></lock></shape></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><shapetype id="_x0000_t202" coordsize="21600,21600" path="m,l,21600r21600,l21600,xe" o:spt="202"><stroke joinstyle="miter"></stroke><path o:connecttype="rect" gradientshapeok="t"></path></shapetype><shape id="_x0000_s1028" style="LEFT: 1702px; WIDTH: 8280px; POSITION: absolute; TOP: 7925px; HEIGHT: 1800px" stroked="f" type="#_x0000_t202"><textbox inset="5.85pt,.7pt,5.85pt,.7pt"><table cellspacing="0" cellpadding="0" width="100%"><tbody><tr> <td style="BORDER-LEFT-COLOR: #d4d0c8; BORDER-BOTTOM-COLOR: #d4d0c8; BORDER-TOP-COLOR: #d4d0c8; BACKGROUND-COLOR: transparent; BORDER-RIGHT-COLOR: #d4d0c8"> <div> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US" style="FONT-FAMILY: 宋体">1</span><span lang="EN-US" style="mso-fareast-font-family: 宋体"><font face="Garamond"> </font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Garamond; mso-hansi-font-family: Garamond">用户处在</span><span lang="EN-US" style="mso-fareast-font-family: 宋体"><font face="Garamond">Welcome.jsp </font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Garamond; mso-hansi-font-family: Garamond">页面,点击登录连接到达</span><span lang="EN-US" style="mso-fareast-font-family: 宋体"><font face="Garamond">Login.jsp</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Garamond; mso-hansi-font-family: Garamond">页面</span><span lang="EN-US" style="mso-fareast-font-family: 宋体"><p></p></span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US" style="mso-fareast-font-family: 宋体"><font face="Garamond">2 </font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Garamond; mso-hansi-font-family: Garamond">在</span><span lang="EN-US" style="mso-fareast-font-family: 宋体"><font face="Garamond">Login.jsp</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Garamond; mso-hansi-font-family: Garamond">输入用户名密码,点击登陆按钮,转到</span><span lang="EN-US" style="mso-fareast-font-family: 宋体"><font face="Garamond">LoginAction</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Garamond; mso-hansi-font-family: Garamond">处理</span><span lang="EN-US" style="mso-fareast-font-family: 宋体"><p></p></span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US" style="mso-fareast-font-family: 宋体"><font face="Garamond">3.1 </font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Garamond; mso-hansi-font-family: Garamond">在登陆成功的情况下,再回到</span><span lang="EN-US" style="mso-fareast-font-family: 宋体"><font face="Garamond">Welcome.jsp</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Garamond; mso-hansi-font-family: Garamond">页面,在页面上显示登录信息</span><span lang="EN-US" style="mso-fareast-font-family: 宋体"><p></p></span></font></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US" style="mso-fareast-font-family: 宋体"><font face="Garamond">3.2 </font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Garamond; mso-hansi-font-family: Garamond">在登陆失败的情况下,返回到</span><span lang="EN-US" style="mso-fareast-font-family: 宋体"><font face="Garamond">Login.jsp</font></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: Garamond; mso-hansi-font-family: Garamond">显示登陆错误信息</span><span lang="EN-US" style="mso-fareast-font-family: 宋体"><p></p></span></font></p> </div> </td> </tr></tbody></table></textbox></shape><group id="_x0000_s1029" style="LEFT: 2962px; WIDTH: 6299px; POSITION: absolute; TOP: 1985px; HEIGHT: 5581px" coordsize="6299,5581" coordorigin="2962,1985"><group id="_x0000_s1030" style="LEFT: 2962px; WIDTH: 6299px; POSITION: absolute; TOP: 1985px; HEIGHT: 5581px" coordsize="6299,5581" coordorigin="2962,1985"><group id="_x0000_s1031" style="LEFT: 2962px; WIDTH: 1979px; POSITION: absolute; TOP: 2885px; HEIGHT: 1981px" coordsize="1685,1697" coordorigin="2741,8106"><rect id="_x0000_s1032" style="LEFT: 2741px; WIDTH: 1685px; POSITION: absolute; TOP: 8106px; HEIGHT: 1697px" alt=""><textbox inset="5.85pt,.7pt,5.85pt,.7pt"><font size="3"></font></textbox></rect><shape id="_x0000_s1033" style="LEFT: 2894px; WIDTH: 1378px; POSITION: absolute; TOP: 8415px; HEIGHT: 308px" stroked="f" type="#_x0000_t202"><textbox style="mso-next-textbox: #_x0000_s1033" inset="5.85pt,.7pt,5.85pt,.7pt"><table cellspacing="0" cellpadding="0" width="100%"><tbody><tr> <td style="BORDER-LEFT-COLOR: #d4d0c8; BORDER-BOTTOM-COLOR: #d4d0c8; BORDER-TOP-COLOR: #d4d0c8; BACKGROUND-COLOR: transparent; BORDER-RIGHT-COLOR: #d4d0c8"> <div> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-FAMILY: 宋体"><font size="3">Welcome.jsp</font></span></p> </div> </td> </tr></tbody></table></textbox></shape></group><group id="_x0000_s1034" style="LEFT: 7282px; WIDTH: 1979px; POSITION: absolute; TOP: 2885px; HEIGHT: 1981px" coordsize="1684,1698" coordorigin="5498,8106"><rect id="_x0000_s1035" style="LEFT: 5498px; WIDTH: 1684px; POSITION: absolute; TOP: 8106px; HEIGHT: 1698px"><textbox inset="5.85pt,.7pt,5.85pt,.7pt"><font size="3"></font></textbox></rect><shape id="_x0000_s1036" style="LEFT: 5651px; WIDTH: 1378px; POSITION: absolute; TOP: 8415px; HEIGHT: 308px" stroked="f" type="#_x0000_t202"><textbox style="mso-next-textbox: #_x0000_s1036" inset="5.85pt,.7pt,5.85pt,.7pt"><table cellspacing="0" cellpadding="0" width="100%"><tbody><tr> <td style="BORDER-LEFT-COLOR: #d4d0c8; BORDER-BOTTOM-COLOR: #d4d0c8; BORDER-TOP-COLOR: #d4d0c8; BACKGROUND-COLOR: transparent; BORDER-RIGHT-COLOR: #d4d0c8"> <div> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-FAMILY: 宋体"><font size="3">Login.jsp</font></span></p> </div> </td> </tr></tbody></table></textbox></shape></group><group id="_x0000_s1037" style="LEFT: 3862px; WIDTH: 4320px; POSITION: absolute; TOP: 1985px; HEIGHT: 900px" coordsize="3217,771" coordorigin="4119,7952"><line id="_x0000_s1038" style="POSITION: absolute; flip: y" from="4119,8261" to="4119,8723"><font size="3"></font></line><line id="_x0000_s1039" style="POSITION: absolute" from="4119,8261" to="7336,8261"><font size="3"></font></line><line id="_x0000_s1040" style="POSITION: absolute" from="7336,8261" to="7336,8723"><stroke endarrow="block"><font size="3"></font></stroke></line><shape id="_x0000_s1041" style="LEFT: 5038px; WIDTH: 1074px; POSITION: absolute; TOP: 7952px; HEIGHT: 309px" stroked="f" type="#_x0000_t202"><textbox style="mso-next-textbox: #_x0000_s1041" inset="5.85pt,.7pt,5.85pt,.7pt"><table cellspacing="0" cellpadding="0" width="100%"><tbody><tr> <td style="BORDER-LEFT-COLOR: #d4d0c8; BORDER-BOTTOM-COLOR: #d4d0c8; BORDER-TOP-COLOR: #d4d0c8; BACKGROUND-COLOR: transparent; BORDER-RIGHT-COLOR: #d4d0c8"> <div> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US" style="FONT-FAMILY: 宋体">1 </span><span style="FONT-FAMILY: 宋体">开始登陆</span><span lang="EN-US" style="mso-fareast-font-family: 宋体"><p></p></span></font></p> </div> </td> </tr></tbody></table></textbox></shape></group><rect id="_x0000_s1042" style="LEFT: 4942px; WIDTH: 1980px; POSITION: absolute; TOP: 5585px; HEIGHT: 1981px"><textbox inset="5.85pt,.7pt,5.85pt,.7pt"><font size="3"></font></textbox></rect><group id="_x0000_s1043" style="LEFT: 6922px; WIDTH: 1260px; POSITION: absolute; TOP: 4863px; HEIGHT: 1442px" coordsize="1260,1442" coordorigin="6922,4863"><line id="_x0000_s1044" style="POSITION: absolute" from="8180,4863" to="8180,6303"><font size="3"></font></line><line id="_x0000_s1045" style="POSITION: absolute; flip: x" from="6922,6305" to="8182,6305"><stroke endarrow="block"><font size="3"></font></stroke></line></group><group id="_x0000_s1046" style="LEFT: 3862px; WIDTH: 1080px; POSITION: absolute; TOP: 4865px; HEIGHT: 1440px" coordsize="1080,1440" coordorigin="3862,4865"><line id="_x0000_s1047" style="POSITION: absolute; flip: x" from="3862,6305" to="4942,6305"><font size="3"></font></line><line id="_x0000_s1048" style="POSITION: absolute; flip: y" from="3862,4865" to="3862,6305"><stroke endarrow="block"><font size="3"></font></stroke></line></group><shape id="_x0000_s1049" style="LEFT: 7460px; WIDTH: 1260px; POSITION: absolute; TOP: 6483px; HEIGHT: 360px" stroked="f" type="#_x0000_t202"><textbox inset="5.85pt,.7pt,5.85pt,.7pt"><table cellspacing="0" cellpadding="0" width="100%"><tbody><tr> <td style="BORDER-LEFT-COLOR: #d4d0c8; BORDER-BOTTOM-COLOR: #d4d0c8; BORDER-TOP-COLOR: #d4d0c8; BACKGROUND-COLOR: transparent; BORDER-RIGHT-COLOR: #d4d0c8"> <div> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US" style="FONT-FAMILY: 宋体">2 </span><span style="FONT-FAMILY: 宋体">登陆</span></font></p> </div> </td> </tr></tbody></table></textbox></shape><shape id="_x0000_s1050" style="LEFT: 2962px; WIDTH: 1619px; POSITION: absolute; TOP: 6485px; HEIGHT: 360px" stroked="f" type="#_x0000_t202"><textbox inset="5.85pt,.7pt,5.85pt,.7pt"><table cellspacing="0" cellpadding="0" width="100%"><tbody><tr> <td style="BORDER-LEFT-COLOR: #d4d0c8; BORDER-BOTTOM-COLOR: #d4d0c8; BORDER-TOP-COLOR: #d4d0c8; BACKGROUND-COLOR: transparent; BORDER-RIGHT-COLOR: #d4d0c8"> <div> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US" style="FONT-FAMILY: 宋体">3.1</span><span style="FONT-FAMILY: 宋体">登陆成功</span></font></p> </div> </td> </tr></tbody></table></textbox></shape><group id="_x0000_s1051" style="LEFT: 5842px; WIDTH: 1440px; POSITION: absolute; TOP: 4145px; HEIGHT: 1440px" coordsize="1440,1440" coordorigin="5842,4145"><line id="_x0000_s1052" style="POSITION: absolute; flip: y" from="5842,4145" to="5842,5585"><font size="3"></font></line><line id="_x0000_s1053" style="POSITION: absolute" from="5842,4145" to="7282,4145"><stroke endarrow="block"><font size="3"></font></stroke></line></group><shape id="_x0000_s1054" style="LEFT: 5662px; WIDTH: 1260px; POSITION: absolute; TOP: 3605px; HEIGHT: 360px" stroked="f" type="#_x0000_t202"><textbox inset="5.85pt,.7pt,5.85pt,.7pt"><table cellspacing="0" cellpadding="0" width="100%"><tbody><tr> <td style="BORDER-LEFT-COLOR: #d4d0c8; BORDER-BOTTOM-COLOR: #d4d0c8; BORDER-TOP-COLOR: #d4d0c8; BACKGROUND-COLOR: transparent; BORDER-RIGHT-COLOR: #d4d0c8"> <div> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><font size="3"><span lang="EN-US" style="FONT-FAMILY: 宋体">3.2</span><span style="FONT-FAMILY: 宋体">登陆失败</span></font></p> </div> </td> </tr></tbody></table></textbox></shape></group><shape id="_x0000_s1055" style="LEFT: 5122px; WIDTH: 1621px; POSITION: absolute; TOP: 5944px; HEIGHT: 541px" stroked="f" type="#_x0000_t202"><textbox style="mso-next-textbox: #_x0000_s1055" inset="5.85pt,.7pt,5.85pt,.7pt"><table cellspacing="0" cellpadding="0" width="100%"><tbody><tr> <td style="BORDER-LEFT-COLOR: #d4d0c8; BORDER-BOTTOM-COLOR: #d4d0c8; BORDER-TOP-COLOR: #d4d0c8; BACKGROUND-COLOR: transparent; BORDER-RIGHT-COLOR: #d4d0c8"> <div> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US" style="FONT-FAMILY: 宋体"><font size="3">LoginAction</font></span></p> </div> </td> </tr></tbody></table></textbox></shape></group></p> <wrap type="none"></wrap><anchorlock></anchorlock></group>
第二节 使用maven建立基本开发结构
使用如下命令建立Struts2 应用程序框架结构
mvn archetype:create
-DgroupId=com.jpleasure
-DartifactId=login
-DarchetypeGroupId=org.apache.struts -DarchetypeArtifactId=struts2-archetype-starter
-DarchetypeVersion=<chsdate w:st="on" year="1899" month="12" day="30" islunardate="False" isrocdate="False">2.0.5</chsdate>-SNAPSHOT -DremoteRepositories=http://people.apache.org/repo/m2-snapshot-repository
目录说明
生成的Struts2开发框架目录满足一般的maven项目,主要由以下目录组成:
src
├─main 源代码目录
│ ├─java java代码
│ ├─resources 资源文件等
│ └─webapp Web目录
│ ├─jsp JSP目录
│ ├─styles CSS目录
│ └─WEB-INF WEB-INF目录
└─test 测试代码目录
├─java java代码
└─resources 资源文件等
重要文件:
src\main\resources
applicationContext.xml Spring配置文件
log4j.properties log4j配置文件
struts.properties struts参数文件
struts.xml struts配置文件
xwork-conversion.properties xwork参数文件
src\main\webapp\WEB-INF
decorators.xml
dwr.xml DWR配置文件
sitemesh.xml SiteMesh配置文件
web.xml Web部署描述文件
进入工程目录(login目录)使用如下命令建立Eclipse工程文件
mvn eclipse:eclipse
使用如下命令打包工程
mvn package
应用程序打包完成之后可以再login\target目录中看到login.war文件,这个文件就是最终的成果文件
使用如下命令运行应用程序
mvn jetty:run
也可以将login.war拷贝到tomcat的webapps目录下来运行struts2应用程序。
打开IE在浏览器中输入:
可以看到如下画面
说明自动生成的框架已经可以运行。
第三节 补充Login功能
下面我们来完成login功能
首先将login工程导入到Eclipse中
之后建立在src\main\java目录中建立LoginAction类,代码清单如下:
package com.jpleasure.login.action;
import javax.servlet.http.HttpSession;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
public class LoginAction extends ActionSupport {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String forward() throws Exception {
return SUCCESS;
}
@Override
public String execute() throws Exception {
if("admin".equals(name)) {
HttpSession session = ServletActionContext.getRequest().getSession();
session.setAttribute("name", name);
return SUCCESS;
} else {
return INPUT;
}
}
}
Action具有以下特点:
1 从ActionSupport继承而来。
2 包含一些属性和getter,setter方法,这些属性用来保存客户端传递到服务器的数据,或者用来作为在JSP上显示的数据的源。
3 有一些返回String类型,无参数的方法,在LoginAction中是execute方法forwardLogin方法,这些方法就是Action需要执行的方法。
SUCCESS和INPUT都在com.opensymphony.xwork2.Action类中定义,类型为String,分别用来表示成功和输入结果。
在src\main\webapp中建立Welcome.jsp和Login.jsp两个JSP文件
Welcome.jsp代码清单如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">3C</chmetcnv>//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Welcome</title>
</head>
<body>
<s:url action="forwardLogin" id="forwardLoginUrl"></s:url>
<s:a href="%{forwardLoginUrl}">Forward Login</s:a>
<%
if(session.getAttribute("name") != null){
out.println("<br/> login success.");
}
%>
</body>
</html>
Login.jsp 代码清单如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W<chmetcnv w:st="on" unitname="C" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">3C</chmetcnv>//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Login</title>
</head>
<body>
<s:url action="login" id="loginUrl"></s:url>
<s:form action="%{loginUrl}">
<s:textfield label="Name" name="name"/>
<s:password label="Password" name="password" />
<s:submit></s:submit>
</s:form>
</body>
</html>
这些JSP有如下特点:
1 有一个特殊的taglib声明,<%@taglib prefix="s" uri="/struts-tags" %>这是struts2的标准taglib声明。
2 一些s标签
<s:url action="forwardLogin" id="forwardLoginUrl"></s:url>定义了一个叫做forwardLoginUrl的指向forwardLogin的Action的路径。
同理:<s:url action="login" id="loginUrl"></s:url>定义了一个叫做loginUrl指向loginaction的Action的路径。
<s:a href="%{forwardLoginUrl}">Forward Login</s:a>定义了一个指向forwardLogin的链接,其中href使用了上面定义的内容。
<s:form action="%{loginUrl}">
<s:textfield label="Name" name="name"/>
<s:password label="Password" name="password" />
<s:submit></s:submit>
</s:form>
定义了一个向login Action提交的form,这个Form提交name和password两个字段,这个Form的action指向使用了前面定义的loginUrl变量。
配置src\main\resources\struts.xml 文件
在默认的package中添加如下内容
<package name="myPackage" extends="struts-default">
<!-- login begin -->
<action name="forwardLogin" method="forward"
class="com.jpleasure.login.action.LoginAction">
<result>/Login.jsp</result>
</action>
<action name="login" class=