Struts2学习记录1

1,Struts2.xml配置文件的注释

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- constant:配置struts2的基本属性,在struts2-core核心包的/org/apache/struts2/default.properties中找 -->
<!-- 乱码解决 -->
<constant name="struts.i18n.encoding" value="UTF-8" />


<!-- 自定义扩展名,一下可以没有,可以为.do可以为.action -->
<constant name="struts.action.extension" value="action,,do" />


<!-- 当配置文件更改后自动装载 。同时要开启开发者模式 -->
<!--true:是开发者模式。外部不可访问;false:外部可以访问 ,出错时候友好的提示信息;实际发布的时候选择false,为了安全 -->
<constant name="struts.devMode" value="true" />
<constant name="struts.configuration.xml.reload" value="true" />


<!-- 启动动态方法action配置 -->
<constant name="struts.enable.DynamicMethodInvocation" value="false" />


<!-- 把struts的action对象交给spring容器管理 -->
<constant name="struts.objectFactory " value="spring" />


<!-- include这个是团队开发模式使用的,多个xml文件的时候就使用 ,这样每个人只要维护自己的配置文件即可 -->
<!-- <include file="直接指定扩展xml文件的路径即可"/> -->




<!-- struts是基于包管理的 name随便写,namespace是指不同命名空间, extends必须是struts-default,直接或者间接继承,简介继承就使用json-default 

从Struts-core核心包中可以看到json-default 继承了struts-default,扩展了其中的过滤器配置
可以配置多个包,用于团队开发 -->
<!-- 配置文件加载顺序:struts-default.xml->struts-plugin.xml->struts.xml -->
<package name="default" namespace="/" extends="json-default">
<!-- 配置默认执行的action,当所请求的action不存在的时候默认执行的action-->
<default-action-ref name="default"/>

<!-- 配置默认执行的class ,当一个action没有配置class的时候就是这个去处理,可以不指定,也有框架自己默认的-->
<default-class-ref class="com.yc.ssm.action.UserAction"/>

<!-- 配置全局结果集 -->
<global-results>
<result name="fail">/login.jsp</result>
</global-results>
<!-- 请求这个名字name是url请求名,不需要加后缀(.action)
CLASS是请求对用的action类的全类名
method配置处理请求的方法,默认为execute方法
方法返回值类型必须是String,必须是public的
在action的配置中不配置class将由默认的action(ActionSupport类)来执行
-->
<action name="User_*" class="com.yc.ssm.action.UserAction" method="{1}">
<!-- name:匹配请求方法返回值,默认是success
type:结果处理类型
默认是dispatcher转发;
      chain:是指action链,执行actionA后直接指定actionB,地址栏是第一个action
                     dispatcher:转发,特点和Servlet一致,如果Request中有数据要显示则用
            redirect:重定向,如果重定向到jsp页面,可以直接重定向
            但是如果重定向到另一个action,需要注意是否配置action的后缀名
            redirectAction:重定向到另一个action,不用加action的后缀名,自动帮你加上了
            stream:以流的形式显示-文件下载
            还有一些就不具体讲了
-->
<result name="success" type="dispatcher">/page/index.jsp</result>
<result type="json" name="json">
<param name="contentType">
text/html
</param>
</result>
</action>

<action name="default">
<result>/404.jsp</result>
</action>
</package>
</struts>


2,web.xml中的配置

<!-- struts框架的核心(过滤器)其它过滤器都配置在它之前 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<!-- struts core如果是2.5 的版本则要删除ng -->
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>

注:这个filter一定要放在其它的过滤器之后,不然就不会执行其它的过滤器了

3,Action类的官方推荐写法

Struts2的Action是线程安全的,每次请求都将会创建一个新的action,

/**
 * ActionSupport:官方推荐继承这个类(验证) :其中的一些默认的配置

*ModelDriven:模型驱动,自动注入 

*UserBean:指需要注入的对象
 * @author shuang
 *
 */
@Controller
public class UserAction extends ActionSupport implements ModelDriven<UserBean>{

private UserBean userBean = new UserBean();

public UserBean getModel() {
return userBean;
}


使用以上写法,在action类中就可以任意使用我们的实体类userBean对象,但是提交的数据的name一定要和实体类的属性保持一致

4,最好的使用解耦和的方式获取jsp内置对象

其一:ActionContext.getContext().getSession()获取session对象

/**
 * ActionContext.getContext().getSession()一般使用这种解耦合的方式获取内置对象
 * ActionContext是一个map结构的容器,是action的上下文,
 * 存放action执行过程中的数据信息,比如session的,Application的等
 * 每次请求的时候创建一个新的ActionContext
 * 而ActionContext采用了ThreadLocal的方式来存放ActionContext
 * 所以ActionContext是线程安全的
 * ActionContext是基于请求创建的,所以在非请求的线程中是不能访问的,获取也是为空的
 * @return
 */

ActionContext:Struts2的ACtion不用依赖于web容器,本身只是一个普通的java类而已,但是在web开发中我们往往需要

获得Request等对象,这时候就可以通过ActionContext,

ActionContext正如其名,是action执行的上下文,他内部有个map属性,它存放了action执行时需要用到的对象,

在每次执行action之前都会创建新的ActionContext对象,所以ActionContext是线程安全的,新new的ActionContext是保存在

一个ThreadLocal变量中,即采用ThreadLocal模式,ThreadLocal变量为每个线程提供独立的变量值的副本,使得每个线程都可以独立

的使用自己的副本,而不会和其他的线程发生冲突

通过ActionContext获取的session,Request等并不是真的httpservletRequest等对象,而是将对象里面的值重新包装成了map对象

,这样的封装,我们及获取了我们需要的值,同时避免了跟web容器直接打交道,实现了完全的解耦


ps:ThreadLocal:提供了线程局部变量,存放线程局部变量的一个容器,


以上测试可以知道ThreadLocal是线程安全的


ActionContext包含6大对象:

1,Application

2,request

3,session

4,attr(page->request->sesssion->application)括号中是取值顺序

5,parameters

6,ValueStack(值栈)

ValueStack(值栈)

1、是ActionContext中的一个对象,值栈是栈结构(FILO:先进后出);

Struts2中值栈存放的数据是Action对象

注意:Action对象可以ValueStack,我们可以对象值栈进行操作,但是建议不是很熟就不要去操作了

5,包

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yc</groupId>
<artifactId>spring-struts-mybatis</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>


<!-- struts2框架 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.3.28</version>
</dependency>
<!-- struts2使用json格式传输数据的时候使用的包 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.3.16</version>
</dependency>


<!--struts2整合spring的插件包 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>2.5-BETA3</version>
</dependency>


<!-- spring框架的核心包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.6.RELEASE</version>
<scope>runtime</scope>
</dependency>


<!-- spring框架支持数据访问层的包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.1.6.RELEASE</version>
<scope>runtime</scope>
</dependency>


<!-- spring框架支持表现层的包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.6.RELEASE</version>
<scope>runtime</scope>
</dependency>
<!-- spring框架支持单元测试的包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.1.6.RELEASE</version>
<scope>runtime</scope>
</dependency>


<!-- aspectj框架的包 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
<scope>runtime</scope>
</dependency>


<!-- 日志 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.5</version>
<scope>runtime</scope>
</dependency>


<!-- 日志 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.5</version>
<scope>runtime</scope>
</dependency>


<!--oracle 数据库驱动包 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>oracle-driver</artifactId>
<version>oracle11g</version>
<scope>runtime</scope>
</dependency>


<!-- 数据库连接池的包 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
<scope>runtime</scope>
</dependency>


<!-- mybatis框架核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.1</version>
<scope>runtime</scope>
</dependency>


<!-- mybatis与spring整合包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
<scope>runtime</scope>
</dependency>


<!-- jstl包 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>


<!-- 邮件发送包 -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.5</version>
</dependency>
<!-- gosn包 -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.6.2</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<finalName>spring-struts-mybatis</finalName>
</build>
</project>


遇到的问题:取自网站

   在struts2中发现,调用action中的方法,方法会被执行两次,后来发现调用的方法是get开头的,把它改为其他名称开头的后,就不会执行两次了。继续查找,发现调用的是返回json数据格式的action,如果是调用返回页面的action就不会有这种问题。

     结合网上的搜索,总结了一下:

1.  json格式下, firefox中的yslow插件会发送第二个 HTTP GET 请求得到页面的信息。.

2.  ajax模式下,调用的action方法不能为get*方式命名,内中机理未知。

结论:action中方法最好不要以get开头。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值