`

struts03:拦截器、过滤器与拦截器的区别、文件上传

 
阅读更多

第一:概念

1.拦截器(默认完成了struts基本功能,我们写的方法专门做我们自己的事):过滤器filter是针对web请求和响应进行过滤。拦截器interceptor是针对某个方法执行之前和之后进行拦截(特定的逻辑操作)(其实就是在前后加特定的功能)。
例如:params拦截器:负责将请求参数设置成为action属性。
      servletConfig:拦截器将源于servlet的api中的各种对象注入到action
      fileUpdate拦截器:对文件上提供支持。
      exception拦截器:捕获异常,并且将异常映射到用户自定义的错误页面。
      vaildation拦截器:调用验证框架进行数据验证。
      workflow拦截器:调用action类的validate(),执行编码验证。
2.代理对象:包含原来的功能(目标对象的功能)和扩展的功能。原理是代理对象和被代理对象实现同一个接口。(代理对象持有被代理类的引用类)
3.实现拦截器的步骤:注意:拦截器随着项目的加载而加载
  ---1.创建一个类实现interceptor接口(struts的接口),重写三个方法(我们是在struts框架下的拦截器,拦截的是action,也就是对execute方法(action中的方法)进行前后拦截)
         在重写的方法中的Actioninvoaction形参中能够获得目标对象和代理对象。拦截器中返回被代理对象的返回结果。
  ---2.配置Interceptor拦截器,并注册到action中(针对action中的方法进行拦截)
        interceptor-stack 是拦截器栈,<interceptor-ref name="defaultStack"></interceptor-ref>是引用struts2默认的拦截器栈,只要上面有extends=struts-default这个属性,name="defaultStack"就会有效。
3.Actioninvoaction.getAction是得到目标对象。
 Actioninvoaction.invoke是调用应用action(目标对象)中的方法。(并继续执行剩余的拦截器和Action
)。
 ActionInvocation(action印我k神)是获得应用action的状态
4.配置拦截器:在struts.xml中,<interceptors>进行配置拦截器,这个标签里放的是拦截器或者是拦截器栈。(因特塞pt)
里面的<interceptor>标签是通过反射创建一个拦截器对象,也就是说这样在项目加载的时候创建对象。
里面的拦截器栈<interceptor-stack>里面的<interceptor-ref>是指拦截器栈中引用哪个拦截器。注意:拦截器栈就是在所有拦截器中选出几个最基本最常用的放在一起。
也就是说我的拦截器中包含系统拦截器栈,还有我的拦截器,因为只有加了系统的才能完成struts中拦截的基本功能。(把系统的拦截器栈放在我的拦截器前面,是因为栈的先进后出原则)。
最后把拦截器栈加入action中,表示给这个action加入了拦截器。
5.文件上传:其实就是在使用系统的拦截器fileUpload类。把内存中的临时文件拷贝到磁盘中。
    ---1.固定的属性(因为我们用的是系统的)。三个属性:文件域。文件的名字,文件内容的类型
   

注意:cope是将文件从一个文件拷贝到另外一个文件。
      FileUtils是struts提供的,在commons-io-1.3.2.jar这个jar包中

/* (1)如果没有下一个拦截器,invocation.invoke()方法
 *     的执行,实际上是action的execute的方法的执行
 * (2)如果有下一个拦截器,invocation.invoke()方法的执行,
 *     是指下一个拦截器的interpt方法的执行*/

项目执行过程:jsp页面--->struts核心控制器(org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter)-->struts2核心配置文件(struts.xml)
注意:action中的属性如果绑定到了值栈上下文中,其实也就是绑定到了值栈中,也同时绑定到了值栈上下文中的request对象中。
  问1:为什么action中的属性如果绑定到了值栈上下文中,其实也就是绑定到了值栈中?
     答:因为值栈上下文中有个固定绑定叫action(放的是action层的属性),这个固定绑定的键是action,值就是值栈,因此如果是把action层属性放到值栈上下文中了,也就是把属性放在了值栈了
  问2:为什么也同时绑定到了值栈上下文中的request对象中?
     答:放在值栈上下文中的东西默认也放在了request对象中。

 

 

 

第二:拦截器

1.jsp页面:表单提交到struts.xml里的login里

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
   
    <title>My JSP 'index.jsp' starting page</title>
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">   
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page">
 <!--
 <link rel="stylesheet" type="text/css" href="styles.css">
 -->
  </head>
 
  <body>
    <form action="login.action" method="post">
     姓名:<input type="text" name="uname" value=""><br/>
     密码:<input type="text" name="upwd" value=""><br/>
     角色:<input type="text" name="role" value=""><br/>
     <input type="submit" name="sub" value=" 登 录 "><br/>
    </form>
    <s:debug></s:debug>
  </body>
</html>

2.action类:struts.xml的login将会调用class="com.action.UserAction"

package com.action;

import java.util.ArrayList;
import java.util.Map;

import javax.servlet.http.HttpSession;

import com.opensymphony.xwork2.ActionContext;

public class UserAction {
 private String uname;
 private String upwd;
 private String role;
 //private ArrayList<String> opList=new ArrayList<String>();
 public String getUname() {
  return uname;
 }
 public void setUname(String uname) {
  this.uname = uname;
 }
 public String getUpwd() {
  return upwd;
 }
 public void setUpwd(String upwd) {
  this.upwd = upwd;
 }
 public String getRole() {
  return role;
 }
 public void setRole(String role) {
  this.role = role;
 }
 
 
 /*public ArrayList<String> getOpList() {
  
  return opList;
 }
 public void setOpList(ArrayList<String> opList) {
  this.opList = opList;
 }*/
 
 
 public String execute(){
  if(uname.equals("admin")&&upwd.equals("0000")){
   ActionContext ac = ActionContext.getContext();
   Map<String,Object> session=ac.getSession();
   session.put("role",role);
   //opList.add("lllllllllll");
   //session.put("opList",opList);
   return "success";
  }else{
   return "index";
  }
 }

}

3.拦截器的调用(但是在调用class="com.action.UserAction"这个类之前先会进入拦截器(看struts.xml可以看出来))

package com.action;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

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

public class MyInterceptor implements Interceptor{

 @Override
 public void destroy() {
  // TODO Auto-generated method stub
  System.out.println("---------destroy");
 }

 @Override
 public void init() {
  // TODO Auto-generated method stub
  System.out.println("---------init");
 }
 
     //前后拦截action
 @Override
 public String intercept(ActionInvocation invocation) throws Exception {
  //1.调用方法之前拦截
  Object obj = invocation.getAction();//得到被代理对象(目标对象),得到此时被拦截器拦截的action
  System.out.println("----------被拦截action:"+obj);
  //2.调用方法
   String result=invocation.invoke();//调用应用action中的方法(由于拦截器配置在了action中,因此拦截器对象能够找到这个应用action(目标对象))。调用完成后继续执行剩余的过滤器和action
   //3.调用之后拦截
   ActionContext ac = ActionContext.getContext();//获得上下文对象
   Map<String, Object> session = ac.getSession();//通过值栈上下文对象获得该对象的一个固定绑定:session
  Object role = session.get("role");
  if(result.equals("success")){
   List<String> opList=new ArrayList<String>();
   //UserAction u=new UserAction();
   //ArrayList<String> opList = u.getOpList();
   if(String.valueOf(role).equals("1")){
    opList.add("会员管理");
    opList.add("---会员添加");
    opList.add("---会员列表");
    opList.add("商品管理");
    opList.add("---商品添加");
    opList.add("---商品列表");
   }else
    if(String.valueOf(role).equals("2")){
     opList.add("任务管理");
     opList.add("---定制任务");
     opList.add("---任务分配");
    }
   session.put("opList",opList);
   return result;
  }
  return "index";
 }

}

5.返回成功

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
   
    <title>My JSP 'success.jsp' starting page</title>
   
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">   
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page">
 <!--
 <link rel="stylesheet" type="text/css" href="styles.css">
 -->

  </head>
 
  <body>
  ${session.opList}
  <h2>dddddddddd</h2>
    <s:property value="opList"/><br><!-- 获得的是值栈中的属性,由于opList不是action层的属性,因此也不是值栈中的属性,因此不能输出 -->
    <c:forEach var="str" items="${opList}">
        ${str}<br>
    </c:forEach>
    <s:debug/>
  </body>
</html>

 

第三:文件上传

1.jsp页面:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
   
    <title>My JSP 'index.jsp' starting page</title>
 <meta http-equiv="pragma" content="no-cache">
 <meta http-equiv="cache-control" content="no-cache">
 <meta http-equiv="expires" content="0">   
 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
 <meta http-equiv="description" content="This is my page">
 <!--
 <link rel="stylesheet" type="text/css" href="styles.css">
 -->
  </head>
 
  <body>
    <form action="faction.action" method="post"  enctype="multipart/form-data">
     img:<input type="file" name="img" value=""><br/>
     
     <input type="submit" name="sub" value=" 上 传 "><br/>
    </form>
  </body>
</html>

 

2.struts.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
    <package name="text_file" namespace="" extends="struts-default">
       <action name="faction" class="com.action.FileAction">
           <result name="success">success.jsp</result>
       </action>
   
    </package>
</struts>   

 

3.action层

package com.action;

import java.io.File;
import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;

import freemarker.template.utility.Execute;

public class FileAction {
 private File img;//文件,这里这个文件保存的是点击上传按钮时候的临时文件
 private String imgFileName;//文件名
 private String imgContenttype;//文件类型,文件内容的类型,不是文件后缀
 public File getImg() {
  return img;
 }
 public void setImg(File img) {
  this.img = img;
 }
 public String getImgFileName() {
  return imgFileName;
 }
 public void setImgFileName(String imgFileName) {
  this.imgFileName = imgFileName;
 }
 public String getImgContenttype() {
  return imgContenttype;
 }
 public void setImgContenttype(String imgContenttype) {
  this.imgContenttype = imgContenttype;
 }
 
 public String execute() {
  System.out.println("临时文件:"+img);//\Tomcat 6.0\work\Catalina\localhost\chu_struts03_file\\upload__5c8a98d2_1495a86f8cd__8000_00000000.tmp;
  //1.获得文件在tomcat服务器上的保存目录。其实就是获得img文件夹的绝对路径
  /*
   * ServletContext application = ServletActionContext.getServletContext();//这是通过ServletActionContext获得servlet技术中的application
    application.getRealPath("img");//获得绝对路径(getRealPath方法没过时)
   HttpServletRequest request = ServletActionContext.getRequest();//通过servletActionContext对象获得servletAPI中的request对象
   request.getRealPath("img");//获得绝对路径(他的getRealPath方法过时了)
   */
  String path=ServletActionContext.getServletContext().getRealPath("img");//这是目录,当项目启动的时候webroot下面的img文件夹将部署到tomcat服务器中,这里是找到这个文件夹的绝对(物理)路径
        System.out.println("----------"+path);//F:\Tomcat 6.0\webapps\chu_struts03_file\img
        //2.这是获得文件在tomcat下保存的文件。也就是目录+文件名。
        File f=new File(path+"/"+imgFileName);//这是目录下的文件
        System.out.println("文件:"+f);//F:\Tomcat 6.0\webapps\chu_struts03_file\img\1247561947.jpg
        try {
         //拷贝文件,第一个参数是原来文件(也就是我们的属性,当我们点击按钮的时候文件已经被保存到这里了,可以看jsp中写了name="img"。第二个参数是我要拷贝到哪个文件里)
   FileUtils.copyFile(img, f);//从tomcat下的临时文件换成tomcat服务器下固定的文件
  } catch (IOException e) {
   e.printStackTrace();
  }
        return "success";
 }
 
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics