<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} -->
第一个简单的struts实例
1. 添加Struts相关的jar包(antlr-2.7.2.jar、commons-beanutils-1.7.0.jar、commons-chain-1.1.jar、commons-digester-1.8.jar、commons-logging-1.0.4.jar、commons-validator-1.3.1.jar、struts-core-1.3.8.jar、struts-taglib-1.3.8.jar、struts-tiles-1.3.8.jar)9个到WEB-INF/lib下
2. 准备视图组件
WebRroot下建idex.jsp
<%@ page language="java" contentType="text/html; charset=gbk" pageEncoding="gbk"%> <!DOCTYPE html PUBLIC "-//W3C//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=gbk"> <title>主页</title> </head> <body>
<form action="Login.do" method="post"> 用户名:<input type="text" name="name"/><br> 密码:<input type="password" name="password"/><br> <input type="submit" value="提交"/> </form>
</body> </html> |
WEB-INF下建success.jsp
WEB-INF下建fail.jsp
3. 创建控制器组件
建java类LoginAction.java
public class LoginAction extends Action {
@Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { //获得数据 UserForm userForm = (UserForm) form; String name = userForm.getName(); String password = userForm.getPassword();
//调用逻辑处理 LoginService ls = new LoginService(); boolean flag = ls.isLogin(name, password);
//实现跳转 if(flag){ System.out.println("成功"); return mapping.findForward("ok"); }else{ System.out.println("失败"); return mapping.findForward("fail"); } } } |
4. 创建模型组件
建java类UserForm.java
public class UserForm extends ActionForm { 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; } } |
建java类LoginService.java
public class LoginService { public boolean isLogin(String name,String password){ if("gjw".equals(name) && "123".equals(password)){ return true; }else{ return false; } } } |
5. 准备配置文件
在web.xml文件中添加如下标记
<servlet> <servlet-name>login</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>login</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> |
在WEB-INF下建立struts-config.xml文件
<?xml version="1.0" encoding="gbk" ?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd"> <struts-config> <form-beans> <form-bean name="userForm" type="com.high.struts.action.UserForm"></form-bean> </form-beans>
<global-exceptions></global-exceptions> <global-forwards></global-forwards>
<action-mappings> <action path="/Login" name="userForm" type="com.high.struts.action.LoginAction"> <forward name="ok" path="/WEB-INF/success.jsp"></forward> <forward name="fail" path="/WEB-INF/fail.jsp"></forward> </action> </action-mappings> </struts-config> |
指定其他名字的struts配置文件:
<servlet> <servlet-name>struts</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/config/struts.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> |
表单验证
1. 自己建form,重写其中的validate()方法
(1) 前台jsp文件,使用到struts标签库,要在WEB-INF下加入struts-html.tld,并配置在web.xml文件中
<%@ page language="java" contentType="text/html; charset=gbk" pageEncoding="gbk"%> <%@taglib prefix="html" uri="/struts-html" %> <!DOCTYPE html PUBLIC "-//W3C//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=gbk"> <title>主页</title> </head> <body>
<form action="Login.do" method="post"> 用户名:<input type="text" name="name"/><html:errors property="name"/><br> 密码:<input type="password" name="password"/><html:errors property="password"/><br> <input type="submit" value="提交"/> </form> </body> </html> |
在web.xml中加入下面的标记 <jsp-config> <taglib> <taglib-uri>/struts-html</taglib-uri> <taglib-location>/WEB-INF/struts-html.tld</taglib-location> </taglib> </jsp-config> |
(2) 在自己的form类中重写validate()方法
@Override public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors actionErrors =new ActionErrors(); if(this.name==null||"".equals(this.name.trim())) actionErrors.add("name", new ActionMessage("name.message")); if("123".equals(this.name)) actionErrors.add("name", new ActionMessage("name.message1")); if(this.password==null||"".equals(this.password.trim())) actionErrors.add("password", new ActionMessage("pwd.message")); return actionErrors; } |
(3) 填写struts.properties文件,在struts-config.xml中配置资源文件
分别填写name.message,name.message1,pwd.message的值 |
<message-resources parameter="struts"></message-resources> |
(4) 照常配置struts-config.xml文件的form-bean和action
<action path="/Login" input="/index.jsp" name="userForm" type="com.high.struts.action.LoginAction"> |
2. 用org.apache.struts.action.DynaActionForm类型的form,在action里写验证
(1)struts-config.xml里的form-bean配置 |
<form-bean name="DynaForm" type="org.apache.struts.action.DynaActionForm"> <form-property name="image" type="org.apache.struts.upload.FormFile"></form-property> </form-bean> |
(2)在action里,获得表单数据 |
DynaActionForm dynaform = (DynaActionForm) form; FormFile image = (FormFile) dynaform.get("image"); |
(3)获得表单数据后,写验证代码 |
ActionErrors actionErrors = new ActionErrors(); if(!"image/pjpeg".equals(image.getContentType())){ actionErrors.add("image",new ActionMessage("upload.error")); saveErrors(request,actionErrors); return mapping.getInputForward(); } |
3. 用org.apache.struts.validator.DynaValidatorForm类型的form,配置validation.xml,完成验证
(1) 根据jsp页面配置struts-config.xml里的动态表单和plug-in
<form-bean name="ValidatorForm" type="org.apache.struts.validator.DynaValidatorForm"> <form-property name="name" type="java.lang.String"></form-property> <form-property name="age" type="java.lang.String"></form-property> <form-property name="address" type="java.lang.String"></form-property> <form-property name="date" type="java.lang.String"></form-property> </form-bean> |
<plug-in className="org.apache.struts.validator.ValidatorPlugIn"> <set-property property="pathnames" value="/org/apache/struts/validator/validator-rules.xml, /WEB-INF/validation.xml"/> </plug-in> |
(2) 在WEB-INF下新建validation.xml,从官方的例子里复制头标记,在struts-core-1.3.8.jar中找到validator-rules.xml文件,以便查看验证信息
(3) 配置validation.xml文件
<?xml version="1.0" encoding="gbk" ?> <!DOCTYPE form-validation PUBLIC "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.3.0//EN" "http://jakarta.apache.org/commons/dtds/validator_1_3_0.dtd">
<form-validation> <formset> <form name="ValidatorForm"> <field property="name" depends="required,minlength,maxlength"> <arg key="username"/> <arg key="${var:minlength}" resource="false" position="1" name="minlength"/> <arg key="${var:maxlength}" resource="false" position="1" name="maxlength"/> <var> <var-name>minlength</var-name> <var-value>6</var-value> </var> <var> <var-name>maxlength</var-name> <var-value>10</var-value> </var> </field> <field property="age" depends="required,integer,intRange"> <arg key="userage"/> <arg key="${var:min}" resource="false" position="1"/> <arg key="${var:max}" resource="false" position="2"/> <var> <var-name>min</var-name> <var-value>18</var-value> </var> <var> <var-name>max</var-name> <var-value>50</var-value> </var> </field> <field property="address" depends="required,mask"> <arg key="useraddress"/> <var> <var-name>mask</var-name> <var-value>^[0-9a-zA-Z]*$</var-value> </var> </field> <field property="date" depends="required,date"> <arg key="userdate"/> <var> <var-name>datePattern</var-name> <var-value>yyyy-mm-dd</var-value> </var> </field> </form> </formset> </form-validation> |
(4) 填写资源文件*.properties
填写域的名称和错误信息,域的名称可以自己命名,但错误信息的名字一定要查看validator-rules.xml文件上面的注释内容,要和注释里的名字一样,错误内容要动态传入,参考注释中的英文。
文件上传
Jsp页面表单填写
<form action="upload.do" enctype="multipart/form-data" method="post"> 附件:<input type="file" name="image"/> <input type="submit" value="submit"/> </form> |
Action类的execute方法
@Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { FileForm fileform = (FileForm) form; FormFile image = fileform.getImage();
String filename = image.getFileName(); String path = getServlet().getServletContext().getRealPath("images"); String type = filename.substring(filename.lastIndexOf("."));
String outpath = path+File.separator+System.currentTimeMillis()+type; System.out.println(outpath); InputStream in = null; OutputStream out = null; in = image.getInputStream(); out = new FileOutputStream(outpath);
IOUtils.copy(in,out); in.close(); out.close();
request.setAttribute("image",outpath.substring(outpath.lastIndexOf(File.separator))); return new ActionForward("/image.jsp"); } |
异常处理
(1) 在<global-exceptions>标签里配置最底层的异常处理页面,没有被action里的特定异常处理捕获到的,都到这里
<exception type="java.lang.Exception" key="allexception" path="/WEB-INF/error.jsp"></exception>
(2) 在<action>子标签中配置本页面特定异常的显示处理,包括自己定义的异常
<exception type="java.sql.SQLException" key="sql.exception" path="/WEB-INF/error.jsp"/>
(3) 在error.jsp中只写<html:errors/>即可
Struts中的包:
除了都要导入的9个基本包外还有:
1. 文件上传:commons-fileupload.jar, commons-io.jar
2. 正则表达式:oro-2.0.8.jar
3. 使用DispatchAction:struts-extras-1.3.8.jar
4. 使用struts标签:struts-taglib-1.3.8.jar
DispatchAction:
将类似但是处理逻辑不相同的业务代码封装在同一个Action类的不同方法中;这个Action类能同时处理多个不同的请求,客户端是通过提交不同的参数实现区分不同的请求。
例如:将对数据库的select、delete、insert都提交给同一个action处理
首先:新建这个Action类
public class DoDB extends DispatchAction {
public ActionForward select(ActionMapping arg0, ActionForm arg1, HttpServletRequest arg2, HttpServletResponse arg3) throws Exception { System.out.println("select"); return arg0.findForward("del"); }
public ActionForward delete(ActionMapping arg0, ActionForm arg1, HttpServletRequest arg2, HttpServletResponse arg3) throws Exception { System.out.println("delete"); return arg0.findForward("sel"); }
public ActionForward insert(ActionMapping arg0, ActionForm arg1, HttpServletRequest arg2, HttpServletResponse arg3) throws Exception { System.out.println("insert"); DynaValidatorForm vForm = (DynaValidatorForm) arg1; String name = vForm.getString("name"); String age = vForm.getString("age"); String[] city = vForm.getStrings("city"); System.out.println(name); System.out.println(age); for(int i=0;i<city.length;i++){ System.out.println(city[i]); } return arg0.findForward("sel"); } } |
然后:写jsp页面
在提交处都要多提交一个method=select,get方式通常采用”doDB.do?method=select”格式,post方式通常加个隐藏域
最后:配置struts-config.xml文件的action标签
因为要提交到同一个Action,但有的页面有表单,需要验证,需要通不过的input跳转;有的却没有表单,所以可以给通一个Action类配置多个<action>标签。
<action path="/doDB" type="com.high.struts.action.DoDB" parameter="method"> <forward name="del" path="/delete.jsp"></forward> <forward name="sel" path="/select.jsp"></forward> </action>
<action path="/doDB2" name="vForm" input="/insert.jsp" type="com.high.struts.action.DoDB" parameter="method" validate="true"> <forward name="sel" path="/select.jsp"></forward> </action> |
配多个struts的xml文件:每个模块都有自己的配置文件
<servlet> <servlet-name>login</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value> /WEB-INF/config/struts-config.xml, /WEB-INF/config/struts-config-login.xml, /WEB-INF/config/struts-config-user.xml </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> |
资源文件的配置<message-resources parameter="struts"></message-resources> 和验证的相关配置只在公共处配置就可以了 <plug-in className="org.apache.struts.validator.ValidatorPlugIn"> <set-property property="pathnames" value="/org/apache/struts/validator/validator-rules.xml, /WEB-INF/validation.xml"/> </plug-in> |
BasePath的问题:为了使<action>标记的path配置都为“path="/theUser"”的形式,不加多余目录,看起来更清晰明了。
方法一:Eclipse自动生成的jsp页面中的小段代码
<% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> |
<base href="<%=basePath%>"> |
方法二:添加一个过滤器,避免了jsp中加入java代码
public class Myfilter implements Filter {
public void destroy() { }
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) arg0; String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; request.setAttribute("path", basePath); arg2.doFilter(request, arg1); }
public void init(FilterConfig arg0) throws ServletException { } } |
<filter> <filter-name>myFilter</filter-name> <filter-class>action.Myfilter</filter-class> </filter> <filter-mapping> <filter-name>myFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> |
<a href="${path}theUser.do">try</a> |
用户的权限处理:加一个过滤器,不是管理员的被过滤跳到错误页,管理员的action只处理管理员
@Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException {
HttpServletRequest request =(HttpServletRequest) arg0;
HttpServletResponse response =(HttpServletResponse) arg1;
User user =(User) request.getSession().getAttribute("userInfo");
if(user!=null&&!”admin”.equals(user.getRole())){ request.getRequestDispatcher(“/error.jsp”).forward(request, response); }else{ arg2.doFilter(request, response); } } |
过滤*.do <url-pattern>*.do</url-pattern> |
错误页面的配置:在web.xml中配置(修改IE的设置)
<error-page> <error-code>404</error-code> <location>/error404.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/error500.jsp</location> </error-page> |
Struts中的标签:
首先:要在项目中加入struts-taglib-1.3.8.jar包中的3个tld文件struts-bean.tld、struts-html.tld、struts-logic.tld
通常放在/WEB-INF/tld/下
然后:在web.xml中配置他们
<jsp-config> <taglib> <taglib-uri>/struts-html</taglib-uri> <taglib-location>/WEB-INF/tld/struts-html.tld</taglib-location> </taglib> <taglib> <taglib-uri>/struts-bean</taglib-uri> <taglib-location>/WEB-INF/tld/struts-bean.tld</taglib-location> </taglib> <taglib> <taglib-uri>/struts-logic</taglib-uri> <taglib-location>/WEB-INF/tld/struts-logic.tld</taglib-location> </taglib> </jsp-config> |
最后:在jsp页面写头标记后使用
<%@taglib prefix="html" uri="/struts-html" %> <%@taglib prefix="bean" uri="/struts-bean" %> <%@taglib prefix="logic" uri="/struts-logic" %> |
<html:>标签:基本和标准的HTML标签类似
1. <html:form>默认的method为post
2. property的值一定要和对应的地方一样,不然很容易报错
3. 可以和标准的HTML标签混用
4. <html:errors>标签不写property属性将列出所有的错误信息
5. 标签的action可以不写.do
6. <html:link action="index">跳跃
<html:param name="method" value="find"></html:param>
</html:link>
与<a href="index.do?method=find">跳转</a>功能相同
<bean:>标签:
1.<bean:message>读取资源文件中的键-值信息
2.<bean:define>标记
3.<bean:write>标记与EL表达式功能类似
<logic:>标签:
1.<logic:iterate>标记
<logic:iterate id="str" name="sports"> <input type="checkbox" name="sports" value="${str }"/>${str } </logic:iterate> |
struts1存在的问题
1. 它与JSP耦合非常紧密,只支持jsp作为表现层技术,不提供其他表现层技术的支持。例如(Velocity,FreeMarker等)
2. 与Servlet严重耦合,难于测试
3. 代码严重依赖于struts1 的API,属于侵入式设计。在struts1中Action类必须继承Action基类。而且又包含了大量的struts1的API,这种侵入式设计的最大弱点在于,一旦系统需要重构时,这些Action类将完全没有利用的价值,成为一堆废品。导致了 设计上的代码复用性很低。
4. 他的标签库有问题,不够完善