标签:
struts2本身自带有上传功能,所以只需要导入相应的包即可以使用,具体的哪些包,可以上网搜索,就不一一列举了。
先看一下前台代码:
<form action="fileUpload_upload" method="post" enctype="multipart/form-data">
<table>
<tr>
<td>上传文件:</td>
<td><input type="file" name="myFile"></td>
</tr>
<tr>
<td><input type="submit" value="上传"></td>
<td><input type="reset"></td>
</tr>
</table>
</form>
可以看到点击上传的时候,会调用fileUpload_upload.action,所以要到struts.xml中找到fileUpload_upload.action所对应的是哪个类中的哪个方法。
找到后,是下面这个类:
import java.io.*;
import com.arche.alderman.mvc.base.controller.BaseAction;
import org.apache.struts2.ServletActionContext;
/**
* Created by hexiaoyu on 2015/5/18.
*/
public class FileUpload extends BaseAction {
private File myFile;
private String myFileContentType;
private String myFileFileName;
/**
* 文件上传
* @return
* @throws Exception
*/
public String upload() throws Exception {
InputStream inputStream = new FileInputStream(myFile);
String uploadPath = ServletActionContext.getServletContext()
.getRealPath("/");
File toFile = new File(uploadPath,this.getMyFileFileName());
OutputStream os = new FileOutputStream(toFile);
byte[] buffer = new byte[1024];
int length = 0;
while ((length = inputStream.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
is.close();
os.close();
setServerResponseResult(ResponseStatusCode.REP_SERVER_HANDLE_SUCCESS, myFileFileName+"_"+myFileContentType, null);
return ServerCommonString.ACTION_RESULT_JSON;
}
public File getMyFile() {
return myFile;
}
public void setMyFile(File myFile) {
this.myFile = myFile;
}
public String getMyFileContentType() {
return myFileContentType;
}
public void setMyFileContentType(String myFileContentType) {
this.myFileContentType = myFileContentType;
}
public String getMyFileFileName() {
return myFileFileName;
}
public void setMyFileFileName(String myFileFileName) {
this.myFileFileName = myFileFileName;
}
}
此时上传图片是可以成功的,但是缺少:
1.检测后缀名不为图片的文件。
2.检测把后缀名强行改为.jpg的非图片文件。
关于解决第一点,则需要在struts.xml中添加一些文件上传的拦截器配置:
<package name="fileUpload" extends="global">
<action name="fileUpload_*" class="com.arche.alderman.constant.FileUpload" method="{1}">
<result name="result_json" type="json">
<param name="root">mResult</param>
</result>
<!--配置fileUpload的拦截器-->
<interceptor-ref name="fileUpload">
<!--配置允许上传的文件类型-->
<param name="allowedTypes">image/bmp,image/png,image/gif,image/jpeg</param>
<!--配置允许上传的文件大小单位字节-->
<param name="maximumSize">5242880</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
</action>
</package>
由于fileUpload这个拦截器是struts2自带的,所以可以直接使用,然后配置允许上传的文件类型和最大字节。这样就解决了第一个问题。
然后就是第二个,如何判断文件是否是图片文件了,这时候我在osc上问了一些大神,大家说可以用判断文件头的方式解决,我试了下,可以成功,只需要在上面的FileUpload这个类中再添加两个方法:
/**
* 得到上传文件的文件头
* @param src
* @return
*/
public static String bytesToHexString(byte[] src){
StringBuilder stringBuilder = new StringBuilder();
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
/**
* 根据制定文件的文件头判断其文件类型
* @param is
* @return
*/
public static String getTypeByStream(InputStream is){
byte[] b = new byte[4];
try {
is.read(b, 0, b.length);
} catch (IOException e) {
e.printStackTrace();
}
String type = bytesToHexString(b).toUpperCase();
if(type.contains("FFD8FF") || type.contains("89504E47") || type.contains("49492A00") || type.contains("424D")){
return "isImage";
}
return "notImage";
}
然后在得到inputStream的时候,调用
getTypeByStream()方法,把inputStream传进去,就可以判断是不是图片文件了
这里需要特别注意的是,传进去的inputStream会去掉文件头,所以最后上传的图片是已经损坏的,我没想到什么好的办法,就是创建了一个新的inputStream,把这个新的再拿去上传,这两个互不影响,测试是可以通过的。贴下完整的FileUpload.java供参考:
import java.io.*;
import com.arche.alderman.mvc.base.controller.BaseAction;
import org.apache.struts2.ServletActionContext;
/**
* Created by hexiaoyu on 2015/5/18.
*/
public class FileUpload extends BaseAction {
private File myFile;
private String myFileContentType;
private String myFileFileName;
/**
* 得到上传文件的文件头
* @param src
* @return
*/
public static String bytesToHexString(byte[] src){
StringBuilder stringBuilder = new StringBuilder();
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
/**
* 根据制定文件的文件头判断其文件类型
* @param is
* @return
*/
public static String getTypeByStream(InputStream is){
byte[] b = new byte[4];
try {
is.read(b, 0, b.length);
} catch (IOException e) {
e.printStackTrace();
}
String type = bytesToHexString(b).toUpperCase();
if(type.contains("FFD8FF") || type.contains("89504E47") || type.contains("49492A00") || type.contains("424D")){
return "isImage";
}
return "notImage";
}
/**
* 文件上传
* @return
* @throws Exception
*/
public String upload() throws Exception {
InputStream is = new FileInputStream(myFile);
if ("notImage".equals(getTypeByStream(is))){
setServerResponseResult(-1, "file type error", null);
return ServerCommonString.ACTION_RESULT_JSON;
}
InputStream inputStream = new FileInputStream(myFile);
String uploadPath = ServletActionContext.getServletContext()
.getRealPath("/");
File toFile = new File(uploadPath,this.getMyFileFileName());
OutputStream os = new FileOutputStream(toFile);
byte[] buffer = new byte[1024];
int length = 0;
while ((length = inputStream.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
is.close();
os.close();
setServerResponseResult(ResponseStatusCode.REP_SERVER_HANDLE_SUCCESS, myFileFileName+"_"+myFileContentType, null);
return ServerCommonString.ACTION_RESULT_JSON;
}
public File getMyFile() {
return myFile;
}
public void setMyFile(File myFile) {
this.myFile = myFile;
}
public String getMyFileContentType() {
return myFileContentType;
}
public void setMyFileContentType(String myFileContentType) {
this.myFileContentType = myFileContentType;
}
public String getMyFileFileName() {
return myFileFileName;
}
public void setMyFileFileName(String myFileFileName) {
this.myFileFileName = myFileFileName;
}
}
标签:
原文地址:http://my.oschina.net/xiaoyuHe/blog/416613