Struts2

Struts2

  Struts2出于传统的Struts1、WebWork两个经典的MVC框架发展兴起,无论是从Struts2企划角度来拘禁,还是打Struts2在实际上项目蒙之易用性来拘禁,Struts2都是一个要命不错之MVC框架。与民俗的Struts1对待,Struts2兴用普通的、传统的Java对象作为Action;Action的execute()方法不再与Servlet
API耦合,因而更易测试;支持更多之视图技术;基于AOP思想的拦截器机制,提供了极其好之而是扩展性;更精、更易于用之输入校验功能;整合的Ajax支持等,这些还是Struts2的光辉吸引力。

Struts2运之开支步骤

  1、在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>

   2、定义处理要的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之间的涉嫌。

1、包和命名空间

  Struts2采用包来组织Action,Action定义在包定义下完成,定义Action通过采用<package
…/>下之<action
…/>子元素来成功。每个包就是是大抵个Action、多个拦截器、多单拦截器引用的汇聚。

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

  每次定义一个package元素,都可指定一个namespace属性,用于指定该包对应的命名空间。命名空间要是为了处理以及一个Web应用被蕴藏同名Action的情形,同一个命名空间不克生同名的Action。

  当包指定了命名空间后,该包下所有的Action处理的URL应该是命名空间+Action名。

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

 

3、配置处理结果

  Action处理了用户的请求后,将返回一个普普通通字符串,整个普通字符串就是一个逻辑视图名叫。Struts2经过配备逻辑视图名和大体视图之间的投关系,一旦接收Action返回的逻辑视图名,系统会将相应的物理视图呈现给用户。

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

   全局结果

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

   该<result
…/>元素配置了一个大局结果,全局结果以对具备的Action都有效

 

Struts2决定文件上传

  文件上传的流程

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

  2、表单中设置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拦截器

  开发流程:

  1、开发拦截器类

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";
        }    
    }
}

 

 

  此拦截器实现之效益是阻止所有请求,判断用户是否登录,登录则放行,否则转发到登录页面。

  2、配置拦截器

 

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

 

 

 

  3、使用拦截器

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

 

相关文章