struts2学习笔记

第一天:

struts2是在WebWork基础上发展而来的,也属于MVC框架。

struts2和struts1名字上很像,但是他们是完全不同的。

struts具有以下的优点:

struts2的优点:
1、struts2不依赖与ServletAPI和strutsAPI
2、struts2提供了拦截器
3、struts2提供了类型转换器,我们可以把特殊的请求参数转换为需要的类型
4、struts2提供支持多种表现层的技术如 JSP、freeMarker、Velocity等
5、struts2输入校验可以对指定方法进行校验
6、struts2提供全局范围、包范围、和Action范围的国际化资源文件管理实现

struts2开发步骤:

1、struts2 开发所需要的架包。

2、编写struts2的配置文件

struts2的默认配置文件是struts.xml文件,在WEB-INF/classes下。该文件的模板文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
</struts>

注意:此文件在开发的时候是放到src目录下,程序编译后会自动拷贝到WEB-INF/classes目录下。

3、在web.xml中加入struts2 MVC框架的初始配置。

struts2框架是通过Filter启动的,他在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>
</filter-mapping>

在StrutsPrepareAndExecuteFilter的init()方法中将会读取类路径下默认的配置文件struts.xml完成初始化操作。

注意:struts2读取到struts.xml的内容后,以javabean形式存放在内存中,以后struts2对用户的每次请求处理将使用内存中的数据,而不是每次都读取struts.xml文件

struts.xml 文件的说明:

 <package name="itcast" namespace="/test" extends="struts-default">
    <action name="helloworld" class="cn.itcast.action.HelloWorldAction" method="execute" >
        <result name="success">/WEB-INF/page/hello.jsp</result>
    </action>
 </package> 

在struts2文件中通过package来管理action

name属性可以任意取,但是要保证其唯一性,主要是被其他包使用。


namespace主要作为访问action路径的一部分


extends 继承于哪个包


action name可以作为访问该action路径的一部分。


每个包都继承于struts-defult

class 访问该类需要处理的类。

第二天:

转发和重定向。

action中result默认的就是服务器内部请求转发(dispatcher)

redirect:浏览器重定向,引导用户浏览器访问某个路径,不能访问WEB-INF下边的JSP,只有服务器内部可以访问。

dispatcher 和redirect区别:内部定向不会显示到浏览器地址栏中,也就是jsp里面的转发器,用户看不到地址栏的变化。

redirectAction:重定向到一个Action。

如果不在一个里边的Action,重定向请求时候,需要:

redirectAction对应一个Java类,该类里边有两个setActionName()和setNamespace()

<param name="actionName">xxx</param>
<param name="namespace">/</param>

在package配置中:

extends="struts-default"

这一项不是默认配置的,必须要配置。

 还可以进行配置全视图:

<global-results>
            <result name="message">/WEB-INF/message/message.jsp</result>
</global-results>

跨包使用全局视图,可以通过继承包就可以实现。

第三天:为Action属性注入值

通过<param>标签,name为变量的名字,标签体为值。

<action name="hello" class="cn.lyjs.web.action.Hello" >
            <param name="path">/WEB-INF/jsp/hello.jsp</param>
            <result name="success">/WEB-INF/jsp/hello.jsp</result>
 </action>

2、指定struts2处理的请求后缀

<constant name="struts.action.extension" value="do"></constant>

3、常量的配置

最好在struts.xml 文件中定义常量。

 4、struts2的处理过程

用户请求到达---StrutsPrepareAndExecuteFilter过滤------》进入Struts2框架-------》经过一系列Interceptor----》action---->Resutlt--->Jsp/html

struts2对于用户的每一次请求都会创建一个Action,所以Struts2中的Action是线程安全的。

5、为应用指定多个配置文件

把一个stuts.xml配置文件拆分成多个配置文件,然后再struts.xml文件中包含其他配置文件

<include file="文件的地址"/>

 第四天:

1、动态方法调用

直接在请求地址后边:!方法名(很少使用)

禁止方法如下:

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

2、使用通配符

<action name="hello_*" class="cn.lyjs.web.action.Hello" method="{1}" >
            <result name="success">/WEB-INF/jsp/hello.jsp</result>
</action>

获取*时候,用{1},1代表第几个*号。

 3、接受请求参数:


在Action中定义与请求参数同名的属性
使用JavaBean来接收参数,person.id,person.name 来获得参数的值


4、struts2类型转换器:
局部:
1、首先要写一个类来继承DefaultTypeConverter
2、然后覆盖convertValue这个方法,在里面进行数据转型
3、在action类所在的包下放置ActionClassName-conversion.properties文件,ActionClassName是类名,后面的-conversion.properties是固定的写法,
4、d.Properties文件里面的内容为:属性名称=类型转换器的全类名(既包名.类名)
如:birthday=com.ljq.type.converter.DateTypeConverter

package cn.lyjs.type.conserver;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;

public class HelloDate extends DefaultTypeConverter {

    @Override
    public Object convertValue(Map<String, Object> context, Object value,
            Class toType) {
        //必须以这个格式严格输入
        SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
    try{
        if(toType==Date.class){ //转化为Date类型
            String[] params=(String[]) value;
                return sdf.parseObject(params[0]);
            
        }else if(toType==String.class){ //转化为字符类型
            Date date=(Date) value;
            return sdf.format(date);
        }
    }
    catch (ParseException e) {
        
    }
    return null;
    }
}

 访问或添加几个属性

通过ActionContext来访问
ServletContext、session、request

1、通过ActionContext进行获取(仅仅需要添加属性)
        ActionContext ac=ActionContext.getContext();
        ac.getApplication().put("app", "应用范围");
        ac.getSession().put("ses","session范围");
        ac.put("req", "request范围");

2、通过ServletActionContext类直接获取(获取绝对路径的)

        HttpServletRequest request=ServletActionContext.getRequest();
        ServletContext servletContext=ServletActionContext.getServletContext();
        servletContext.setAttribute("app", "应用属性范围");
        request.setAttribute("req", "请求属性范围");
        request.getSession().setAttribute("ses","绘话属性范围");

<c:forEach items="${names } var="name">
        ${name }<br/>
    </c:forEach>
public class HelloWorldAction {
    
    public String execute(){
        
        ActionContext ac=ActionContext.getContext();
        ac.getApplication().put("app", "应用范围");
        ac.getSession().put("ses","session范围");
        ac.put("req", "request范围");
        ac.put("names", Arrays.asList("价格","答案","发个"));
        return "success";
    }
    
    public String rsa() throws Exception{
        HttpServletRequest request=ServletActionContext.getRequest();
        ServletContext servletContext=ServletActionContext.getServletContext();
        servletContext.setAttribute("app", "应用属性范围");
        request.setAttribute("req", "请求属性范围");
        request.getSession().setAttribute("ses","绘话属性范围");
        
        return "success";
    }
}

 第四天:

文件上传

1、把form的enctype设置为multipart-data

2、private File uploadImage;

  private String uploadImageFileName ; 得到文件的名称

3、

    public String execute() throws IOException{
        //在 WEB-INF下边创建 images 文件
        String realpath=ServletActionContext.getServletContext().getRealPath("/WEB-INF/images");
        if(image!=null){
            File savefile=new File(new File(realpath),imageFileName); //创建一个实例而已,而不是创建一个文件
            if(!savefile.getParentFile().exists()) savefile.getParentFile().mkdirs();//创建多级目录
            FileUtils.copyFile(image, savefile);//savefile只是一个实例,现在根据这个实例,把image内容,写入到这个实例的文件中
            ActionContext.getContext().put("message", "上传成功");
        }
        return "success";
    }

 多文件上传:

public class Hello {
    
    private File[] image;
    private String[] imageFileName;
    
    
    public File[] getImage() {
        return image;
    }


    public void setImage(File[] image) {
        this.image = image;
    }


    public String[] getImageFileName() {
        return imageFileName;
    }


    public void setImageFileName(String[] imageFileName) {
        this.imageFileName = imageFileName;
    }


    public String execute() throws IOException{
        //在 WEB-INF下边创建 images 文件
        String realpath=ServletActionContext.getServletContext().getRealPath("/WEB-INF/images");
        System.out.println(realpath);
        if(image!=null){
            File file=new File(realpath);
            if(!file.exists()) file.mkdirs();
            for(int i=0;i<image.length;i++){
                File savefile=new File(file,imageFileName[i]);
                FileUtils.copyFile(image[i], savefile);
            }
            ActionContext.getContext().put("message", "上传成功");
        }
        return "success";
    }
    

 第五天:

自定义拦截器

1、拦截器类必须继承于Interceptor

package cn.lyjs.interceptors;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;

public class PermissionInterceptor implements Interceptor{

    public void destroy() {
                
    }

    public void init() {
    
    }

    public String intercept(ActionInvocation invocation) throws Exception {
        Object session=ActionContext.getContext().getSession().get("user");
        if(session!=null) return invocation.invoke();//执行该action
        ActionContext.getContext().put("message", "你没有权限查看,请你先登录");
        return "success";
    }
    
}

2、配置

配置拦截器栈,默认的栈排在第一个。

<package name="test" namespace="/" extends="struts-default">
    <interceptors>
        <interceptor name="permission" class="cn.lyjs.interceptors.PermissionInterceptor"/>
        <interceptor-stack name="permissionStack">
            <interceptor-ref name="defaultStack"/>
            <interceptor-ref name="permission"/>
        </interceptor-stack>
    </interceptors>
    <global-results >
        <result name="success">/WEB-INF/jsp/hello.jsp</result>
    </global-results>
    <action name="hello" class="cn.lyjs.web.action.Hello" method="execute">
        <interceptor-ref name="permissionStack"/>
    </action>
    </package>
原文地址:https://www.cnblogs.com/lyjs/p/4967351.html