Servlet文件上传

文件上传对于初学者是一个头痛的问题,最近在整理电脑的时候发现我大学里的demo,写的并不好,重要不是好与不好,而是把它分享出来,让初学者可以了解了解

1.编写文件上传的注解,作用域为属性范围

@Retention(RetentionPolicy.RUNTIME)
@Target({java.lang.annotation.ElementType.FIELD})
public @interface UploadForm {
public abstract String name();
}

2.上传文件的对象

public class Video {
private long id;
private String videoName;


@UploadForm(name = "title")
private String title;


@UploadForm(name = "introduc")
private String introduc;


@UploadForm(name = "category")
private long categoryId;


@UploadForm(name = "lables")
private String lable;


private Date date;


private long userId;


private String savePath;


private Double fileSize;

//自己生成getters and setters

}

下面被注解标注的就是表单要传到后台的值

3.编写文件上传公共的bean

public class FileBean<T> {

    private double fileSize;//文件大小
    private String fileName;//文件名称
    private String newName;//文件新的名称(上传时一般都会生成新的文件名以便存储保存路径)
    private List<String> errorMsg;//上传时产生的错误信息列表
    private T upLoadEntity;//上传文件时其他自定义上传属性的对象如上面的video

}

4.编写一些工具类

public class FileUtil {

    public void mkdir(String path) {
        File file = new File(path);
        if (!file.exists()) {
            file.mkdir();
        }


    }


    public static String getLastModifiedDate(File file) {
        return new Date(file.lastModified()).toString();
    }


    /**
    * To Suffix
    * 去除文件后缀
    * @param fileName
    * @return string
    */
    public static String toSuffix(String fileName) {
        String name = null;
        try {
            int index = fileName.lastIndexOf(".");
            name = fileName.substring(0, index);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return name;
    }

    public static boolean delete(String path) {
        try {
            File file = new File(path);
            file.delete();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

}

public class MathUtil {

/**
* calculate fileSize
* 计算文件有多少MB
* @param fileSize
* @return
*/
public static double calculateFileSize(long fileSize) {
// long a = 37531073;
Double number = (Long) fileSize / (1024.0 * 1024.0);
BigDecimal bigDecimal = new BigDecimal(number);
double newNumber = bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP)
.doubleValue();
return newNumber;
}

}

public class ReflectUtil {

public static Object getValue(Field field, String value) {
Object obj = null;
try{
if (field.getType().toString().equals("byte")
|| field.getType() == Byte.class) {
obj = Byte.valueOf(value);
} else if (field.getType().toString().equals("boolean")
|| field.getType() == Boolean.class) {
obj = Boolean.valueOf(value);
} else if (field.getType().toString().equals("double")
|| field.getType() == Double.class) {
obj = Double.valueOf(value);
} else if (field.getType().toString().equals("float")
|| field.getType() == Float.class) {
obj = Float.valueOf(value);
} else if (field.getType().toString().equals("int")
|| field.getType() == Integer.class) {
obj = Integer.valueOf(value);
} else if (field.getType().toString().equals("long")
|| field.getType() == Long.class) {
obj = Long.valueOf(value);
} else if (field.getType().toString().equals("short")
|| field.getType() == Short.class) {
obj = Short.valueOf(value);
} else if (field.getType() == Timestamp.class) {
obj = Timestamp.valueOf(value);
} else if (field.getType() == Date.class) {
obj = Date.valueOf(value);
} else if (field.getType() == Time.class) {
obj = Time.valueOf(value);
} else if (field.getType() == UUID.class) {
obj = UUID.fromString(value);
} else {
obj = value;
}
}catch (RuntimeException e) {
e.printStackTrace();
obj = null;
}
return obj;
}

}

public class CharacterUtil {

/**
* Randomly generated a string

* @param length
* @return
*/
public static String getRandomString(int length) {
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
StringBuffer buffer = new StringBuffer();
Random random = new Random();
for (int i = 0; i < length; i++) {
int number = random.nextInt(62);
buffer.append(str.charAt(number));
}
return buffer.toString();
}

}

以上几个工具都是很基础的,下面的核心工具需要使用它们

public class UploadTool<T> {
private Class<T> clazz;
private static final String EXCEPTION_MSG = " is unmarked by UploadFormAnnotation annotation";
public UploadTool(Class<T> clazz) {
this.clazz = clazz;
}
/**
* 如果上传失败,返回的文件bean包含上传文件的出错信息。 如果是上传成功,返回的文件bean中包含文件的详细信息
* 例如:文件大小和文件名,并且返回的错误信息为null

* @param request
*            HttpServletRequest
* @param tempPath
*            临时文件目录
* @param maxSize
*            限制文件大小上线
* @param uploadPath
*            上传的路径
* @param ext
*            允许上传的文件格式数组
* @return 包含文件信息的实体
*/
public FileBean<T> fileUpload(HttpServletRequest request, String tempPath,
long maxSize, String uploadPath, String[] ext) {
boolean flag = false;
double fileSize = 0;
String fileName = null;
String newName = null;
FileBean<T> fileBean = null;
// 获得文件列表
List<FileItem> items = this.getItem(request, tempPath, maxSize);
// 存储表单信息
List<FileItem> formFieldList = new ArrayList<FileItem>();
// 存储文件列表信息
List<FileItem> fileFieldList = new ArrayList<FileItem>();
// 记录错误信息
List<String> errorMsg = new ArrayList<String>();
if (items.size() > 0) {
for (FileItem item : items) {
// 如果是表单元素,添加到表单元素列表中
// 如果不是则添加文件列表中
if (item.isFormField()) {
formFieldList.add(item);
} else {
fileFieldList.add(item);
}
}
}
// 分解文件元素
for (FileItem fileItem : fileFieldList) {
// 判断是否选择了文件
if (fileItem.getName() != null && !"".equals(fileItem.getName())) {
String extName = fileItem.getName().split("\\.")[1]
.toLowerCase();// 获得文件后缀名
int count = 0;
for (int i = 0; i < ext.length; i++) {
if (ext[i].endsWith(extName)) {
count++;
}
}
// 上传文件的大小
long size = fileItem.getSize();
if (count == 0) {
String msgs = this.formateFileMsg(ext);
errorMsg.add(msgs);
// throw new RuntimeException(msg0);
} else if (size > maxSize) {
String msg0 = "File size no more than "
+ MathUtil.calculateFileSize(maxSize) + " MB";
errorMsg.add(msg0);
// throw new RuntimeException(msg0);
} else {
// 将文件大小单位转换为MB,并保留两位小数
fileSize = MathUtil.calculateFileSize(size);
fileName = fileItem.getName();// 获取上传文件全名,包括路径
// 去除掉文件后缀名
fileName = FileUtil.toSuffix(fileName);
newName = CharacterUtil.getRandomString(10) + "."
+ fileItem.getName().split("\\.")[1];
flag = this.upload(uploadPath, fileItem, newName, size);
}
} else {
String msg = "Didn't choose to upload a file";
errorMsg.add(msg);
// throw new RuntimeException(msg);
}
}
// 分解表单中元素,不包含文件
T t = this.setIntoObject(formFieldList);
// 将表单中的信息和上传文件的信息封装到通用的文件信息bean中
fileBean = new FileBean<T>();
if (flag && null != t) {
fileBean.setFileSize(fileSize);
fileBean.setFileName(fileName);
fileBean.setNewName(newName);
fileBean.setErrorMsg(null);
fileBean.setUpLoadEntity(t);
} else {
fileBean.setErrorMsg(errorMsg);
}
return fileBean;
}
/**
* 创建文件的磁盘工厂,并返回上传的文件列表

* @param request
*            HttpServletRequest
* @param tempPath
*            临时文件目录
* @param maxSize
*            上传的最大值
* @return 返回文件列表
*/
private List<FileItem> getItem(HttpServletRequest request, String tempPath,
long maxSize) {
List<FileItem> list = null;
try {
DiskFileItemFactory factory = new DiskFileItemFactory();// 创建磁盘工厂
factory.setRepository(new File(tempPath));// 临时文件目录
factory.setSizeThreshold(5 * 1024); // 最大缓存
ServletFileUpload upload = new ServletFileUpload(factory);// 创建处理工具
// upload.setSizeMax(maxSize);
list = upload.parseRequest(request);
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
/**
* 根据上传的表单控件获取到表单的值,把这些值封装到 上传实体对象中,返回实体对象

* @param formFieldList
* @return
*/
private T setIntoObject(List<FileItem> formFieldList) {
T t = null;
try {
t = clazz.newInstance();
for (FileItem formItem : formFieldList) {
String con = formItem.getString("utf-8");
String fieldName = formItem.getFieldName();
List<Field> fieldList = this.getFieldsByAnnotation(clazz);
for (Field field : fieldList) {
field.setAccessible(true);
UploadForm attr = field.getAnnotation(UploadForm.class);
if (fieldName.endsWith(attr.name())) {
Object obj = ReflectUtil.getValue(field, con);
field.set(t, obj);
}
}
}
} catch (InstantiationException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
return t;
}
private List<Field> getFieldsByAnnotation(Class clazz) {
Field[] allFields = clazz.getDeclaredFields();
List<Field> fields = new ArrayList<Field>();
for (Field field : allFields) {
if (field.isAnnotationPresent(UploadForm.class)) {
fields.add(field);
}
}
if (fields.size() <= 0) {
throw new RuntimeException(clazz + EXCEPTION_MSG);
} else {
return fields;
}
}
private String formateFileMsg(String[] ext) {
StringBuffer buffer = new StringBuffer();
buffer.append("You can only upload ");
for (String subfix : ext) {
buffer.append(subfix).append(" or ");
}
buffer.deleteCharAt(buffer.lastIndexOf(" "));
buffer.deleteCharAt(buffer.lastIndexOf("o"));
buffer.deleteCharAt(buffer.lastIndexOf("r"));
buffer.deleteCharAt(buffer.lastIndexOf(" "));
buffer.append(" format file");
return buffer.toString();
}
/**
* 将文件流根据上传路径写入磁盘,如果成功返回true,否则返回false

* @param uploadPath
*            上传的路径
* @param item
* @param newName
*            新的文件名
* @param fileSize
*            文件的大小
* @return 返回boolean
*/
private boolean upload(String uploadPath, FileItem item, String newName,
long fileSize) {
boolean flag = false;
InputStream input = null;// 定义输入流
OutputStream output = null;// 定一输出流
double precent = 0;// 定义上传进度
try {
input = item.getInputStream();// 获取上传文件输入流
output = new FileOutputStream(new File(uploadPath, newName));// 定义输出文件路径


int length = 0;
byte data[] = new byte[512];// 分块保存
// 读取内容
while ((length = input.read(data)) != -1) {
precent += length / (double) fileSize * 100D;
output.write(data, 0, length);// 保存内容
}
flag = true;
} catch (Exception e) {
flag = false;
} finally {
try {
input.close();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return flag;
}
}

5.上传请求servlet

public class FileUpload extends HttpServlet {
/**

*/
private static final long serialVersionUID = -5679009449927809174L;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
HttpSession session = req.getSession();
int userid = 0;
String name = (String) session.getAttribute("name");
List<String> list = new ArrayList<String>();
if (null == name) {
list.add("Sorry,You can not upload this video");
req.setAttribute("errorList", list);
req.getRequestDispatcher("error.jsp").forward(req, resp);
} else {
userid = new Integer((session.getAttribute("userId")).toString())
.intValue();// 获得用户id
int maxSize = 50 * 1024 * 1024;
UploadTool<Video> tool = new UploadTool<Video>(Video.class);//利用上传工具
String tempPath = getServletContext().getRealPath("/")
+ "uploadtemp";//上传文件的临时目录
String uploadPath = getServletContext().getRealPath("/")
+ "uploadfile";// 定义文件上传路径
String[] formate = {"mp4","flv"};
try {
FileBean<Video> fileBean = tool.fileUpload(req, tempPath,
maxSize, uploadPath, formate);//上传文件
List<String> errorMsg = fileBean.getErrorMsg();
if (null != errorMsg) {//调到错误页面
list.addAll(errorMsg);
req.setAttribute("errorList", list);
req.getRequestDispatcher("error.jsp").forward(req, resp);
} else {
Video video = fileBean.getUpLoadEntity();
String newName = fileBean.getNewName();//生成新的文件名
String savePath = "uploadfile/" + newName;//目录加文件名组成新的路径存入数据库
//将从表但获取的
Video model = new Video();
model.setCategoryId(video.getCategoryId());
model.setIntroduc(video.getIntroduc());
model.setLable(video.getLable());
model.setTitle(video.getTitle());


model.setDate(DateTimeUtil.getSqlDate());
model.setFileSize(fileBean.getFileSize());//上传的文件大小
model.setUserId(userid);
model.setSavePath(savePath);//文件的保存路径
model.setVideoName(fileBean.getFileName());//上传文件的原名称
VideoService videoDao = videoDao = (VideoService) new PropertiesBeanFactory()
.getName("videoDao");//使用工厂模式
boolean flag = videoDao.save(model);//数据存入数据库
if (flag) {
req.getRequestDispatcher("/upload/uploadsuccess.jsp")
.forward(req, resp);
} else {
//如果文件信息添加导数据库失败,则删除当前上传的文件
String realPath = req.getSession().getServletContext()
.getRealPath(savePath);
//根据路径删除文件
FileUtil.delete(realPath);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

6.上传页面编写

<form action="./FileUpload" enctype="multipart/form-data" method="post">
标题:<input type="text" name="title" />
简介:<input type="text" name="introduc" />
分类:<select name="category"></select>
标签:<input type="text" name="lables" />
文件:<input type="file" name="fileName" />
    <input type="submit" value="上传" />
    <input type="reset" value="取消" />
</form>

表单中每个输入项的name值要和注解指定的一样,@UploadForm(name = "title") //表单中必须写name为title。否则封装的工具不能得到正确的值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值