struts实现文件上传

通常情况下,文件上传分为三种,

1,上传到tomcat服务器,也就是放入到tomcat项目里,这样会导致图片或者文件和项目高偶藕性,可能会有导致其他的一些错误。

2,上传到指定文件目录,添加服务器与真实目录的映射关系,从而解耦上传文件与tomcat的关系文件服务器。

3,在数据库表中建立二进制字段,将图片存储到数据库。这种方式如果是数据只有几千几万的情况下,是可以的,但是如果数据一多,数据库就会数据量大,从而影响读取速度。

所以一般情况下,都会选择第二种方式来进行文件上传。下面,我使用第二种方式来讲解。

配置文件

首先,在struts中要实现文件上传的第一步,就是在pom.xml里面配置

<dependency>
		    <groupId>commons-fileupload</groupId>
		    <artifactId>commons-fileupload</artifactId>
		    <version>1.3.1</version>
		</dependency>

上传方法

配置好后,在web页面写方法。这里要写两个方法, preUpload()方法是跳转到页面选择文件进行上传, upload()则是进行上传操作。
在 upload()中, targetPath是你要存放的实际位置,severPath则是放到数据库中的地址,要让两者产生映射关系,则要在Servers项目中的server.xml里加一条映射关系。

在这里插入图片描述
在这里插入图片描述

	/**
	 * 跳转页面
	 * @return
	 */
	public String preUpload() {
		try {
			Clazz c = this.clzDao.list(clz, null).get(0);
			request.setAttribute("clz", c);
		} catch (InstantiationException | IllegalAccessException | SQLException e) {
			e.printStackTrace();
		}
		return "toUpload";
	}

	/**
	 * 实现上传
	 * @return
	 */
	public String upload() {
		try {
			//实际图片存储的位置
			String targetPath = "D:/img";
			//存到数据库中的地址
			String  severPath = "/upload";
			FileUtils.copyFile(file, new File(targetPath+"/"+fileFileName));
			clz.setPic(severPath+"/"+fileFileName);
			this.clzDao.edit(clz);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "toList";
	}

然后在配置文件中,配置好方法的路径。
就可以在jsp页面中调用了,

<a href="${pageContext.request.contextPath}/sy/clz_preUpload.action?cid=${c.cid}">图片上传</a>

当我点击这个按钮,则跳到选择文件页面。
这里因为要获取上传图片的是哪个,所以要隐藏域传参数过去。且表单也要设置成为多功能表单,再表单中添加一条属性

 enctype="multipart/form-data"

在这里要注意的是图片路径的name,因为这里的name要和其他两个参数在web文件中set/get出来。

    private File file;
    private String fileContentType;
    private String fileFileName;
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="${pageContext.request.contextPath}/sy/clz_upload.action" method="post" enctype="multipart/form-data">
		<input type="hidden" name="cid" value="${clz.cid} "/><br>
		<input type="hidden" name="cname" value="${clz.cname} "/><br>
		<input  type="hidden" name="cteacher" value="${clz.cteacher} "/><br>
		图片路径:<input type="file" name="file"/><br>
		<input type="submit">
	</form>
</body>
</html>

效果图:
在这里插入图片描述

当点击提交则运行upload()方法。
运行成功返回tolist重新刷新一次界面。
效果图:在这里插入图片描述

完善上传方法

能实现文件上传最主要的则是upload()方法里的
FileUtils.copyFile(file, new File(targetPath+"/"+fileFileName));
这一句。
但他并不适用,所以我们可以改进一下,

	/**
	 * 这是FileUtils.copyFile的底层,并且通过缓冲区进行了增强
	 * @param source
	 * @param target
	 */
	public void copyBufFile(File source,File target) {
		try {
			BufferedInputStream in = new BufferedInputStream(new FileInputStream(source));
			BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(target));
			byte[] bbuf = new byte[1024];
			int leng = 0;
			while((leng = in.read(bbuf))!=-1) {
				out.write(bbuf,0,leng);
			}
			in.close();
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

若没改进,在进行大文件上传的时候可能会文件丢失,等错误。

拦截器设置文件上传要求

而要设置上传文件的大小和格式的话,则要通过拦截器来设置,
要创建拦截器,
可以通过implements Interceptor和extends AbstractInterceptor
他们与filter的区别:先过filter再过interceptor。
这里我使用implements Interceptor。
然后要重写三个方法。我们只需写intercept就行了

public class OneInterceptor implements Interceptor{

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void init() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public String intercept(ActionInvocation arg0) throws Exception {
		
		return null;
	}
	
}

写好拦截器,然后在配置文件中配置好路径。

<interceptors>
	<interceptor name="one" class="com.zlk.crud.interceptor.OneInterceptor"></interceptor>
	<interceptor name="two" class="com.zlk.crud.interceptor.TwoInterceptor"></interceptor>
</interceptors>
	<interceptor-ref name="one"></interceptor-ref>
	<interceptor-ref name="two"></interceptor-ref>

这样就可以了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值