struts2文件上传

这篇博客主要介绍了Struts2中文件上传的实现,包括JSP界面的设置、Action的定义以及服务器配置。同时,深入探讨了Struts2拦截器的工作原理、拦截器与过滤器的区别,并给出了自定义拦截器的示例。文章还强调了在文件上传中设置enctype属性的重要性,以及拦截器在执行流程中的角色。

struts文件上传

简单的上传,jsp界面。我们这里是在上一次的基础上修改图片的路径的,jsp界面我们需要使用隐藏域穿值。
注意:我们的表单提交必须使用 enctype="multipart/form-data"

<form action="${pageContext.request.contextPath }/sy/clz_upload.action" method="post" enctype="multipart/form-data">
	<input type="hidden" name="cid" value="${clz.cid }">
	<input type="hidden" name="cname" value="${clz.cname }">
	<input type="hidden" name="cteachar" value="${clz.cteachar }">
	<!-- 注意:name对应的值 -->
	<input type="file" name="file" value="${clz.pic }">
	<input type="submit" value="提交">
</form>

定义Action
Action中的三个变量:

File file : 对于单文件上传类型,这个文件的名字必须是File类型的并且变量的名字要和前端表单的文件控件的name属性一致,会给这个变量赋值指向处于服务器上传文件临时目录中的那个文件。

fileContentType :文件的MIME类型,比如image/jpeg,application/octet-stream之类的。

fileFileName : 文件名,文件在上传之前在客户端的磁盘上存在就必然有一个名字,这里就是那个名字。

总结一下单文件上传:

1.表单的enctype="multipart/form-data"属性。

2.Action的三个成员变量file(文件本身),fileContentType(文件MIME类型),fileFileName(文件名)。

	private File file;//与表单file控件的name一致,指向了服务器临时目录中的上传文件
	private String fileContentType;//File变量的名+ContentType,表示文件的MIME类型
	private String fileFileName;//File变量的名+FileName,表示文件上传之前的名称
	
	public File getFile() {
		return file;
	}

	public void setFile(File file) {
		this.file = file;
	}

	public String getFileContentType() {
		return fileContentType;
	}

	public void setFileContentType(String fileContentType) {
		this.fileContentType = fileContentType;
	}

	public String getFileFileName() {
		return fileFileName;
	}

	public void setFileFileName(String fileFileName) {
		this.fileFileName = fileFileName;
	}

	/**
	 * 跳转新增修改页面的公用方法
	 * @return
	 */
	public String preSave() {
		if(clz.getCid()!=0) {
			try {
				Clazz c =this.clzDao.list(clz, null).get(0);
				request.setAttribute("clz",c );
			} catch (InstantiationException | IllegalAccessException | SQLException e) {
				e.printStackTrace();
			}
		}
		return "preSave";
	}
	
	
	/**
	 * 图片上传
	 * @return
	 * @throws Exception 
	 */
	public String upload() throws Exception {
		//注意在Linux下是没有E盘的,Linux下只有一个盘符;那么以为这,当打包到Linux服务器的时候需要改变代码
		//这个时候通常是这样解决的,将targetPath对应目录串,配置到资源文件中,通过Properties类进行动态读取
		//那么需要将项目发布到Linux服务器的时候,只需要改变xxx.targetPath
		//实际图片存储的位置
		String targetDir = "D:/pppp";
		//存储数据库中的地址
		String severPath="uploads";
		//FileUtils.copyFile(file, new File(targetDir+"/"+fileFileName));
		copyBuffile(file, new File(targetDir+"/"+fileFileName));
		//注意:数据库存放的是网络地址
		clz.setPic(severPath+"/"+fileFileName);
		this.clzDao.edit(clz);
		return "toList";
	}
	
	/**
	 * FileUtils.copyFile的底层,并且通过缓冲流加强
	 * @param Source
	 * @param target
	 * @throws Exception
	 */
	public void copyBuffile(File Source,File target) throws Exception {
		BufferedInputStream in = new BufferedInputStream(new FileInputStream(Source));
		BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(target));
		byte[] bbuf = new byte[1024];
		int len = 0;
		while((len=in.read(bbuf))!=-1) {
			out.write(bbuf,0,len);
		}
		in.close();
		out.close();
		
	}
	
	
	/**
	 * 跳转上传页面
	 * @return
	 * @throws SQLException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public String preUpload() throws InstantiationException, IllegalAccessException, SQLException {
		Clazz c =this.clzDao.list(clz, null).get(0);
		request.setAttribute("clz",c );
		return "toUpload";
	}	

这里还有一个需要注意的,需要修改servers里面的配置文件server.xml 在最后加上

<Context path="/T224_strutr/uploads" docBase="D:/pppp/"/>

path是网络文件,docBase本地文件夹

效果展示

在这里插入图片描述

拦截器

拦截器和过滤器的区别

拦截器是对调用的Action起作用,它提供了一种机制可以使开发者定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式,很多业务逻辑都是靠拦截实现的,比如校验,验证登录权限(比如下载时跳转到登陆页面)等等。

过滤器是对整个的请求过程起作用!换句话说就是拦截器没有过滤器的范围广。过滤器是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符(聊天室经常用到的,一些骂人的话,比如判断用户提交的数据是否存在非法字符等等。

Struts2拦截器是Struts2中的一个很重要的功能,本质是代理模式。本文将从概念开始,为大家讲解Struts2拦截器的实现原理以及如何定义等等内容。

理解Struts2拦截器

  1. Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP的一种实现。
  2. 拦截器栈(Interceptor Stack)。Struts2拦截器栈就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被调用。

执行责任

这个执行职责有3种选择:

  1. 中止整个执行,直接返回一个字符串作为resultCode
  2. 通过递归调用负责调用堆栈中下一个Interceptor的执行
  3. 如果在堆栈内已经不存在任何的Interceptor,调用Action

实现Struts2拦截器原理

Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts2会查找配置文件,并根据其配置实例化相对应的拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器

定义Struts2拦截器

Struts2规定用户自定义拦截器必须实现com.opensymphony.xwork2.interceptor.Interceptor接口。该接口声明了3个方法

void init();    //初始化方法
void destroy();  //结束方法
String intercept(ActionInvocation invocation)throws Exception; //主要执行方法主体方法

拦截器例子

TowInterceptor


public class TowInterceptor  implements Interceptor {

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		System.out.println("我是TowInterceptor的结束方法");
	}

	
	@Override
	public void init() {
		// TODO Auto-generated method stub
		System.out.println("我是TowInterceptor的初始化方法");
	}

	@Override
	public String intercept(ActionInvocation actionInvocation) throws Exception {
		// TODO Auto-generated method stub
		//拦截器中request和respones的方式实例
		HttpServletRequest request = ServletActionContext.getRequest();
		HttpServletResponse response =  ServletActionContext.getResponse();
		
		System.out.println("-------TowInterceptor-----------start");
		String invoke=actionInvocation.invoke();//放行
		System.out.println("-------TowInterceptor-----------start");
		
		return invoke;
	}
	
}

OneInterceptor

public class OneInterceptor implements Interceptor {

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		System.out.println("我是OneInterceptor的结束方法");
	}

	@Override
	public void init() {
		// TODO Auto-generated method stub
		System.out.println("我是OneInterceptor的初始化方法");
	}

	@Override
	public String intercept(ActionInvocation actionInvocation) throws Exception {
		// TODO Auto-generated method stub
	    System.out.println("-------OneInterceptor-----------start");
		String invoke=actionInvocation.invoke();//放行
		System.out.println("-------OneInterceptor-----------end");
		return invoke;
	}
	
}

在Struts的配置文件中配置一下拦截器

<struts>
	<!-- 多了一个包的概念,区分分类 -->
	<package name="sy" extends="base" namespace="/sy">
	
		<!-- 定义这两个拦截器 -->
		<interceptors>
				<interceptor name="one" class="com.crud.web.OneInterceptor"></interceptor>
				<interceptor name="two" class="com.crud.web.TowInterceptor"></interceptor>
	
				<!-- 配置拦截器栈 -->
	            <interceptor-stack name="myStack">
	                <!-- 默认自带的拦截器,当配置自己的拦截器时不再走默认的拦截器,所以需要调用自带的拦截器,并写在第一行 主要这是关键,如果不加 defaultStack拦截器就会导致from表达提交值失效-->
	                <interceptor-ref name="defaultStack"/>
	                <!-- 加入自己的拦截器 -->
	                <interceptor-ref name="one"/>
	                <interceptor-ref name="two"/>
	            </interceptor-stack>
		</interceptors>

		
		<action name="/clz_*" class="com.crud.web.ClazzAction" method="{1}">
		
			<!-- 引入拦截器栈,只要请求clz的相关方法就会触发拦截栈中定的拦截器 -->
			<interceptor-ref name="myStack"></interceptor-ref>
			
			<result name = "list"> /clzList.jsp</result>
			<result name = "preSave"> /clzEdit.jsp</result>
			<result name = "toList" type="redirectAction"> clz_list</result>
			<result name = "toUpload"> /upload.jsp</result>
		</action>
		
	</package>
</struts>

结果:
-------OneInterceptor-----------start
-------TowInterceptor-----------start
你进入了Action方法内容
-------TowInterceptor-----------start
-------OneInterceptor-----------end

org.apache.struts2.interceptor.FileUploadInterceptor
拦截类设置上传文件,可以传什么类型的文件?可以传多大的文件?传过来以后放哪儿?叫什么名字?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值