查看: 1327|回复: 0

[Oracle数据库] Java框架中的拦截器简介

发表于 2018-2-17 08:00:01
拦截器 一:

1.Struts 2架构分析

下面我们开始介绍结构图中所涉及的对象:
(1.)ActionMapper:提供了在请求和Action调用的映射信息,ActionMapper根据请求的URL来查找是否存在对应的Action调用请求,如果有,则返回一个描述,Action映射的ActionMapping对象,如果没有找到匹配的Action调用请求,则返回null。
(2.)ActionMapping:ActionMapping保存了调用Action的映射信息,其中必须保存Action的命名空间信息和name属性信息。
(3.)ActionProxy:ActionProxy在XWork和正真的Action之间充当代理,在执行Action的过程中,因为使用代理而非直接操作对象,所以可以在Action执行前后执行额外的操作。
(4.)ActionInvocation:标示Action的执行状态,它保存拦截器(按配置顺序),Action实例。Actionlnvocation由ActionProxy创建,通过调用invoke()方法开始Action的执行,执行顺序为按配置顺序执行拦截器,拦截器执行完毕后执行Action,Action执行结束后返回结果字符串,匹配对应的Result后,再一次执行拦截器。
(5.)Interceptor(拦截器):拦截器是一种可以再请求处理之前或者之后执行的Struts 2组件。拦截器是Struts 2重要特性,Struts 2框架的绝大多数功能是通过拦截器完成的。 二:Struts 2的拦截器 为什么使用拦截器:
便于请求数据的封装,类型转换,数据效验,解析上传文件,防止表单多次提交等。
拦截器的方法在Action执行之前或者执行之后自动地执行,从而将通用的操作动态插入到Action执行的前后,这样有利于系统的解耦。
2.拦截器栈:
从结构上看,拦截器相当于多个拦截器的组合,拦截器栈也是拦截器同样可以和其他拦截器(或拦截器栈)一起组成更强大的拦截器栈。
3.拦截器的工作原理:
拦截器围绕着Action 和Result的执行而执行。从上图可以看出,struts 2拦截器的实现原理和Servlte Filter的实现原理差不多,以链试执行,对正真要执行的方法(execute())进行拦截。首先执行Action配置的拦截器,在Action和Result执行之后拦截器在一次执行(与先前调用相反的顺序)在此链式的执行过程中,任何一个拦截器都可以直接返回,从而终止余下的拦截器,Action及Result的执行。
当ActionInvocation的invoke()方法被调用时,开始配置Action配置的第一个拦截器,拦截器做出相应处理后再次调用ActionInvocation的invoke()方法,ActionInvocation对象负责跟踪执行过程的状态,并且把控制权交给合适的拦截器。ActionInvocation通过调用拦截器的intercept()方法将控制转交给拦截器,因此拦截器的执行可以看做一个递归的过程,后续拦截器继续执行,直到最后一个拦截器。

4.拦截器有一个三阶段的,有条件的执行周期:
(1.)做一下Action执行前的预处理。拦截器可以准备,过滤,改变或者操作任何可以访问的数据,包括Action。
(2.)调用ActionInvocation的invoke()方法将控制权转交给后续的拦截器或者返回字符串终止执行,如果拦截器决定请求的处理不应该继续,可以不调用invoke()方法,而不是直接返回一个控制字符串。通过这种方式,可以停在后续的执行,并且决定将那个结果呈现给客户端。
(3.)做一下Action执行后的处理。此时拦截器依然可以改变可以发访问的对象和数据,只是此时框架已经选择了一个结果呈现给客户端了。
示例如下:
public class MytimerInterceptor extends AbstractInterceptor{

  1. @Override
  2. public String intercept(ActionInvocation invocation) throws Exception {
  3. // TODO Auto-generated method stub
  4. //执行Action之后的工作,获取开始执行时间
  5. long startTime=System.currentTimeMillis();
  6. System.out.println("开始时间:"+startTime);
  7. //2.执行后续拦截器
  8. String result=invocation.invoke();
  9. //3.执行action之后的工作,计算并输出时间
  10. long endTime=System.currentTimeMillis();
  11. long execTime=endTime-startTime;
  12. System.err.println("结束时间:"+endTime);
  13. System.err.println("总共用时:"+execTime);
  14. return result;
  15. }
复制代码

}

三:拦截器的配置 配置拦截器需要经过以下两个步骤: 通过元素定义拦截器。

通过元素来使用拦截器。
示例代码如下 struts.xml文件中:


class="cn.bdqn.interceptor.MytimerInterceptor">

  1. <action name="invocation" class="cn.bdqn.action.Invocation"
  2. method="time">
  3. <result name="success">/index.jsp</result>
  4. <interceptor-ref name="myTimer"></interceptor-ref>
  5. <!-- 引用默认拦截器栈 -->
  6. <interceptor-ref name="defaultStack"></interceptor-ref>
  7. </action>
复制代码

四:Struts 2内置拦截器 params 拦截器:
将请求中的数据设置到Action的属性上。 staticParams拦截器:
在配置文件中通过元素的子元素设置的参数设置到对应的Action的属性中。

servletConfig拦截器:
提供了将一种源于Servlet API的各种对象注入,Action当中的简洁方法,Action必须实现相应对应的接口,servletConfig拦截器才能将对应的Servlet对象注入Action中。
ServletAPI对象的接口如下:
接口 作用
ServletContextAware 设置ServletContext
ServletRequestAware 设置HttpServletRequest
ServletResponseAware 设置HttpServletResponse
ParameterAware 设置Map类型的请求参数
RequestAware 设置Map类型的请求(HttpServletRequest)属性
SessionAware 设置Map类型的会话(HttpSession)属性
ApplicationAware 设置Map类型的应用程序作用域对象(ServletContext)

fileUpload拦截器:
拦截器将文件和元数据从多重要求(multipart/form-data)转换为常规的请求数据,以便将他们设置在对应的Action属性上,实现文件上传。 validation拦截器:
该拦截器用于执行数据效验。 work flow拦截器:
该拦截器提供当数据效验错误时终止执行流程的功能。 exception拦截器:
该拦截器用于捕获异常,并且能够根据异常类型捕获的异常映射到用户自定义的错误页面。 五:自定义拦截器 改接口提供了三个方法:
Com.opensymphony.xwork2.interceptor.Interceptor
(1.)Void init();该拦截初始化后再改拦截器执行拦截之前,系统回调该方法。执行一次
(2.)void destroy();该方法跟init()方法对应。在拦截器销毁之前系统回调。
(3.)String intercept(ActionInvocation invocation)throws Exception:该方法是用户需要实现的拦截动作。该方法会返回一个字符串作为逻辑视图。
2.处此之外继承com.opensymphony.xwork2.interceptor.AbstractInterceptor类是更简单的一种实现拦截器的方式,AbstractInterceptor类提供了init()和destroy()方法的实现,这样我们只需要实现intercept()方法,就可以创建自己的拦截器了。 六:文件上传及下载:

首先导入JAR架包:

package cn.bdqn.action;包中文件:
UploadAction 类:
package cn.bdqn.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class UploadAction extends ActionSupport {
//封装文件标题属性
private String title;
//封装上传文件属性
private File upload; //upload 与jsp页面中 组件<name属性值保持一致
//获取提交的文件类型
private String uploadContentType;// 命名规则 name属性值开头
//封装上传文件名称
private String uploadFileName;//命名规则 name属性值开头
//获取文件上传的路径
private String savePath; //上传路径

  1. public String getUploadContentType() {
  2. return uploadContentType;
  3. }
  4. public void setUploadContentType(String uploadContentType) {
  5. this.uploadContentType = uploadContentType;
  6. }
  7. public String getUploadFileName() {
  8. return uploadFileName;
  9. }
  10. public void setUploadFileName(String uploadFileName) {
  11. this.uploadFileName = uploadFileName;
  12. }
  13. @Override
  14. public String execute() throws Exception {
  15. byte[] buffer=new byte[1024];
  16. //读取配置文件
  17. FileInputStream fis=new FileInputStream(this.getUpload());
  18. //保存文件,并设置保存目录路径
  19. FileOutputStream fos=new FileOutputStream(getSavePath()+"\\"+this.getUploadFileName());
  20. int length=fis.read(buffer);
  21. while (length>0) {
  22. //每次写入length长度的内容
  23. fos.write(buffer,0, length);
  24. length=fis.read(buffer);
  25. }
  26. fis.close();
  27. fos.flush();
  28. fos.close();
  29. return SUCCESS;
  30. }
  31. //获取上传文件的路径 通过读取保存目录获得保存路径
  32. public String getSavePath() {
  33. return ServletActionContext.getServletContext().getRealPath(savePath);
  34. }
  35. public void setSavePath(String savePath) {
  36. this.savePath = savePath;
  37. }
  38. public File getUpload() {
  39. return upload;
  40. }
  41. public void setUpload(File upload) {
  42. this.upload = upload;
  43. }
  44. public String getTitle() {
  45. return title;
  46. }
  47. public void setTitle(String title) {
  48. this.title = title;
  49. }
复制代码

}

ManyUploadAction 类:
package cn.bdqn.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class ManyUploadAction extends ActionSupport {
//封装文件标题属性
private String title;
//封装上传文件属性
private File[] upload; //upload 与jsp页面中 组件<name属性值保持一致

  1. //获取提交的文件类型
  2. private String[] uploadContentType;// 命名规则 <s:file name=upload >name属性值开头
  3. //封装上传文件名称
  4. private String[] uploadFileName;//命名规则 <s:file name=upload>name属性值开头
  5. //获取文件上传的路径
  6. private String savePath; //上传路径
  7. @Override
  8. public String execute() throws Exception {
  9. byte[] buffer=new byte[4096];
  10. for(int i=0;i<upload.length;i++){
  11. //读取配置文件
  12. FileInputStream fis=new FileInputStream(this.getUpload()[i]);
  13. //保存文件,并设置保存目录路径
  14. FileOutputStream fos=new FileOutputStream(getSavePath()+"\\"+this.getUploadFileName()[i]);
  15. int length=fis.read(buffer);
  16. while (length>0) {
  17. //每次写入length长度的内容
  18. fos.write(buffer,0, length);
  19. length=fis.read(buffer);
  20. }
  21. fis.close();
  22. fos.flush();
  23. fos.close();
  24. }
  25. return SUCCESS;
  26. }
  27. //获取上传文件的路径 通过读取保存目录获得保存路径
  28. public String getSavePath() {
  29. return ServletActionContext.getServletContext().getRealPath(savePath);
  30. }
  31. public void setSavePath(String savePath) {
  32. this.savePath = savePath;
  33. }
  34. public String[] getUploadContentType() {
  35. return uploadContentType;
  36. }
  37. public void setUploadContentType(String[] uploadContentType) {
  38. this.uploadContentType = uploadContentType;
  39. }
  40. public String[] getUploadFileName() {
  41. return uploadFileName;
  42. }
  43. public void setUploadFileName(String[] uploadFileName) {
  44. this.uploadFileName = uploadFileName;
  45. }
  46. public void setUpload(File[] upload) {
  47. this.upload = upload;
  48. }
  49. public File[] getUpload() {
  50. return upload;
  51. }
  52. public String getTitle() {
  53. return title;
  54. }
  55. public void setTitle(String title) {
  56. this.title = title;
  57. }
复制代码

}

FileDownAction类:
package cn.bdqn.action;

import java.io.BufferedInputStream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

import java.io.InputStream;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class FileDownAction extends ActionSupport {
private String inputPath; //下载文件的目录
public String getInputPath() {
return inputPath;
}

  1. public void setInputPath(String inputPath) {
  2. this.inputPath = inputPath;
  3. }
  4. //下载文件的文件名
  5. private String fileName;
  6. //读取下载文件的输入流
复制代码

// private InputStream inputStream;
//下载文件的类型
private String conetntType;

  1. public InputStream getInputStream() throws FileNotFoundException{
  2. /*return ServletActionContext
  3. .getServletContext()
  4. .getResourceAsStream(inputPath + "\\" + fileName);*/
  5. String path=ServletActionContext.getServletContext().getRealPath(inputPath);
  6. return new BufferedInputStream(new FileInputStream(path+"\\"+fileName));
  7. }
  8. @Override
  9. public String execute() throws Exception {
复制代码

/ //创建一个File对象
File file=new File(fileName);
//通过读取File对象创建输入流
inoutStream=new FileInputStream(file) ;
//得到实际的文件名称
fileName=file.getName();
//
conetntType=this.getConetntType();
/

  1. return SUCCESS;
  2. }
  3. public String getFileName() {
  4. return fileName;
  5. }
  6. public void setFileName(String fileName) {
  7. this.fileName = fileName;
  8. }
复制代码

/ public InputStream getInputStream() {
return inputStream;
}
/
public String getConetntType() {
return conetntType;
}
// public void setInputStream(InputStream inputStream) {
// this.inputStream = inputStream;
// }

  1. public void setConetntType(String conetntType) {
  2. this.conetntType = conetntType;
  3. }
复制代码

}

Jsp页面示例代码如下
Filedown.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>




  1. <title>My JSP 'filedown.jsp' starting page</title>
  2. <meta http-equiv="pragma" content="no-cache">
  3. <meta http-equiv="cache-control" content="no-cache">
  4. <meta http-equiv="expires" content="0">
  5. <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
  6. <meta http-equiv="description" content="This is my page">
  7. <!--
  8. <link rel="stylesheet" type="text/css" href="styles.css">
  9. -->
复制代码


点击此处下载文档

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




  1. <title>文件上传</title>
  2. <meta http-equiv="pragma" content="no-cache">
  3. <meta http-equiv="cache-control" content="no-cache">
  4. <meta http-equiv="expires" content="0">
  5. <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
  6. <meta http-equiv="description" content="This is my page">
  7. <!--
  8. <link rel="stylesheet" type="text/css" href="styles.css">
  9. -->
复制代码


  1. 文件一:<s:file name="upload" label="选择文件"></s:file><br/>
复制代码

<%-- 文件二:

--%>



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




  1. <title>文件上传</title>
  2. <meta http-equiv="pragma" content="no-cache">
  3. <meta http-equiv="cache-control" content="no-cache">
  4. <meta http-equiv="expires" content="0">
  5. <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
  6. <meta http-equiv="description" content="This is my page">
  7. <!--
  8. <link rel="stylesheet" type="text/css" href="styles.css">
  9. -->
复制代码


  1. 文件一:<s:file name="upload" label="选择文件"></s:file><br/>
  2. 文件二:<s:file name="upload" label="选择文件"/><br/>
复制代码




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




文件上传






  1. 您所上传的文件是:
  2. <s:property value="uploadFileName" />
  3. <br /> 文件类型:
  4. <s:property value="uploadContentType" />
  5. <br />
  6. <s:iterator value="uploadFileName" status="i">
  7. 图片:<img src="<%=basePath%>upload/<s:property />" />
  8. </s:iterator>
复制代码


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




文件上传







您所上传的文件是:


文件类型:


图片:



示例代码如下:struts.xml配置文件

"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">





  1. <action name="upload" class="cn.bdqn.action.UploadAction">
  2. <!-- param 标签的name值为action中定义的属性 -->
  3. <param name="savePath">/upload</param>
  4. <result name="success">/upload_success.jsp</result>
  5. </action>
  6. <!-- 多文件上传 -->
  7. <action name="mangUpload" class="cn.bdqn.action.ManyUploadAction">
  8. <!-- 通过设置参数方式保存路径 -->
  9. <param name="savePath">/upload</param>
  10. <result name="success">/manyupload_success.jsp</result>
  11. </action>
  12. <!-- 下载 注意事项,下载的文件必须提前存在upload文件中 -->
  13. <action name="download" class="cn.bdqn.action.FileDownAction">
  14. <!-- inputPath 为action 中 定义的下载文件目录 WebRoot下文件名upload -->
  15. <param name="inputPath">/upload</param>
  16. <result name="success" type="stream">
  17. <!-- contentType 下载文件类型 此处配置通用的 -->
  18. <param name="contentType">application/octet-stream</param>
  19. <!-- inputName 固定命名,为action中定义的inputStream类型的属性名称 -->
  20. <param name="inputName">inputStream</param>
  21. <!--
  22. attachment表示下载弹出对话框,filename下载文件名称 ${fileName}为读取action中下载文件名称
  23. -->
  24. <param name="contentDisposition">attachment;filename="${fileName}"</param>
  25. <!-- 上传或下载的缓冲区 4k -->
  26. <param name="bufferSize">4096</param>
  27. </result>
  28. </action>
  29. </package>
复制代码



回复

使用道具 举报