Struts2学习小结

1 基础

使用:导入 jar 包,配置 web.xml,并引入 struts.xml 文件

DMI:动态方法调用,调用时使用!分隔 action 名与方法名,如 index ! add.action,可以进行快捷测试

<!-- 需要修改配置文件,默认为false,需要修改为true -->
<constant name="struts.enable.DynamicMethodInvocation" value="true" /> 

通配符:

<action name="\*_*" class="action.{1}Action" method="{2}">
    <result>{1}_{2}.jsp</result>
</action>

结果类型:

  • dispatcher:默认为此项,转发到某个页面
  • chain:跳转到一个action
  • redirect:重定向到页面或action,会丢失参数
  • redirectAction:重定向到某个action
  • 跳转到另一个包中的action
<result name="loginSuccess" type="redirectAction">
    <param name="namespace">/</param>
    <param  name="actionName">index</param>
    <param name="method">index</param>
</result>
  • 带参数的结果集:
<result name="params" type="redirect">/params.jsp?t=${type}</result> 

接收参数

  1. 直接在 Action 中增加属性
  2. 使用 domainModel,在 Action 中持有一个 Bean 的引用
  3. 实现 ModelDriven 接口

访问web元素(request,session等)

  1. 直接定义,使用 ActionContext.getContext().getSession() 获取
  2. 使用 ServletActionContext 类的静态方法
  3. IoC,实现相应的 Aware 接口(ServletRequestAware,SessionAware等)

Struts2读取配置文件顺序:

  1. struts-default.xml
  2. struts-plugin.xml
  3. struts.xml
  4. struts.properties
  5. web.xml

JSP转发到action失败,strus2默认不接受转发。解决:修改web.xml:

<filter>
     <filter-name>struts2</filter-name>
     <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
     <filter-name>struts2</filter-name>
     <url-pattern>/*</url-pattern>
     <dispatcher>REQUEST</dispatcher>
     <dispatcher>FORWARD</dispatcher>
</filter-mapping>

2 数据校验

必须添加如下配置:/login.jsp

使用struts2标签,非simple主题自动显示错误信息,simple主题可以使用标签 或 EL/OGNL 表达式获取错误信息

编程式验证:

  • 重写 validate() 方法,使用 addFieldError() 或 addActionError() 返回错误信息
  • 在不需要验证的方法上增加注解:@SkipValidation

声明式验证:xwork里的validation拦截器

  • 在action包下添加ActionClassName-validation.xml(针对所有方法)
  • 添加ActionClassName-alias-validation.xml(针对某个方法),alias为struts.xml下action标签的name属性
<validators>
    <!-- 字段验证,fielderror -->
    <field name="age">
        <!-- 短路验证 -->
        <field-validator short-circuit="true" type="conversion">
            <message>类型转换出错</message>
        </field-validator>

        <field-validator type="int">
            <param name="min">18</param>
            <param name="max">70</param>
            <!-- key引用国际化配置文件中的name -->
            <message key="error.message"></message>
            <!-- 在国际化配置文件中添加如下信息 -->
            <!--
            error.message=$(getText(fieldName)) needs to be betweents ${min} and ${max}
            age=年龄
            count=数量
            -->
        </field-validator>
    </field>
     <!-- 非字段验证,actionerror -->
    <validator type="expression">
        <param name="expression"><![CDATA[password==password2]]></param>
        <message>两次密码输入不一致</message>
    </validator>
</validators>

3 OGNL

  • 访问静态方法:
  • Math类的静态方法:
  • List:
  • Map.keys:
  • Map.values:
  • size:
  • // 投影:抽取集合中的某一列数据
  • // 选择:从集合中选取满足条件的数据
  • // ?表示获取满足指定条件的所有元素
  • 选择所有的:
  • 选择第一个: 20}.{name}"/>
  • 选择最后一个: 20}.{name}"/>
  • 判断为空: 20}.{name} == null"/>

?

中括号【】:

4 Struts2标签库

数据标签:

property取值为字符串 :

property设定默认值 :

property解析html : " escape="false" />

set设定adminName值(默认存放在request和ActionContext(Stack Context)中)

//注意使用%{str}将str强转为ognl表达式, 并注意OGNL与EL的结合使用

//标签中的value属性直接以ognl表达式解析

//其他标签都需要使用 % 将字符串强转为ognl表达式

<!-- select的两种用法:struts标签和jstl标签 -->

<s:select list="departments" listKey="id" listValue="name" value="model.department.id" headerKey="" headerValue="---请选择---"/>

<select>
    <c:forEach items="${departments}" var="dept">
         <!-- 注意相等是用 "==" 表示 -->
         <option value="${dept.id}" <c:if test="${dept.id == model.department.id}">selected="selected"</c:if>>${dept.name }</option>
    </c:forEach>
</select>

<!-- <s:select/>自定义列表内容 -->
<s:select list="#{'I':'调入','O':'调出'}" key="ajustLogModel.flag" headerKey="" headerValue="--请选择--"></s:select>

5 $,%,#的用法

  • $用于 struts.xml 文件和 i18n 中引用 ognl 表达式
  • #用于取 ActionContext ( Stack Context,堆栈 ) 中的对象
  • %用于将字符串强转为 ognl 表达式

6 处理ajax请求

  1. 通用的方式:
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("This is an ajax response from a struts Action.");
out.flush();
return null;
  1. 使用struts2中的流的方式
private InputStream inputStream;

public String delete() throws UnsupportedEncodingException {
    trainService.delete(ids);
    inputStream  = new ByteArrayInputStream("1".getBytes("utf-8"));
    return SUCCESS;
}
<!-- 以stream的方式传输ajax请求 -->
<result type="stream" name="deleteSuccess">
    <param name="contneType">text/html</param>
    <param name="inputName">inputStream</param>
</result>

7 文件上传

form表单必须以 multipart/form-data 方式提交

//文件上传需要的参数,多文件改成数组即可

private File upload;            //文件,名称对应input中file类型的name值
private String uploadFileName;       //文件名称,setter方法必须为:setUploadFileName
private String uploadContentType;    //文件的MIME类型,setter方法必须为:setUploadContentType

private void upload(Product product) throws IOException {
     //删除上传的图片
     String path = product.getImage();
     if (path != null) {
           String realPath = ServletActionContext.getServletContext().getRealPath("/" + path);
           File file = new File(realPath);
           file.delete();
     }

     if (upload != null) {
           //获取文件上传的磁盘的绝对路径
           String realPath = ServletActionContext.getServletContext().getRealPath("/products");
           //创建一个文件
           File diskFile = new File(realPath + "//" + uploadFileName);
           //文件上传
           org.apache.commons.io.FileUtils.copyFile(upload, diskFile);
           product.setImage("products/" + uploadFileName);
     }
}
<!-- 配置其它上传参数需要使用拦截器 -->
<constant name="struts.multipart.maxSize" value="107374182400" />

<interceptor-ref name="fileUpload">
     <param name="allowedTypes">image/bmp,image/jpeg,image/jpg,image/png,image/gif</param>
     <param name="maximumSize">2M</param>
</interceptor-ref>

8 全局异常处理

<global-exception-mappings>
    <exception-mapping result="error" exception="java.lang.NullPointerException"></exception-mapping>
</global-exception-mappings>

需要为error配置一个全局结果集,前台使用struts标签或ognl表达式获取:${exception.message}

9 拦截器

  • 自定义拦截器:实现Interceptor接口,或继承MethodFilterInterceptor(推荐)
  • 默认使用 defaultStack,若使用自定义拦截器则需要显示调用自定义的和默认的,或定义自己的拦截器栈
  • 在package下注册自定义拦截器并添加拦截器栈:
<interceptors>
     <interceptor name="timer" class="interceptor.MyInterceptor" />
     <interceptor-stack name="myStack">
          <interceptor-ref name="defaultStack" />
          <interceptor-ref name="timer" />
     </interceptor-stack>
</interceptors>
  • 在action中引入自定义拦截器(栈):<interceptor-ref name="myStack"/>
  • 拦截器和过滤器区别
    1. 过滤器是J2EE的标准,任何的一个程序都可以使用;拦截器是struts2框架的一个标准,不能离开struts2框架,必须依赖struts2框架。
    2. 拦截器是基于java的反射机制的,而过滤器是基于函数回调。
    3. 拦截器不依赖于servlet容器,过滤器依赖于servlet容器。
    4. 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
    5. 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
    6. 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
    7. 拦截器可以注入IOC容器中的bean,而过滤器不行,这点很重要,如在拦截器里注入Service,可以调用业务层方法
    8. 执行的顺序:过滤器 -----> 拦截器。
    9. 过滤器拦截的是web.xml配置文件。其他的拦截工作就都交给了拦截器。

10 设置编码方式

  1. struts2.3.x以后默认为utf-8
  2. struts2.3.x中的 default.properties 中的默认配置即为utf-8
  3. 在 struts.xml 中配置常量:<constant name="struts.i18n.encoding" value="utf-8"></constant>
  4. 在web.xml中为struts2的核心过滤器设置初始化参数
<filter>
     <filter-name>struts2</filter-name>
     <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
     <init-param>
            <param-name>struts.i18n.encoding</param-name>
           <param-value>utf-8</param-value>
     </init-param>
</filter>

几个配置文件加载顺序:default.properties > struts.xml > web.xml

核心流程源码解析:

首先,客户端发出请求,经三个过滤器(ActionContextCleanUp(可选),其他过滤器,到StrutsPrepareAndExecuteFilter(新版),此过滤器询问ActionMapper该请求是否属于struts2请求,是就将请求处理交给ActionProxy,ActionProxy通过ConfigurationManager 加载配置文件struts.xml,找到请求对应的Action类,然后创建一个ActionInvocation实例,根据配置文件struts-default.xml循环调用action相关的拦截器,每执行完一个拦截器,会继续调用invocation的invoke方法,把请求传给下个拦截器,所有的拦截器执行完以后,会调用Action,action执行完毕后返回一个result,通常是jsp或FreeMarker模板,渲染结果生成动态页面(struts2标签等),此时还没有完毕,继续按照相反顺序调用相关拦截器,最后将结果返回。

原文地址:https://www.cnblogs.com/mabaoqing/p/10346140.html

时间: 2024-10-18 12:11:13

Struts2学习小结的相关文章

Struts2 学习小结

struts2配置步骤 在web.xml文件中添加web监听spring容器上下文对象 <!-- web监听 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> 初始化spring容器,加载spring核心配置文件 配置struts2核心过滤器,接管所有的请求 <!-

struts2 学习记录 之 国际化

struts2 接下来是国际化,如果一个系统想要被多个国家的人所用就不得不考虑国际化的问题,如果为每一个国家都开发一套系统维护起来会很麻烦,所以就有了个思想,那就是把动态的,用不同语言展示的部分,放到配置文件中,动态的从文件里读取想要展示的内容,不同国家的人就得到了不同的展示,这是一个很好的思想,所以我把它记录一下了,嘻嘻... 首先 struts2 要把它的配置文件写好,以中文和美式英语为例,配置文件如下: 配置文件是以键值对的形式存在的,且以properties结尾,命名也有一定的格式,如t

struts2 学习记录 过滤器 国际化

struts2接触不是一天两天了,但是一直没有用它做什么项目,但老师确一直说它有很大的学习价值,所以还是把我学习到的东西给记录一下,记录的东西没有规律,只是给自己留个备份, struts2中最关键的是action,action可以用来传值,用起来很方便,它可以用el表达式在jsp页面上展示出来,也可以用ognl,el只能表达作用域里面的值,而struts2里面还有个放数据的地方叫做ActionContext,这个类里面可以放不在作用域里的键值对,但是el表达式还是可以获取到,但是效率很低,所以尽

struts2学习笔记(二)—— 获取登录信息及计算在线人数

实现目的: 1.点击"Login"的超链接,进入登录页面 2.填写登录信息,提交表单,将用户信息保存进Session 3.显示用户名,并计算在线人数 4.点击"Logout"的超链接,在线人数减一,并使Session失效 Struts2实现: 1.配置web.xml文件 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http:/

git学习小结

背景:最近因为工作原因,需要将以前的代码库由bitbucket重新布置在一台服务器上,所以就学习了下git,特此记录下 在167这台机器上搭建apache,用做git server,由于以前apache都已经搭好了,所以这里只配置git server 就可以了,此处贴出配置: 服务器搭好了,来到配置中的root目录,git clone https://[email protected]/XXXX 此时,库和服务器都搭好了,用于新库测试的机器也可以从git server上克隆库了,来,我们来试试从

网络编程学习小结

几种网络编程方式: ISAPI.CGI.WinInet.Winsock 它们之间的差别: 1)  ISAPI主要是开发基于浏览器client与server端程序.效率比CGI方式高,并且也扩展了CGI没有的一些功能.(基于TCP/IP模型中的应用层) 2)  CGI主要是开发基于浏览器client与server端程序.(基于TCP/IP模型中的应用层) 3)  WinInet主要是开发client程序.(基于TCP/IP模型中的应用层) 4)  Winsock主要是基于socket来开发clie

struts2学习笔记(8)-------struts2的ajax支持

struts2支持一种stream类型的Result,这种类型的Result可以直接向客户端浏览器响应二进制,文本等, 我们可以再action里面生成文本响应,然后在客户端页面动态加载该响应即可. 直接看例子: public class LoginAction { private String user; private String pass; private InputStream inputStream; public InputStream getInput(){ return inpu

Struts2学习

Struts2流程 Web端发起一个request到Struts2action的过程为:首先对提交的表单或者数据进行类型转换,如果转换失败,则action跳转至input所对应的页面,如果没有设置input对应的页面则页面报错.如果转换成功,则已经自动给action的属性赋值了,接下来会调用action中的validate()校验方法,如果校验失败,则同转换失败一样跳转至input所对应的页面,只有校验通过了,才会去执行execute()方法,然后根据返回值跳转到对应的页面. JSP EL表达式

MogileFS学习小结

大纲: 一.关于MogileFS 二.常见分布式文件系统 三.MogileFS基本原理 四.MogileFS的实现 一.关于MogileFS 当下我们处在一个互联网飞速发展的信息社会,在海量并发连接的驱动下每天所产生的数据量必然以几何方式增长,随着信息连接方式日益多样化,数据存储的结构也随着发生了变化.在这样的压力下使得人们不得不重新审视大量数据的存储所带来的挑战,例如:数据采集.数据存储.数据搜索.数据共享.数据传输.数据分析.数据可视化等一系列问题. 传统存储在面对海量数据存储表现出的力不从