Struts2的配置和struts2的上传下载中的注意事项

Struts2实现了MVC模式:
    Model:Action接口/ActionSupport类 (业务控制器)多实例单线程
    View:Struts2提供了4种视图技术  jsp freemarker velocity xslt,同时提供了Result接口,允许用户自定义扩展        
    Controller:一组拦截器和前端控制器StrutsPrepareAndExecuteFilter
    
配置前端控制器web.xml
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
        <init-param>
            <param-name>struts.devMode</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

Struts2的常量配置
    default.properties  struts-default.xml struts-plugins.xml[插件配置] struts.xml struts.properties web.xml    
    
struts.xml中的常量配置方法:
    <constant name="struts.action.extension" value="action" />
    
抽象包  --只能被继承使用
    <package name="default" extends="struts-default" abstract="true"></package>

Action的定义方法:
    1、不实现任何接口,不继承任何类
    2、Action接口(5大常量和execute方法)
    3、ActionSupport

Action的配置:
    <action name="hello" class="com.yan.action.HelloAction"></action>
    使用hello.action访问HelloAction中的execute方法
    
    <action name="hello" class="com.yan.action.HelloAction" method="show"></action>
    使用hello.action访问HelloAction中的show方法
        
Action的编程:
    将一个类对象相关的CRUD方法定义在一个Action类中
    public class MyAction{
        public String add()throws Exception{}
        public String del()throws Exception{}
        public String load()throws Exception{}
        ......
    }
    
    <action name="user_*" class="com.yan.MyAction" method="{1}">
        user_add.action访问MyAction类中的add方法
    
    <action name="*_*" class="com.yan.{1}Action" method="{2}">
        User_add.action访问com.yan.UserAction类中的add方法
    
    特例:<action name="*">如果不定义<action>的class属性,则默认ActionSupport类
            <result>/{1}.jsp
        实现了hello.action直接访问/hello.jsp页面,不需要额外定义对应的Action类

ActionSupport提供了服务器端数据校验的支持,可以通过编码实现服务器端数据校验
    如果Action类中有一个方法public String add()throws Exception,则对应的服务器端数据校验方法为
        public void validateAdd(){}。校验方法名称规则为"validate"+方法名,注意方法名首字母大写 
        
        执行流程:当客户提交数据时,首先框架自动化构建对应的Action对象(反射),然后框架的拦截器负
    责接收用户提交数据,并通过set方法将参数注入到Action对象中,然后调用validateXXX方法实现服务器端
    数据校验,然后如果有validate方法则继续执行validate方法;以上方法中如果调用this.addFieldError添
    加了报错信息,则自动跳转到<result name=input>对应的页面;如果没有添加任何报错信息,则执行对应的
    方法xxx或者execute
    
Action如何接收请求参数:
    1、属性驱动
    2、模型驱动
    3、对象驱动OGNL  <input name="user.username"/>
    
Action中如何使用Servlet Api
    1、ActionContext  --Map
    2、ServletActionContext  ---API
    3、实现xxxAware接口
        (Map  API)
        
Action中添加报错信息的方法
    addActionError("报错信息")        
        <s:actionerror/>
    addFieldError("输入域名称","报错信息")
        <s:fielderror/>显示所有输入域相关的报错信息
        <s:fielderror name="username"/>显示<input name="username"/>对应的报错信息        

Struts2为了简化页面编写,提供了一个标签库,可以分为2大类:<%@ taglib uri="/struts-tags" prefix="s"%>
    UI标签用于生成可以显示的标签,例如输入域,Struts2提供了4种主题:
        xhtml默认 css_xhtml  simple  ajax(事实上高版本中已经移到其它包)        
    非UI标签用于进行页面的显示逻辑控制,例如<s:if>                    

UI标签
    <s:head/>
    <s:form
    <s:textfield
    <s:password
    <s:submit
    <s:reset
    <s:file>
    
非UI标签
    <s:if test="userList!=null and userList.size()>0">
        <s:elsif test="">
        <s:else>
    <s:iterator>        
    
    <s:iterator value="#userList" var="u1">
    
    <s:property value="#u1.id"/>
    
    <s:url var="u1" action="list">
        <s:param name="pages.pageNum" value="1"/>
    </s:url>
    
    <s:a href="%{#u1}">首页</s:a>
    
在Maven中进行反向映射
    1、在pom.xml中添加插件
    
    2、配置反向映射配置文件
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE generatorConfiguration
            PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
            "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
    <generatorConfiguration>
        <classPathEntry location="E:/libs/driver/ojdbc6.jar" />
    
        <context id="DB2Tables" targetRuntime="MyBatis3">
            <commentGenerator>
                <property name="suppressAllComments" value="true" />
            </commentGenerator>
    
            <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
                connectionURL="jdbc:oracle:thin:@localhost:1521:EDUASK" userId="yanjun"
                password="tiger">
            </jdbcConnection>
    
            <javaModelGenerator targetPackage="com.yan.entity"
                targetProject="src/main/java">
                <property name="enableSubPackages" value="ture" />
                <property name="trimStrings" value="true" />
            </javaModelGenerator>
            <sqlMapGenerator targetPackage="com.yan.mapper"
                targetProject="src/main/resources">
                <property name="enableSubPackages" value="ture" />
            </sqlMapGenerator>
            <javaClientGenerator type="XMLMAPPER"
                targetPackage="com.yan.dao" targetProject="src/main/java">
                <property name="enableSubPackages" value="ture" />
            </javaClientGenerator>
            <table tableName="T_USERS" domainObjectName="User"
                enableCountByExample="false" enableDeleteByExample="false"
                enableSelectByExample="false" enableUpdateByExample="false" />
        </context>
    </generatorConfiguration>        
    
    3、用Maven命令mvn mybatis-generator:generate生成                    


<package name="包名称,没有什么特殊要求,只是在整个应用中不要出现重复,出了被引用之外,没有什么特殊含义"
    extends="父包名称,表示新定义的包需要继承这个包,父包中的定义子包可以直接继承,不需要重复定义"
    abstract="true用于定义抽象包,表示则这个包不能直接使用,只能被其它包进行继承" 
    namespace="/user设置名空间,表示这个包中的所有请求路径都应该是/user打头,在具体的Action匹配过程中,不
是通过name进行匹配,而是首先匹配对应的名空间,以查找对应的包;如果不定义名空间,则默认名空间为空,进行匹配时
首先匹配名空间对应的包;如果匹配失败,则匹配名空间为空的包"

如何在配置文件中定义action的属性
    <action name="user" class="com.yan.action.UserAction">
        <param name="属性名称">值</param>

<result>配置
    用于定义逻辑地址名和物理地址之间的对应关系
        <result name="login">/WEB-INF/content/user/login.jsp</result>
        
        name是逻辑地址名,如果不定义name属性,则默认属性是success;地址跳转方式默认采用的请求转发
        
        type属性
        <result-types>
            <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
            <result-type name="dispatcher" class="org.apache.struts2.result.ServletDispatcherResult" default="true"/>
            <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
            <result-type name="httpheader" class="org.apache.struts2.result.HttpHeaderResult"/>
            <result-type name="redirect" class="org.apache.struts2.result.ServletRedirectResult"/>
            <result-type name="redirectAction" class="org.apache.struts2.result.ServletActionRedirectResult"/>
            <result-type name="stream" class="org.apache.struts2.result.StreamResult"/>
            <result-type name="velocity" class="org.apache.struts2.result.VelocityResult"/>
            <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
            <result-type name="plainText" class="org.apache.struts2.result.PlainTextResult" />
            <result-type name="postback" class="org.apache.struts2.result.PostbackResult" />
        </result-types>    
        
   <result-type name="dispatcher" class="org.apache.struts2.result.ServletDispatcherResult" default="true"/>
           当定义<result>时如果不定义对应的type属性,则属性值默认为dispatcher,请求转发到对应的jsp页面  【重点】
           
       <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
           用于实现从一个action请求转发到下一个action。同时前一个action中的属性会自动向后传递
           
               <action name="show" class="com.yan.MyAction">
                   <result type="chain">
                       <param name="actionName">list</param>跳转的action的名称
                       <param name="namespace">/abc</param>跳转的action所属的名空间的名称
                       
       <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>支持freemarker视图                
       <result-type name="velocity" class="org.apache.struts2.result.VelocityResult"/>支持Velocity视图                
    <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>    支持xslt视图
    
    <result-type name="plainText" class="org.apache.struts2.result.PlainTextResult" />直接显示页面的源码
    <result-type name="postback" class="org.apache.struts2.result.PostbackResult" />回退
    
    
    <result-type name="httpheader" class="org.apache.struts2.result.HttpHeaderResult"/>用于生成一个头响应信息,类似于response.sendError
        <action name="test1">
            <result type="httpheader">
                <param name="error">500</param>出错代码,例如404等
                <param name="errorMessage">页面不存在!</param>默认的报错信息
            </result>
        </action>
        
    <result-type name="redirect" class="org.apache.struts2.result.ServletRedirectResult"/>用于实现重定向到一个新的地址[可以是jsp,
也可以是action]只是需要配置为地址,而且IDE工具对调转到action的地址会报错,但是不影响使用
        <result name="login" type="redirect">
            <param name="location">/index.jsp</param>具体要跳转的地址(可以是下一个action的name,也可以是某个具体的jsp路径),允许使用?name=value传值
        </result>
        
     <result-type name="redirectAction" class="org.apache.struts2.result.ServletActionRedirectResult"/>用于实现重定向到一个action,
其中包含参数actionName和namespace,同type=chain.如果跳转的action在同一个名空间中,namespace可以不定义    【重点】
        <action name="test1" class="com.yan.action.UserAction" method="tologin">
            <result name="login" type="redirectAction">
                <param name="actionName">tologin</param>
                <param name="namespace">/user</param>
            </result>
        </action>
        
    <result-type name="stream" class="org.apache.struts2.result.StreamResult"/>用于直接输出数据到输出流中
            其中包括一个参数inputName,这是输入流的属性名称,Action从这个输入流中读取数据,并写出到输出流  【重点】
        动态生成校验码:
            public class PicAction extends ActionSupport implements SessionAware{
                private int width = 120, height = 120;
                private String source="0123456789";
                private Map<String,Object> session;
            
                private InputStream is;
                @Override
                public String execute() throws Exception {
                    BufferedImage buffer = new BufferedImage(width, height,
                            BufferedImage.TYPE_INT_RGB);
                    Graphics g = buffer.getGraphics();
                    g.setColor(Color.CYAN);
                    g.fillRect(0, 0, width, height);
                    g.setColor(Color.BLACK);
                    g.drawRect(2, 2, width-6, height-6);
                    String checkcode=this.generateCheckcode(6);
                    session.put("checkcode",checkcode);
                    g.setFont(new Font("宋体",Font.BOLD,28));
                    g.setColor(new Color(88,66,200));
                    g.drawString(checkcode, 10, height-10);
                    ByteArrayOutputStream baos=new ByteArrayOutputStream();
                    ImageIO.write(buffer, "jpg", baos);
                    baos.flush();
                    is=new ByteArrayInputStream(baos.toByteArray());
                    return super.execute();
                }    
        
            <action name="pic" class="com.yan.action.PicAction">
                <param name="height">40</param> 给action配置参数,Action类定义中应该有对应的属性【get/set】
                <param name="source">qwertyuiopasdfghjklzxcvbnm0123456789</param>
                <result type="stream">
                    <param name="inputName输入流的名称,需要输出的内容需要关联到这个输入流上">is</param>给type定义参数
                    <param name="bufferSize缓冲区的大小,单位是字节">8192</param>
                    <param name="contentType响应内容类型,采用MIME协议定义">image/jpeg</param>
                </result>
            </action>
        
        
Struts2中如何实现文件的上传?
    1、commons-fileupload[commons-io]
        Struts2中使用允许不同的上传组件,例如COS之类的,如何配置
            常量定义
                定义不同的上传组件,需要自行添加所依赖的jar                
                    struts.multipart.parser=jakarta设置使用commons-fileupload上传组件
                    struts.multipart.saveDir=临时存放上传文件的文件夹
                    struts.multipart.maxSize=2097152允许上传文件的最大大小,单位是字节,默认值是2M
                    
    2、定义页面的要点:
        <form>必须method=post,必须添加enctype=multipart/form-data
            <s:form method="post" enctype="multipart/form-data" action="upload.action">
                <s:file name="photo" label="上传头像"/>
                <s:submit value="提交数据"/>
            </s:form>
    
    3、定义Action接收上传的文件数据,  一对三
        public class UploadAction extends ActionSupport {
            private File photo;// 这个属性名称和文件域的name名称一致
            private String photoContentType;//命名规则为"文件域的name"+ContentType,名称格式固定,用于表示上传文件的MIME类型
            private String photoFileName;//上传文件的原始名称,其中不包含路径;命名规则为"文件域的name"+FileName,名称格式固定        
                                
        具体的文件上传细节由commons-fileupload实现,在action中实际上只是负责进行存放的处理
        
            private ServletContext application;
            @Override
            public String execute() throws Exception {
                //获取upload文件夹部署后的绝对路径
                String realPath=application.getRealPath("upload/");
                File ff=new File(realPath);
                if(!ff.exists())
                    ff.mkdirs();
                File destFile=new File(realPath,photoFileName);
                FileUtils.copyFile(photo, destFile);
                return SUCCESS;
            }

下载处理:
    content-disposition attachment;filename=默认名称
    
    public class DownloadAction extends ActionSupport implements ServletContextAware {
        private String fname;
        private InputStream is;
        private ServletContext application;
    
        @Override
        public String execute() throws Exception {
            is=application.getResourceAsStream("upload/"+fname);
            return super.execute();
        }
        
    <action name="download" class="com.yan.action.DownloadAction">
        <result type="stream">
            <param name="contentDisposition">attachment;filename=${fname}</param>
            <param name="inputName">is</param>
            <param name="bufferSize">8192</param>
        </result>
    </action>
    
OGNL:
    Struts2为了实现在各个组件之间共享数据,引入了ValueStack值栈
    
        用户每次访问struts的action,都会创建一个Action对象、值栈对象、ActionContext对象;  
然后把Action对象放入值栈中; 最后再把值栈对象放入request中,传入jsp页面。
    1.ValueStack有一个实现类叫OgnlValueStack. 
    2.每一个action都有一个ValueStack.(一个请求,一个request,一个action,一个valueStack) valueStack生命周期就是request生命周期。 
    3.valueStack中存储了当前action对象以及其它常用web对象(request,session,application.parameters) 
    4.struts2框架将valueStack以“struts.valueStack”为名存储到request域中。
    
    页面上提供了一个标签<s:debug/>可以自动生成一个超链接,点击链接可以查看ValueStack中的内容
                

猜你喜欢

转载自blog.csdn.net/java_laoming/article/details/81159719
今日推荐