Struts2教程

一、初识Struts2

  Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。许多框架在大家一开始学习的时候都觉得比较繁琐和多此一举,但大体都有相同的目的,那就是增强可扩展性。Struts2的核心其实就是通过改配置文件的方式将请求和视图(结果)分开。

1.1 开发环境搭建

  首先下载Struts2,地址http://struts.apache.org/,我这里下载的版本是2.5.10.1,解压之后有如下4个文件夹

  

  所需的基本jar包有以下9个。struts2-core是开发的核心类库,struts2的UI标签的模板使用freemarker编写,OGNL是对象图导航语言,通过它来读写对象属性。

  

1.2 Struts2配置文件

  ①web.xml文件

  主要完成对StrutsPrepareAndExecuteFilter的配置,它的实质是一个过滤器,负责初始化整个Struts框架并且处理所有的请求。在2.5以及2.1.3之前的版本filter-class会不同,请自行查询官方文档,filter-name和url-pattern是默认写法,不建议修改。

<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>
  ②struts.xml文件

  Struts2的核心配置文件就是struts.xml文件,在这个配置文件里面我们可以根据需要再包括其它一些配置文件。在通常的应用开发中,我们每个人来写不同的模块,每个人单独配置一个struts.xml文件,最后合并,这样也利于管理和维护。

  struts.xml中包含全局属性、用户请求和相应Action之间的对应关系、Action可能用到的参数和返回结果以及各种拦截器的配置,具体将在以下几节中慢慢介绍。

  struts.xml可以从解压过后的示例程序里复制,拷贝到工程的src目录下,注释或删除掉struts标签中的内容,来填写我们需要的配置。

  ③struts.properties(default.properties)

  default.properties文件在struts2-core.jar中的org.apache.struts2包下,里面保存着许多Struts是的默认属性,如编码格式、是否启用开发模式等等。当要修改某些属性时,建议在struts2的xml配置文档中进行更改,格式如下面一行代码,而不建议自己新建一个struts.properties文件。

<constant name="" value=""></constant>
  ④struts-default.xml

  此文件是struts2框架默认加载的配置文件,它定义了struts2一些核心bean和拦截器,它会自动包含到struts.xml文件中(实质是通过<package  extends="struts-default">),并为我们提供了一些标准的配置。我们可以在struts2-core.jar中找到这个文件。

二、struts.xml配置

<?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>
     <constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
    <package name="user" namespace="/user" extends="struts-default">
        <action name="user" class="com.dhcc.struts2.action.UserAction">
            <result>/user_add_success.jsp</result>
        </action>
    </package>
</struts>

例子

2.1 配置文件的优先级

  在struts2中一些配置(比如常量)可以同时在struts-default.xml(只读性),strtus-plguin.xml(只读性),struts.xml,struts.properties和web.xml文件中配置,它们的优先级逐步升高,即是说后面的配置会覆盖掉前面相同的配置。

  以struts.i18n.encoding=UTF-8的配置为例进行说明:

  在struts.xml配置形式如下:

<constant name="struts.i18n.encoding" value="gbk"></constant>

  在struts.properties的配置形式如下:struts.i18n.encoding=UTF-8

  在web.xml中配置如下:

<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>

2.2 package配置


属性名


是否必须


说明


Name



Package的唯一标识,不允许同名


Extends



指定要继承的包


Namespace



指定名称空间


Abstract



声明包为抽象否

  package元素的namespace属性及action的name属性,它们共同定义了action所映射到的实质文件。

  namespace默认值“”,即不配置namespace属性,如果action不能进行完整路径匹配,则会来此namespace下进行匹配。namespace也可以配置成namespace="/"。它代表配置为项目的根。总结action的名称探索顺序:完全对应、逐步追溯到上级目录查找、"/"下查找、默认namespace下查找。

  namespace引发的链接问题:当我们为action配置了namespace时,访问此action的形式总会是如下形式:.../webappname/xxx/yyy/ActionName.action,而当此action成功执行跳转到某个jsp页面时,如想在此jsp页面写链接,一定要写绝对路径,因为相对路径是相对.../webappname/xxx/yyy/,而如果以后我们修改了action的namespace时,相对路径又要变,所以链接不能写成相对路径。 可以在建立一个jsp文件时,加上如下内容:

<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

  我们写绝对路径可以参此内容。还可以参<head>下的<base href="<%=basePath%>"> 来完成绝对路径的书写。

三、Action

3.1 新建一个Action

 第一步,新建一个Class,继承ActionSupport ,ActionSupport实现了execute()方法。

package com.struts2.test;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport {
    public String add() {
        return "success";
    }
    public String del() {
        return "success";
    }
    public String update() {
        return "success";
    }
    public String query() {
        return "success";
    }
}

 第二步,配置此Action,在struts.xml中加入如下内容:

<package name="user" extends="struts-default" namespace="/user">
    <action name="addUser" class="com.asm.UserAction" method="add">
    <result name="success">/user/addUser.jsp</result>
    </action>
    <action name="delUser" class="com.asm.UserAction" method="del">
    <result name="success">/user/delUser.jsp</result>
    </action>
    <action name="updateUser" class="com.asm.UserAction" method="update">
    <result name="success">/user/updateUser.jsp</result>
    </action>
    <action name="queryUser" class="com.asm.UserAction" method="query">
    <result name="success">/user/queryUser.jsp</result>
    </action>
</package>

 上面的method方法的值来源于CRUDAction中方法的名字,这样当我们访问上面的每一个Action时,它实质是和method指定的方法关联上。如果没有为action指定class,默认就是ActionSupport类,如果没有为action指定method属性,则默认执行execute方法,如果没有指定result的name属性,默认值为success。

 第三步,编写相应的jsp页面,在此略去crud文件夹下的四个跳转jsp页面(addSuccess.jsp等),重点是crud.jsp页面。内容如下:

<html>
<%
    String path=request.getContextPath();
%>
    <body>
        <a href="<%=path %>/user/addUser.action">添加数据</a><br>
        <a href="<%=path %>/user/delUser.action">删除数据</a><br>
        <a href="<%=path %>/user/queryUser.action">查询数据</a><br>
        <a href="<%=path %>/user/updateUser.action">修改数据</a><br>
    </body>
</html>

 最后发布测试。

3.2 动态调用DMI

  不使用method实现统一,我们在struts.xml中增加如下内容:

<action name="op" class="com.struts2.test.UserAction">
    <result name="add">/user/addUser.jsp</result>
    <result name="del">/user/delUser.jsp</result>
    <result name="query">/user/queryUser.jsp</result>
    <result name="update">/user/updateUser.jsp</result>
</action>

  然后再在crud.jsp中定义如下链接:

<a href="<%=path %>/user/op!add.action">添加数据</a><br>
<a href="<%=path %>/user/op!del.action">删除数据</a><br>
<a href="<%=path %>/user/op!query.action">查询数据</a><br>
<a href="<%=path %>/user/op!update.action">修改数据</a><br>

  注意查看上面的链接地址,它们都是针对op这个action,然后再加地上“!+UserAction中相应的方法名”,最后再写上.action即可以访问到相应result的name指定的jsp。大家会发现跟上面不同的是,result的name不再都是SUCCESS,这样才能区分开要访问的页面,但千万不要忘记在UserAction中相应的方法也要返回add/del/query/update,而不是SUCCESS。如果不想使用动态方法调用,我们可以通过常量来关闭,即在struts.xml中增加如下配置:

<constant name="struts.enable.DynamicMethodInvocation" value="false"/>

3.3 通配符

  为了使用通配符,只需要改写配置文件即可。将3.1节中的配置文件改为如下内容可达到相同的效果:

<package name="user" extends="struts-default" namespace="/user">
    <action name="*User" class="com.asm.UserAction" method="{1}">
    <result name="success">/crud/{1}User.jsp</result>
</package>

  当有.../addUser.action请求时,如果不能在当前应用中找到完全相同的addUser名字的Action时,通配符配置这时就起作用了。

  其实如果我们有良好的编程命名习惯,所有的Action我们都只需要进行一次配置。举例:规定所有的Action类都用XXXAction来命名,类中所有的CRUD方法都用add/del/update/query。Jsp页面也用add/del/update/query_XXX.jsp这样的形式。即配置文件可以写成如下形式:

<action name="*_*" class="com.struts2.test.{2}Action" method="{1}">
    <result name="success">.../{1}_{2}.jsp</result>
</action>

  name中第一个*代表CRUD操作的名字,第二个*代表类的名字。所以访问链接地址举例如:.../del_User.action将访问到UserAction类的del方法,成功后跳到del_User.jsp页面。说明{0}是代表name中所有的*组合。

3.4 接收参数

  ①Action属性接收参数

  UserAction中建两个属性name和age,并且要生成相应的get/set方法。

public class UserAction extends ActionSupport {
    private String name;
    private int age;public int getAge() {
      return age;
    }
    public String getName() {
      return name;
    }
    public void setAge(int age) {
      this.age = age;
    }
    public void setName(String name) {
      this.name = name;
    }
} 

  在传参的jsp页面,有一个表单

<form action="<%=request.getContextPath()%>/addUser.action" method="get">
    名字:<input type="text" name="name"><br>
    年龄:<input type="text" name="age"><br>
    <input type="submit" value="login">
</form>

  这样name和age就能接收到传入的值。需要注意的是,传参参照的action中的方法名,而非属性名。

  ②DomainModel接收参数

  UserAction中有一个域模型private User user,注意不要自己new对象,User类中有name和age属性和对应的get/set方法。UserAction中要生成User对象对应的get/set方法。

  访问http://.../user/user!add?user.name=a&user.age=8 即可对user赋值,相当于调用了user的set方法。

public class UserAction extends ActionSupport {
    private User user;public User getUser() {
        return user;
    }
    public void setUser(User user) {
      this.user = user;
    }
}    
  • 如果传入的参数个数和域模型的属性个数不同,可以用DTO(Data Transfer Object)。比如传入的参数还有一个isAdmin,那么我们建一个UserDTO,包含name,age和isAdmin三个属性,用UserDTO去接收参数,然后用UserDTO再生成相应的User

  ③ModelDriven接收参数

public class UserAction extends ActionSupport implements ModelDriven<User>{   //需要实现ModelDriven接口
    private User user = new  User();  //ModelDriven需要自己new
    @Override
    public User getModel() {
        return user;
    }
}

3.5 访问web元素(request、session、application,HttpServletRequest、)

未完待续。。。

时间: 2024-08-29 21:18:01

Struts2教程的相关文章

struts2教程&amp;实例

1.第一个struts2项目 参考官方配置 http://struts.apache.org/getting-started/ github地址:https://github.com/unbelievableme/maven_hibernate-struts-spring/tree/master/struts2/first 建议:参考官方配置操作一遍,因为技术不断更新,不同版本的struts的类可能不同,老版本的多个类可能在新版本中集成了一个 2.struts2工作流程原理 2.1步骤 1.创建

Struts2 教程

一.Struts2是什么 Struts2是在WebWork2基础发展而来的.和Struts1一样, Struts2也是基于MVC的web层框架. 那么既然有了Struts1,为何还要Struts2? Struts2和Struts1虽然都是基于MVC的Web框架,但是它们的实现机制完全不同. Struts1是基于Servlet的实现,并且Struts1的API过分依赖容器,导致了Action开发.测试都非常繁琐,而Struts2是基于过滤器的实现,API不再依赖容器,测试过程中不必再模拟Web容器

Spring框架整合Struts2使用Validation框架验证表单用户输入数据的详细教程

原创整理不易,转载请注明出处:Spring框架整合Struts2使用Validation框架验证表单用户输入数据的详细教程 代码下载地址:http://www.zuidaima.com/share/1778685765291008.htm 在<Struts2教程4:使用validate方法验证数据>中曾讲到使用validate方法来验证客户端提交的数据,但如果使用validate方法就会将验证代码和正常的逻辑代码混在一起,但这样做并不利于代码维护,而且也很难将过些代码用于其他程序的验证.在St

Struts2之初识

Struts2教程 第一章 初识Struts2 主页:http://struts.apache.org/ 优势:用户请求,模块处理,页面展现.适用于企业级开发,便于维护. 配置:web.xml中添加的核心控制器 <filter> <filter-name>Struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFil

Struts2的输入验证(四)-自定义验证器与编程式验证

一.自定义验证器 1.实现步骤: 1)定义一个验证器的类 自定义验证器必须实现 Validator 接口,由于ValidatorSupport 和 FieldValidatorSupport 实现了 Validator 接口,因此可以继承ValidatorSupport 或 FieldValidatorSupport Ⅰ. 若需要普通的验证程序,可以继承 ValidatorSupport 类: Ⅱ. 若需要字段验证程序,可以继承 FieldValidatorSupport 类: Ⅲ. 若验证程序

Struts2类型转换(二)-自定义类型转换器

一.自定义类型转换器 1). 为什么需要自定义的类型转换器 ? 因为Struts不能自动完成字符串到引用类型的转换. 2). 如何定义类型转换器? I. 开发类型转换器的类: 扩展 StrutsTypeConverter 类: II. 配置类型转换器. 有两种配置方式 ①. 基于字段的配置: > 在字段所在的 Model(可能是 Action,也可能是一个JavaBean) 的包下, 新建一个 ModelClassName-conversion.properties 文件 > 在该文件中输入键

较全的IT方面帮助文档

http://www.shouce.ren/post/d/id/108632 XSLT参考手册-新.CHMhttp://www.shouce.ren/post/d/id/108633 XSL-FO参考手册-新.CHMhttp://www.shouce.ren/post/d/id/108634 XQuery参考手册-新.CHMhttp://www.shouce.ren/post/d/id/108635 XPath参考手册-新.CHMhttp://www.shouce.ren/post/d/id/1

OGNL的使用

访问Action中的普通属性: <s:property value="loginname"/><br/> 访问Action中的对象属性: <s:property value="user.birthday"/><br/> 访问Action中的Set属性: <s:property value="courseSet.toArray()[0]"/><br/> 访问Action中的Li

vue服务端渲染页面缓存和组件缓存的实例详解

vue缓存分为页面缓存.组建缓存.接口缓存,这里我主要说到了页面缓存和组建缓存 页面缓存: 在server.js中设置 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 const LRU = require('lru-cache') const microCache