Struts2核心流程图

1. Struts2 和 Struts1 对比

struts1:基于Servlet(ActionServlet),actionForm众多(类的爆炸),action单例(数据安全[线程安全]问题).

  将所有任务的解决都集于一身.(不容易扩展和定制)

  action位于控制层. extends Action{...}

  action更struts1的action和原生servlet api(HttpServletRequest,HttpServlerResponse)绑定在一起,

  因此不容易测试,需要部署到web容器中进行测试.

  回显数据:struts-html.tld <html:checkbox> html:text

  struts-bean.tld

  struts-logic.tld

  //

  class CustomerAction extends DispatchAction{

   public ActionForward save(ActionMapping ActionForm Request,Response){

}

   public ActionForward update(ActionMapping ActionForm Request,Response){

}

  }

<action-mappings>

   <action path="/customerAction"

     name="customerForm"

     scope="request|session"

     validate="true"

     input="/xxx.jsp"

     type="xxxx..CustomerAction"

     parameter="method" />

  http://xxx/sss/customerAction.do?method=save

struts2:基于filter,没有actionform,action(原型的,独占).

  seperate aware:分离关注.解耦.(interceptor,拦截器).

  action是模型层(接受参数+pojo).

  action不需要和struts的action和原生servlet API(HttpServletRequest,HttpServlerResponse)耦合在一起.

  所以更容易测试,不需要一定要部署到web环境中进行测试.

  struts2是更加整洁的mvc框架(原因是采用了seperate aware技术,实现任务的拆解).

体验struts2:

 1.创建web项目

 2.引入struts2类库

  ${struts解压目录}/app/struts2-blank-2.1.8.1.war/web-inf/lib/*.jar

 3.创建action.

  package cn.itcast.struts2.action;

/**

   * HelloWorldAction

   */

  public class HelloWorldAction {

   public String execute(){

    System.out.println("hello world");

    return null ;

   }

  }

 4.创建struts配置文件.src/struts.xml

  dtd:struts-core.jar/struts-2.1.7.dtd/30行

  <?xml version="1.0"?>

  <!DOCTYPE struts PUBLIC

   "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"

   "http://struts.apache.org/dtds/struts-2.1.7.dtd">

  <struts>

   <package name="HelloWorldPkg" namespace="/helloworld">

    <action name="HelloWorldAction" class="cn.itcast.struts2.action.HelloWorldAction" />

   </package>

  </struts>

 5.配置struts2的过滤器web-inf/web.xml文件中

  类:org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

  <?xml version="1.0" encoding="UTF-8"?>

  <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

   <filter>

    <filter-name>action</filter-name>

    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

   </filter>

   <filter-mapping>

    <filter-name>action</filter-name>

    <url-pattern>/*</url-pattern>

   </filter-mapping>

   

   <welcome-file-list>

    <welcome-file>index.jsp</welcome-file>

   </welcome-file-list>

  </web-app>

struts2包搜索顺序:

 http://localhost:8085/lsn_struts2/helloworld/aaa/bbb/HelloWorldAction.action

 http://localhost:8085/lsn_struts2/helloworld/aaa/bbb/

 http://localhost:8085/lsn_struts2/helloworld/aaa/

 http://localhost:8085/lsn_struts2/helloworld

list lst = .. ;

request.setAttribute("list",list); Map<String,Object>

request.getRequestDispatcher("/xxxx.jsp").forward(request,response);

HttpServletResponse.sendRedirect("/xx");

ContentType:

response.setContentType("text/html");

mime:

(HttpServletRequest)request.getAttribute("list");

request.setAttribute("list",list);

map:Sessoin (ServletContext)Application.setAttri

使用Token拦截器避免表单重复提交:

 1.在jsp页面上使用<s:token />

 2.在拦截器栈中加入token拦截器.

Google:

Web:异步执行.

2. 实例: 表单提交 ,校验,防重复提交,文件上传

web.xml 配置

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
  4. http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  5. <filter>
  6. <filter-name>action</filter-name>
  7. <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  8. </filter>
  9. <filter-mapping>
  10. <filter-name>action</filter-name>
  11. <url-pattern>/*</url-pattern>
  12. </filter-mapping>
  13.  
  14. <welcome-file-list>
  15. <welcome-file>index.jsp</welcome-file>
  16. </welcome-file-list>
  17. </web-app>

struts.xml配置  包含模块 reg.xml

  1. <?xml version="1.0"?>
  2. <!DOCTYPE struts PUBLIC
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
  4. "http://struts.apache.org/dtds/struts-2.1.7.dtd">
  5. <struts>
  6.  
  7. <!-- 通过常量方式改变struts默认的属性配置, -->
  8. <constant name="struts.action.extension" value="do" />
  9. <!-- 设置开发模式,重新加载国际化资源文件和配置文件 -->
  10. <constant name="struts.devMode" value="true" />
  11. <!-- 动态方法调用 -->
  12. <constant name="struts.enable.DynamicMethodInvocation" value="true" />
  13.  
  14. <package name="HelloWorldPkg" namespace="/helloworld" extends="struts-default">
  15. <!-- 默认该包下默认的action引用,若该包没有要访问的action元素,则使用默认的action引用 -->
  16. <default-action-ref name="HelloWorldAction" />
  17.  
  18. <!-- 设置默认的class引用,将摸个类作为默认的action类 -->
  19. <default-class-ref class="cn.itcast.struts2.action.HelloWorldAction" />
  20.  
  21. <!-- 通过通配符的方式实现动态方法调用 -->
  22. <action name="HelloWorldAction_*" class="cn.itcast.struts2.action.HelloWorldAction"
  23. method="{1}">
  24. <result name="success">/index.jsp</result>
  25. <result name="save">/index.jsp</result>
  26. <result name="update">/success.jsp</result>
  27. </action>
  28.  
  29. <!-- 没有类的action -->
  30. <action name="ActionNoClass">
  31. <result>/index.jsp</result>
  32. </action>
  33. </package>
  34. <!-- 模块话编程,包含配置文件 -->
  35. <include file="cn/itcast/struts2/action/reg.xml" />
  36. </struts>

reg.xml  配置

  1. <?xml version="1.0"?>
  2. <!DOCTYPE struts PUBLIC
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
  4. "http://struts.apache.org/dtds/struts-2.1.7.dtd">
  5. <struts>
  6. <package name="RegPkg" namespace="/regns" extends="struts-default">
  7. <action name="RegAction_*" class="cn.itcast.struts2.action.RegAction" method="{1}">
  8. <result name="success">/reg/success.jsp</result>
  9. <result name="error">/reg/error.jsp</result>
  10. <result name="regView">/reg/reg.jsp</result>
  11. <result name="input">/reg/reg.jsp</result>
  12. <interceptor-ref name="defaultStack"> <!--动态方法调用,方式之一-->
  13. <param name="validation.excludeMethods">input,back,cancel,toRegView</param>
  14. </interceptor-ref>
  15. </action>
  16. </package>
  17. </struts>

token.xml 防止重复提交 配置

  1. <?xml version="1.0"?>
  2. <!DOCTYPE struts PUBLIC
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
  4. "http://struts.apache.org/dtds/struts-2.1.7.dtd">
  5. <struts>
  6. <package name="TokenPkg" namespace="/token" extends="struts-default">
  7. <action name="TokenAction_*" class="cn.itcast.struts2.token.TokenAction" method="{1}">
  8. <result name="success">/token/success.jsp</result>
  9. <result name="regView">/token/reg.jsp</result>
  10. <!--无效令牌-->
  11. <result name="invalid.token">/token/reg.jsp</result>
  12. <result name="wait">/wait.jsp</result>
  13. <!-- 如果指定了一个拦截器,则覆盖默认的配置,必须手动指定默认栈 -->
  14. <interceptor-ref name="token">
  15. <param name="excludeMethods">toRegView,findAllCustomers</param>
  16. </interceptor-ref>
  17. <interceptor-ref name="defaultStack" />
  18. <!-- 执行等待拦截器 -->
  19. <interceptor-ref name="execAndWait" />
  20. </action>
  21. </package>
  22. </struts>

reg.jsp 表单提交 JSP, 使用struts-tags 标签,数据回显与校验

  1. <%@ page language="java" contentType="text/html; charset=utf-8"%>
  2. <%@taglib uri="/struts-tags" prefix="s"%>
  3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  4. <html>
  5. <head>
  6. <title>reg.jsp</title>
  7. </head>
  8. <body>
  9. <s:debug />
  10. <s:actionerror />
  11. <s:form namespace="/regns" action="RegAction_reg" method="post" enctype="multipart/form-data">
  12. <s:token /> <!--防止重复提交-->
  13. <s:textfield name="name" label="UserName" />
  14. <s:textfield name="age" label="UserAge" />
  15. <s:file name="photo" label="UserPhoto" />
  16. <s:submit />
  17. </s:form>
  18. </body>
  19. </html>

RegAction.java  处理action

  1. public class RegAction extends ActionSupport {
  2.  
  3. private static final long serialVersionUID = 2941355104469235318L;
  4. private String name;
  5. private Integer age;
  6.  
  7. /* 接受上传的文件 */
  8. private File photo ;
  9. /* 接受文件名称 */
  10. private String photoFileName ;
  11. /* 接受文件内容类型的 */
  12. private String photoContentType ;
  13.  
  14. public String getPhotoFileName() {
  15. return photoFileName;
  16. }
  17.  
  18. public void setPhotoFileName(String photoFileName) {
  19. this.photoFileName = photoFileName;
  20. }
  21.  
  22. public String getPhotoContentType() {
  23. return photoContentType;
  24. }
  25.  
  26. public void setPhotoContentType(String photoContentType) {
  27. this.photoContentType = photoContentType;
  28. }
  29.  
  30. public String getName() {
  31. return name;
  32. }
  33.  
  34. public void setName(String name) {
  35. this.name = name;
  36. }
  37.  
  38. public Integer getAge() {
  39. return age;
  40. }
  41.  
  42. public void setAge(Integer age) {
  43. this.age = age;
  44. }
  45.  
  46. /**
  47. *
  48. */
  49. public String reg(){
  50. System.out.println("reg : " + name);
  51. String dir = ServletActionContext.getServletContext().getRealPath("/upload");
  52. String ext = photoFileName.substring(photoFileName.lastIndexOf("."));
  53. long l = System.nanoTime();
  54. File newFile = new File(dir,l + ext);
  55. photo.renameTo(newFile);
  56. return SUCCESS;
  57. }
  58.  
  59. /**
  60. * 达到注册页面, 动态方法调用之一, 使用SkipValidation标签掉过校验
  61. */
  62. //@SkipValidation
  63. public String toRegView(){
  64. return "regView" ;
  65. }
  66.  
  67. /**
  68. * 动态方法调用之一,命名: validate + 要校验方法(Reg) == void validateReg() {}
  69. */
  70. public void validate() {
  71. if(name == null || name.length() == 0){
  72. //国际化,getText会从配置文件获得message,配置文件名和类名一致,位置相同,RegAction.properties
  73. addFieldError("name",getText("error.name.empty"));
  74. }
  75. }
  76.  
  77. public File getPhoto() {
  78. return photo;
  79. }
  80.  
  81. public void setPhoto(File photo) {
  82. this.photo = photo;
  83. }
  84. }

RegAction.properties 国际化配置文件

  1. error.name.empty=name is required!
  2. error.name.age=age is required!

success.jsp 成功跳转JSP

  1. <%@ page language="java" contentType="text/html; charset=utf-8"%>
  2. <%@taglib uri="/struts-tags" prefix="s"%>
  3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  4. <html>
  5. <head>
  6. <title>index.jsp</title>
  7. </head>
  8. <body>
  9. you input's name is <s:property value="name" />.<br>
  10. you input's age is <s:property value="age" />.<br>
  11. </body>
  12. </html>

wait.jsp 等待页面

  1. <%@ page language="java" contentType="text/html; charset=utf-8"%>
  2. <%@taglib uri="/struts-tags" prefix="s"%>
  3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  4. <html>
  5. <head>
  6. <title>wait.jsp</title>
  7. <meta http-equiv="refresh" content="2;url=<s:url/>"/>
  8. </head>
  9. <body>
  10. 处理中,请稍后....
  11. </body>
  12. </html>

JavaWeb -- Struts2,对比, 简单表单提交,校验,防重复提交, 文件上传的更多相关文章

  1. 表单同时有中文字段和文件上传,加上enctype="multipart/form-data"后导致的中文乱码问题

    因为一个表单需要同时上传字段和文件,所以加上enctype="multipart/form-data",但是上传后的中文字段变成了乱码. 把enctype="multip ...

  2. PHP表单处理、会话管理、文件上传、文件处理、执行函数(10.8 第十六天)

    表单处理 服务器接收用户发过来的数据方式: $_GET 接收用户以GET方式发过来的数据 $_POST 接收用户以POST方式发过来的数据 $_COOKIE 接收用户COOKIE $_REQUEST ...

  3. php表单加入Token防止重复提交的方法分析

    http://www.jb51.net/article/94395.htm 这篇文章主要介绍了php表单加入Token防止重复提交的方法,结合实例形式分析了Token防止重复提交的原理与使用技巧,需要 ...

  4. IE兼容性问题解决方案4--form表单在IE下重复提交

    遇到过一种情况,点击提交按钮的时候,在IE下重复提交,而在其他浏览器下正常. 原因:button按钮不设置type时,在IE下被浏览器默认解析为type="submit",用js提 ...

  5. 前端 HTML form表单标签 input标签 type属性 file 上传文件

     加上上传文件功能 input type='file' - 依赖form表单里一个属性 enctype="multipart/form-data" 加上这个属性表示把你上次文件一点 ...

  6. 简单原始的ASP.NET WEBFORM中多文件上传【参考其他资料修改】

    首先是ASPX页面中添加file标签 <input onclick="addFile()" type="button" value="增加&qu ...

  7. angular 1.2.29版本下 动态添加多个表单、 校验全部、 提交 、ng-form方案

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. Javaweb学习笔记——(二十二)——————文件上传、下载、Javamail

    文件上传概述      1.文件上传的作用          例如网络硬盘,就是用来上传下载文件的.          在网络浏览器中,时常需要上传照片 2.文件上传对页面的要求          上 ...

  9. 超全面的JavaWeb笔记day22<文件上传>

    文件上传概述 1 文件上传的作用 例如网络硬盘!就是用来上传下载文件的. 在智联招聘上填写一个完整的简历还需要上传照片呢. 2 文件上传对页面的要求 上传文件的要求比较多,需要记一下: 1. 必须使用 ...

  10. thinkphp5.0 实现单文件上传功能

    思路是:在app/ceshi/fire下面有一个index操作方法来渲染显示前端文件,然后前端文件跳转到upload操作方法进行处理,成功显示"文件上传成功",失败显示错误. 首先 ...

随机推荐

  1. 【BZOJ1816】[Cqoi2010]扑克牌 二分

    [BZOJ1816][Cqoi2010]扑克牌 Description 你有n种牌,第i种牌的数目为ci.另外有一种特殊的牌:joker,它的数目是m.你可以用每种牌各一张来组成一套牌,也可以用一张j ...

  2. 隐藏内容但仍保持占位的css写法

    通常显示和隐藏内容都会用display:block;和display:none; 如果想要保持内容的占位可以用visbility:visible; 和visiblity:hidden;来控制内容的显示 ...

  3. Jmeter--BeanShell使用

    博客首页:http://www.cnblogs.com/fqfanqi/ (一)BeanShell简介 BeanShell是一个小型嵌入式Java源代码解释器,具有对象脚本语言特性,能够动态地执行标准 ...

  4. vitess数据中心迁移步骤

    在使用vitess的时候我们会遇到刚开始所有的元数据都在同一个ETCD集群中,后续随着业务的增长需要进行数据中心拆分: 分别拆分成多个Local集群的数据中心: 以下就简单说明下迁移步骤: 迁移拓扑图 ...

  5. ORACLE_SID的查找

    SID是System IDentifier的缩写,而ORACLE_SID就是Oracle System Identifier的缩写,在Oracle系统中,ORACLE_SID以环境变量的形式出现,在特 ...

  6. Xcode 编译静态库

    有时候,我们需要将一部分经常用到的代码提取出来用来复用,或者说需要用到c++的代码的时候,可以通过编译成静态库的方式来使用.本文中使用的Xcode版本是8.3,静态库制作过程和其他版本基本一样,可能出 ...

  7. 面向对象 - 1.软件开发/2.异常处理/3.try...except的详细用法

    1.软件开发 软件的开发其实一整套规范,我们所学的只是其中的一小部分,一个完整的开发过程,需要明确每个阶段的任务,在保证一个阶段正确的前提下再进行下一个阶段的工作,称之为软件工程 面向对象的软件工程包 ...

  8. centos7开机启动tomcat7

    1.进入tomcat/bin vi setenv.sh      (原来没有这个文件,需要创建出来) 添加 #add tomcat pid CATALINA_PID="$CATALINA_B ...

  9. Python位运算符

    按位运算符是把数字看作二进制来进行计算的.Python中的按位运算法则如下: 下表中变量 a 为 60,b 为 13,二进制格式如下: a = 0011 1100 b = 0000 1101 ---- ...

  10. PostgreSQL: WITH Queries (Common Table Expressions)

    WITH 允许在 SELECT 语句中定义"表"的表达式,这个"表"的表达式称之为"公共表表达式(Common Table Expression)&q ...