Struts2

Struts2

  Struts2由古板的Struts① 、WebWork多少个经典的MVC框架发展起来,无论是从Struts2统一筹划角度来看,依然从Struts2在实际项目中的易用性来看,Struts2都以二个可怜精粹的MVC框架。与守旧的Struts1比照,Struts2同意选拔普通的、古板的Java对象作为Action;Action的execute()方法不再与Servlet
API耦合,由此更易测试;支持越来越多的视图技术;基于AOP思想的拦截器机制,提供了极好的可增加性;更有力、更易用的输入校验功效;整合的Ajax接济等,那一个都以Struts2的伟人吸重力。

Struts2采取的开发步骤

  一 、在web.xml文件中定义大旨Filter来拦截用户请求。

  由于web应用是依照请求和响应框架结构的应用,都亟需在web.xml文件中布署框架的骨干Servlet或Filter,那样才方可让框架加入Web应用中。

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

   二 、定义处理请求的Action类

  继承ActionSupport,重写execute方法;Action类封装HTTP请求参数,类中应当蕴含与请求参数对应的实例变量,并提供对应的setter和getter方法;处理请求的点子中应再次回到字符串。

  以下代码是印证用户名和密码是或不是输入正确

public class UserAction extends ActionSupport {
    private String username;
    private String userpass;

    public void setUsername(String username) {
        this.username = username;
    }

    public void setUserpass(String userpass) {
        this.userpass = userpass;
    }

    @Override
    public String execute() throws Exception {
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession();
        session.setAttribute("name", username);

        if ("ghq".equals(username)&&"ghq".equals(userpass)) {
            return "Suc";
        }
        return "loginFail";
    }

}

   3、配置Action

  配置Action正是钦赐哪个请求对利用哪个Action举办拍卖,从而让中央控制器依照该配置来创制合适的Action实例,并调用该Action的事体控制措施。

  配置处理结果和物理视图能源之间的照应关系

  当Action处理用户呼吁停止后,经常会回去贰个处理结果(字符串),能够认为该名称正是逻辑视图名,那一个逻辑视图名供给和点名物理视图财富事关才有价值。还需求配置处理结果之间的对应关系。

<?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>
    <package name="userlog" extends="struts-default">
        <action name="UserAction" class="com.ghq.action.UserAction">
            <result name="Suc">/wel.jsp</result>
            <result name="loginFail">/loginfail.jsp</result>
        </action>
    </package>
</struts>

 

 

Struts2流程

图片 1

  图中StrutsPrepareAndExecuteFilter和xxxAction共同组成了Struts2的控制器。平时称StrutsPrepareAndExecuteFilter为主题控制器,xxxAction为工作控制器。

 

Action和Servlet API

  为了能直接待上访问Servlet
API,Struts2提供了ServletActionContext工具类,那么些类中蕴藏了之类多少个静态方法:

//取得Web应用的PageContext对象
static PageContext getPageContext();
//取得Web应用的HttpServletRequest对象
static HttpServletRequest getRequest();
//取得Web应用的HttpServletResponse对象
static HttpServletResponse getResponse();
//取得Web应用的ServletContext对象
static ServletContext getServletContext();

 

配置Action详解

  配置Action便是让Struts2知晓哪些Action处理哪个请求,也正是到位用户请求和Action之间的关联。

壹 、包和命名空间

  Struts2选取包来协会Action,Action定义放在包定义下完毕,定义Action通过使用<package
…/>下的<action
…/>子成分来达成。每种包便是四个Action、七个拦截器、多少个拦截器引用的聚集。

<!-- 包名为user,继承struts-default -->
<package name="user" extends="struts-default">

  每一回定义一个package成分,都能够钦赐三个namespace属性,用于钦点该包对应的命名空间。命名空间最首要是为了处理同三个Web应用中带有同名Action的境况,同3个命名空间不可能有同名的Action。

  当包钦命了命名空间后,该包下全部的Action处理的U库罗德L应该是命名空间+Action名。

贰 、Action的中坚配置

<action name="UserAction" class="com.ghq.action.UserAction">
    <result name="Suc">/wel.jsp</result>
    <result name="loginFail">/loginfail.jsp</result>
</action>

   动态方法调用

<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
    <package name="user" extends="struts-default">
        <action name="UserAction" class="com.ghq.action.UserAction" >
            <result name="addUser">/addUser.jsp</result>
            <result name="getAllUser">/main.jsp</result>
        </action>
</package>

  经过上述配置现在,请求的url为:Http://localhost:8080/login/UserAction!getAllUser

  使用method属性及利用通配符

  将八个Action处理类定义成多少个逻辑Action。在安插<aciton
…/>成分时,能够为它钦点method属性,则足以让Action调用内定方法。

<package name="user" extends="struts-default">
  <action name="getAllUser" class="com.ghq.action.UserAction" method="getAllUser">
     <result name="getAllUser">/main.jsp</result>
    </action>
    <action name="addUser" class="com.ghq.action.UserAction" method="addUser">
       <result name="addUser">/addUser.jsp</result>
    </action>
</package> 

  上边的安插文件中,连个action定义的多方面同样,定义冗余,Struts2有一种简化的款式:使用通配符的法门

<package name="user" extends="struts-default">
    <action name="UserAction_*" class="com.ghq.action.UserAction" method="{1}">
        <result name="addUser">/addUser.jsp</result>
        <result name="getAllUser">/main.jsp</result>
    </action>
</package>

 

叁 、配置处理结果

  Action处理完用户的呼吁后,将重回三个家常字符串,整个普通字符串就是3个逻辑视图名。Struts2透过铺排逻辑视图名和情理视图之间的投射关系,一旦接受Action重临的逻辑视图名,系统会把相应的大体视图显示给用户。

<result name="addUser">/addUser.jsp</result>

   全局结果

<global-results>
    <result name="login">/login.jsp</result>
</global-results>

   该<result
…/>成分配置了3个大局结果,全局结果将对富有的Action都使得

 

Struts2控制文件上传

  文件上传的流程

  1、导入commons-fileupload.jar,common-io.jar包

  贰 、表单中设置entype
= ”multipart/form-data”

<form action=”” method="post" enctype="multipart/form-data">
    <input type="file" name="userphoto">
    <input type="submit" value="注册">
</form>

  3、编写Action类

public class UserAction extends ActionSupport {
    private String username;
    private String userpass;
    //用于封装上传的对象,userphoto必须和文件域的名字相同  ,不管上传的文件类型是什么,userphoto扩展名都是tmp
    private File userphoto;
    //封装被上传的文件的名字,userphoto必须和文件域的名字相同,FileName区分大小写
    private String userphotoFileName;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUserpass() {
        return userpass;
    }

    public void setUserpass(String userpass) {
        this.userpass = userpass;
    }

    public File getUserphoto() {
        return userphoto;
    }

    public void setUserphoto(File userphoto) {
        this.userphoto = userphoto;
    }

    public String getUserphotoFileName() {
        return userphotoFileName;
    }

    public void setUserphotoFileName(String userphotoFileName) {
        this.userphotoFileName = userphotoFileName;
    }

    public String regUI() throws Exception{
        return "regUI";
    }

    public String reg() throws Exception {
        //获取目标文件所在目录的绝对路径
        String filePath = ServletActionContext.getServletContext().getRealPath("/images");
        //目标文件的名字 UUID和扩展名组成
        String fileName = UUID.randomUUID().toString() + userphotoFileName.substring(userphotoFileName.lastIndexOf("."));
        //定义目标文件的对象,即要在服务器上出现的文件,要考虑到目标文件不能重复。
        File targetFile = new File(filePath,fileName);

        //获取上传文件的输入流
        FileInputStream fin = new FileInputStream(userphoto);
        //获取目标文件的输出流
        FileOutputStream fout = new FileOutputStream(targetFile);

        byte[] bs = new byte[1024];
        int count = 0;
        //上传文件
        while ((count = fin.read(bs))!= -1) {
            fout.write(bs,0,count);
        }
        //关闭流
        if (fout != null) {
            fout.close();
        }
        if (fin != null) {
            fin.close();
        }

        return "regSuc";
    }

}

   注:使用common-io.jar包中的FileUtils类能够简化文件上传。

public String reg() throws Exception {
        String filePath = ServletActionContext.getServletContext().getRealPath("/images");
        String fileName = UUID.randomUUID().toString() + userphotoFileName.substring(userphotoFileName.lastIndexOf("."));

        File targetFile = new File(filePath,fileName);
        FileUtils.copyFile(userphoto,targetFile);

        return "regSuc";
}

  4、配置sturts.xml文件

<package name="user" extends="struts-default">
     <global-results>
     <!-- 文件上传失败转发到reg页面 -->
        <result name="input">/reg.jsp</result>
     </global-results>
     <action name="UserAction_*" class="com.ghq.action.UserAction" method="{1}">
         <result name="regSuc">/regSuc.jsp</result>
         <result name="regUI">/reg.jsp</result>         
     </action>
</package>

 

  拦截器完结公文过滤

  Struts2提供了三个文书上传的拦截器,通过安插拦截器能够轻松地落到实处文件过滤。在<action>成分中添加如下代码

<interceptor-ref name="fileUpload">
    <param name="allowedExtensions">jpg,gif,jpeg,bmp,png</param>
    <param name="maximumSize">5210</param>
</interceptor-ref>
<!— 配置系统默认的拦截器 -->
<interceptor-ref name="defaultStack"></interceptor-ref>

   参数含义:

  allowedExtensions:钦命允许上传的文件类型,两个类型此前逗号隔断

  maximumSize:钦命允许上传的文件大小,单位是字节

   能够在jsp页面中添加Struts2标签来输出错误新闻,不过一向调用含有Struts2标签的jsp文件时,会爆发如下卓殊

  <s:fielderror/>

The Struts dispatcher cannot be found.  This is usually caused by using Struts tags without the associated filter. Struts tags are only usable when the request has passed through its servlet filter, which initializes the Struts dispatcher needed for this tag.

  化解办法:

  利用逻辑视图和大体视图之间的呼应关系,使用逻辑视图来调用物理视图。

  例如地点的UserAction中的regUI方法正是达成了此作用,地址栏输入http://127.0.0.1:8080/struts2\_FileUpLoad/UserAction\_regUI.action,调用regUI方法,返回"regUI",在struts.xml文件中找到对应的物理视图映射reg.jsp来加载页面。

  错误消息不荒谬展现的是英文提醒,用户体格检查不好

 图片 2

  能够应用国际化新闻替换。编写upload.properties文件

 图片 3

  在struts.xml文件中配备以加载此文件

<constant name="struts.custom.i18n.resources" value="upload"/>

  配置后展现样式为

 图片 4

 

Struts文件下载

  文件下载开发流程:

  1、编写Action类

public class DownLoadAction {
    private String filename;
    private String finalName;

    public String getFilename() {
        return filename;
    }

    public void setFilename(String filename) {
        this.filename = filename;
    }

    public String getFinalName() {
        return finalName;
    }

    public InputStream getTargetFile() throws Exception{
        finalName = UUID.randomUUID().toString()+filename.substring(filename.lastIndexOf('.'));
        //获取ServletContext的对象
        ServletContext application = ServletActionContext.getServletContext();
     //ServletContext提供getResourceAsStream()方法,返回指定文件对应的输入流
     InputStream fin = application.getResourceAsStream(""+filename);

        return fin;
    }
}

 

  2、配置Action

<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="true" />
    <constant name="struts.action.extension" value="action"/>

    <package name="default" namespace="/" extends="struts-default">
        <action name="DownLoadAction_*" class="com.ghq.action.DownLoadAction" method="{1}">
            <result type="stream">
                <param name="inputName">targetFile</param>
                <!-- attachment用于指定是下载文件,而不是解析文件
                filename为了解决被下载的文件名是中文,下载的时候出现文件名乱码,所以指定下载的文件名 -->
                <param name="contentDisposition">attachment;filename=${finalName}</param>
            </result>
        </action>
    </package>
</struts>

 

   3、开发jsp页面

<a href="<%=path %>/DownLoadAction.action?filename=JavaEE项目开发实践.jpg">下载</a>

 

 

Struts2拦截器

  开发流程:

  一 、开发拦截器类

public class MyInterception extends AbstractInterceptor {
//实现拦截的方法
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        //在struts2框架中使用ActionContext模拟HttpServletRequest
        ActionContext request = invocation.getInvocationContext();
        //获取session
        Map<String, Object> session = request.getSession();
        String username = (String)session.get("username");
        if (username != null) {
            //放行请求,即将控制器交给下一个拦截器或者直接交给目标资源
            return invocation.invoke();
        }else{
            return "login";
        }    
    }
}

 

 

  此拦截器完成的服从是阻挡全体请求,判断用户是还是不是登录,登录则放行,否则转载到登录页面。

  二 、配置拦截器

 

<interceptors>
     <!-- 配置拦截器,自定义的拦截器不能直接拦截页面,但是可以拦截Action类的请求,必须是显示为Action使用拦截器才拦截 -->
   <!-- 定义拦截器-->
     <interceptor name="MyInterception" class="com.ghq.action.MyInterception"/>
       <!-- 定义拦截器栈 -->
        <interceptor-stack name="myStack">
          <interceptor-ref name="MyInterception"/>
           <interceptor-ref name="defaultStack"/>                
        </interceptor-stack>
<interceptors>

     <!-- 拦截器的配置中不能配置逻辑视图和物理视图的映射,所以配置为全局结果 -->
     <global-results>
         <result name="login">/login.jsp</result>
     </global-results>

 

 

 

  三 、使用拦截器

<!-- action元素不写class认为class属性值就是com.opensymphony.xwork2.ActionSupport -->
<action name="*">
  <result>/WEB-INF/jsp/{1}.jsp</result>
   <!-- 为Action应用拦截器,指定拦截器拦截其所在的Action请求 -->
   <interceptor-ref name="myStack"/>
</action>

 

相关文章