文件上传与拦截器
文件上传
在上一次的CRUD基础上我们来完成文件上传。上传到指定文件目录,添加服务器与真实目录的映射关系,从而解耦上传文件与tomcat的关系。
upload.jsp
<body>
<form id="bookForm" action="${pageContext.request.contextPath}/sy/m_upload.action" method="post" enctype="multipart/form-data" method="post">
<input type="hidden" name="SerialNo" value="${m.getSerialNo() }"><br>
<input type="hidden" name="Menuid" value="${m.getMenuid() }"><br>
<input type="hidden" name="Menuname" value="${m.getMenuname() }"><br>
<input type="hidden" name="menuURL" value="${m.getMenuURL() }"><br>
<input type="hidden" name="parentid" value="${m.getParentid() }"><br>
<!--注意:name对应的值决定了子控制器action属性的命名 -->
<input type="file" name="file">
<input type="submit" value="提交" ><br>
</form>
</body>
MenuAction
private File file;//和jsp界面里name对应的值保持一致,下面两个属性也是一样
private String fileContentType;
private String fileFileName;
/**
* 上传图片
* @return
* @throws IOException
* @throws SQLException
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public String upload() throws IOException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, SQLException {
//注意:在Linux下是没有E盘的,Linux下只有一个盘符,那么当打包到Linux服务器的时候需要改动代码
//这时通常是将targetPath对应的目录串配置到资源文件中,通过Properties类进行动态读取
//那么当需要将项目发布到Linux服务器时,只需要改变xxx.properties文件中targetPath=。。。。
//实际图片存储位置
String targetDir="D:/temp";
//存储到数据库中的地址
String serverPath="/upload";
FileUtils.copyFile(file, new File(targetDir+"/"+fileFileName));
//注意:数据库存放的是网络请求地址,而不是本地储存地址
m.setMenuURL(serverPath+"/"+fileFileName);
this.md.edit(m);
return "toList";
}
/**
* 跳转文件上传页面
* @return
* @throws SQLException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public String preupload() throws InstantiationException, IllegalAccessException, SQLException {
Menu menu = this.md.list(m, null).get(0);
request.setAttribute("m", menu);
return "toUpload";
}
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;
}
如果觉得用自带的上传方法比较慢,可以自己写一个方法,用法和前面的一样
/**
* FileUtils.copyFile的底层,并且通过缓冲区进行增强
* @param source
* @param tafget
*/
public void copyBufFile(File source,File tafget){
try {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(source));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(tafget));
byte[] bbuf = new byte[1024];
int len =0;
while((len = in.read(bbuf))!=-1) {
out.write(bbuf,0,len);
}
in.close();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
这样我们的文件就可以上传到指定文件目录,但是如果想要展示出来,就要添加服务器与真实目录的映射关系。如图中,找到server.xml。
将代码写入底部
<Context path="/struts/upload" docBase="D:/temp/"/>
<c:forEach items="${ml }" var="m">
<tr>
<td>${m.getSerialNo()}</td>
<td>${m.getMenuid()}</td>
<td>${m.getMenuname()}</td>
<td>
<img alt="" style="width:60px;height:60px;" src="${pageContext.request.contextPath}${m.getMenuURL()}">
</td>
<td>${m.getParentid()}</td>
<td>
<a href="${pageContext.request.contextPath}/sy/m_preSave.action?SerialNo=${m.getSerialNo()}">修改</a>
<a href="${pageContext.request.contextPath}/sy/m_del.action?SerialNo=${m.getSerialNo()}">删除</a>
<a href="${pageContext.request.contextPath}/sy/m_preupload.action?SerialNo=${m.getSerialNo()}">上传图片</a>
</td>
</tr>
</c:forEach>
这样我们的图片就能显示出来了。
拦截器
写拦截器可以有两种方法,一种是 implements Interceptor ,另一种是 extends AbstractInterceptor
写好类之后,在xml中配置一下就好了
struts-sy.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<package name="sy" extends="base" namespace="/sy">
<interceptors>
<interceptor name="one" class="com.shl.crud.interceptor.OneInterceptor"></interceptor>
<interceptor name="two" class="com.shl.crud.interceptor.TwoInterceptor"></interceptor>
</interceptors>
<action name="/demo_*" class="com.shl.web.HelloAction" method="{1}">
<result name="rs">/rs.jsp</result>
</action>
<action name="/stack_*" class="com.shl.test.DemoAction" method="{1}">
<result name="rs">/rs.jsp</result>
</action>
<action name="/m_*" class="com.shl.crud.web.MenuAction" method="{1}">
<interceptor-ref name="one"></interceptor-ref>
<interceptor-ref name="two"></interceptor-ref>
<result name="list">/mlist.jsp</result>
<result name="preSave">/medit.jsp</result>
<result name="toList" type="redirectAction">/m_list</result>
<result name="toUpload">/upload.jsp</result>
</action>
</package>
</struts>