第一点:Java代码实现文件上传

FormFile file = manform.getFile();

String newfileName = null;

String newpathname = null;

String fileAddre = "/numUp";

try

{

InputStream stream = file.getInputStream();// 把文件读入

String filePath = request.getRealPath(fileAddre);//取系统当前路径

File file1 = new File(filePath);//添加了自动创建目录的功能

((File)file1).mkdir();

newfileName = System.currentTimeMillis()

+ file.getFileName().substring(

file.getFileName().lastIndexOf('.'));

ByteArrayOutputStream baos = new ByteArrayOutputStream();

OutputStream bos = new FileOutputStream(filePath + "/"

+ newfileName);

newpathname = filePath + "/" + newfileName;

System.out.println(newpathname);

// 建立一个上传文件的输出流

System.out.println(filePath + "/" + file.getFileName());

int bytesRead = 0;

byte[] buffer = new byte[8192];

while ((bytesRead = stream.read(buffer, 0, 8192)) != -1)

{

bos.write(buffer, 0, bytesRead);// 将文件写入服务器

}

bos.close();

stream.close();

}

catch (FileNotFoundException e)

{

e.printStackTrace();

}

catch (IOException e)

{

e.printStackTrace();

}

第二点:Jsp页面上实现文件上传

package com.vogoal.util;

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.Date;

import java.util.Hashtable;

import javax.servlet.ServletInputStream;

import javax.servlet.http.HttpServletRequest;

public class JspFileUpload

{

/** request对象 */

private HttpServletRequest request = null;

/** 上传文件的路径 */

private String uploadPath = null;

/** 每次读取得字节的大小 */

private static int BUFSIZE = 1024 * 8;

/** 存储参数的Hashtable */

private Hashtable paramHt = new Hasptable();

/** 存储上传的文件的文件名的ArrayList */

private ArrayList updFileArr = new ArrayList();

/**

* 设定request对象。

*

* @param request

*            HttpServletRequest request对象

*/

public void setRequest(HttpServletRequest request) {

this.request = request;

}

/**

* 设定文件上传路径。

*

* @param path

*            用户指定的文件的上传路径。

*/

public void setUploadPath(String path) {

this.uploadPath = path;

}

文件上传上处理程序

/**

* 文件上传处理主程序。�������B

*

* @return int 操作结果 0 文件操作成功;1 request对象不存在。 2 没有设定文件保存路径或者文件保存路径不正确;3

*         没有设定正确的enctype;4 文件操作异常。

*/

public int process() {

int status = 0;

// 文件上传前,对request对象,上传路径以及enctype进行check。

status = preCheck();

// 出错的时候返回错误代码。

if (status != 0)

return status;

try {

// ��参数或者文件名�u��

String name = null;

// 参数的value

String value = null;

// 读取的流是否为文件的标志位

boolean fileFlag = false;

// 要存储的文件。

File tmpFile = null;

// 上传的文件的名字

String fName = null;

FileOutputStream baos = null;

BufferedOutputStream bos = null;

// ��存储参数的Hashtable

paramHt = new Hashtable();

updFileArr = new ArrayList();

int rtnPos = 0;

byte[] buffs = new byte[BUFSIZE * 8];

// �取得ContentType

String contentType = request.getContentType();

int index = contentType.indexOf("boundary=");

String boundary = "--" + contentType.substring(index + 9);

String endBoundary = boundary + "--";

// �从request对象中取得流。

ServletInputStream sis = request.getInputStream();

// 读取1行

while ((rtnPos = sis.readLine(buffs, 0, buffs.length)) != -1) {

String strBuff = new String(buffs, 0, rtnPos);

// 读取1行数据�n��

if (strBuff.startsWith(boundary)) {

if (name != null && name.trim().length() > 0) {

if (fileFlag) {

bos.flush();

baos.close();

bos.close();

baos = null;

bos = null;

updFileArr.add(fName);

} else {

Object obj = paramHt.get(name);

ArrayList al = new ArrayList();

if (obj != null) {

al = (ArrayList) obj;

}

al.add(value);

System.out.println(value);

paramHt.put(name, al);

}

}

name = new String();

value = new String();

fileFlag = false;

fName = new String();

rtnPos = sis.readLine(buffs, 0, buffs.length);

if (rtnPos != -1) {

strBuff = new String(buffs, 0, rtnPos);

if (strBuff.toLowerCase().startsWith(

"content-disposition: form-data; ")) {

int nIndex = strBuff.toLowerCase().indexOf(

"name=\"");

int nLastIndex = strBuff.toLowerCase().indexOf(

"\"", nIndex + 6);

name = strBuff.substring(nIndex + 6, nLastIndex);

}

int fIndex = strBuff.toLowerCase().indexOf(

"filename=\"");

if (fIndex != -1) {

fileFlag = true;

int fLastIndex = strBuff.toLowerCase().indexOf(

"\"", fIndex + 10);

fName = strBuff.substring(fIndex + 10, fLastIndex);

fName = getFileName(fName);

if (fName == null || fName.trim().length() == 0) {

fileFlag = false;

sis.readLine(buffs, 0, buffs.length);

sis.readLine(buffs, 0, buffs.length);

sis.readLine(buffs, 0, buffs.length);

continue;

}else{

fName = getFileNameByTime(fName);

sis.readLine(buffs, 0, buffs.length);

sis.readLine(buffs, 0, buffs.length);

}

}

}

} else if (strBuff.startsWith(endBoundary)) {

if (name != null && name.trim().length() > 0) {

if (fileFlag) {

bos.flush();

baos.close();

bos.close();

baos = null;

bos = null;

updFileArr.add(fName);

} else {

Object obj = paramHt.get(name);

ArrayList al = new ArrayList();

if (obj != null) {

al = (ArrayList) obj;

}

al.add(value);

paramHt.put(name, al);

}

}

} else {

if (fileFlag) {

if (baos == null && bos == null) {

tmpFile = new File(uploadPath + fName);

baos = new FileOutputStream(tmpFile);

bos = new BufferedOutputStream(baos);

}

bos.write(buffs, 0, rtnPos);

baos.flush();

} else {

System.out.println("test :" + value + "--" + strBuff);

value = value + strBuff;

}

}

}

} catch (IOException e) {

status = 4;

}

return status;

}

private int preCheck() {

int errCode = 0;

if ( request == null )

return 1;

if ( uploadPath == null || uploadPath.trim().length() == 0 )

return 2;

else{

File tmpF = new File(uploadPath);

if (!tmpF.exists())

return 2;

}

String contentType = request.getContentType();

if ( contentType.indexOf("multipart/form-data") == -1 )

return 3;

return errCode;

}

public String getParameter(String name){

String value = "";

if ( name == null || name.trim().length() == 0 )

return value;

value = (paramHt.get(name) == null)?"":(String)((ArrayList)paramHt.get(name)).get(0);

return value;

}

public String[] getParameters(String name){

if ( name == null || name.trim().length() == 0 )

return null;

if ( paramHt.get(name) == null )

return null;

ArrayList al = (ArrayList)paramHt.get(name);

String[] strArr = new String[al.size()];

for ( int i=0;i<al.size();i++ )

strArr[i] = (String)al.get(i);

return strArr;

}

public int getUpdFileSize(){

return updFileArr.size();

}

public String[] getUpdFileNames(){

String[] strArr = new String[updFileArr.size()];

for ( int i=0;i<updFileArr.size();i++ )

strArr[i] = (String)updFileArr.get(i);

return strArr;

}

private String getFileName(String input){

int fIndex = input.lastIndexOf("\\");

if (fIndex == -1) {

fIndex = input.lastIndexOf("/");

if (fIndex == -1) {

return input;

}

}

input = input.substring(fIndex + 1);

return input;

}

private String getFileNameByTime(String input){

int index = input.indexOf(".");

Date dt = new Date();

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");

return input.substring(0,index) + sdf.format(dt) + input.substring(index);

}

}

2.在Jsp页面中进行引用该Java类:

<%@page import="com.vogoal.util.JspFileUpload"%>

<%

//初始化

JspFileUpload jfu = new JspFileUpload();

//设定request对象

jfu.setRequest(request);

//设定上传的文件路径

jfu.setUploadPath("C:\\");

//上传处理

int rtn = jfu.process();

//取得form中其他input控件参数的值

String username = jfu.getParameter("username");

//如果对应同一个参数有多个input控件,返回数组

String[] usernameArr = jfu.getParameters("username");

//取得上传的文件的名字

String[] fileArr = jfu.getUpdFileNames();

//取得上传文件的个数,这个方法有点鸡肋

int fileNumber = jfu.getUpdFileSize();

//下面的是测试输出的代码。

//       out.println("parameter:" + username);

//       out.println("parameter size:" + usernameArr.length);

//       out.println("fileArr size:" + fileArr.length);

//       if (fileArr.length > 0)

//              out.println("fileArr 0:" + fileArr[0]);

%>

第三点:struts2实现文件的上传和下载

第一步:在WEB-INF/lib下加入commons-fileupload-1.2.1.jar、commons-io-1.3.2.jar。这两个文件可以从http://commons.apache.org/下载。

第二步:把form表的enctype设置为:“multipart/form-data“,如下:

Java代码

public class UploadAction{

private File uploadImage; //文件

private String uploadImageContentType;//文件的类型

private String uploadImageFileName;//文件的名称

private String bookname;//书名

private String author;//作者

private String savePath;//文件的保存位置

//属性的getter/setter方法

public String upload() throws Exception{

//实现上传代码,I/O操作完成

return "uploadSuccess";

}

}

注:一个表单里的文件域对应Action中三个属性,分别是文件,文件名,文件类型,命名是固定的,文件名必须表单中的文件域名称相同(uploadImage),文件名为:文件+FileName,文件类型:文件+ContentType。

第四步:将我们的上传Action配置到struts.xml中。

<action name="upload" class="com.gqy.UploadAction">

<param name="savePath">/uploadFile</param>

<result>/success.jsp</result>  </action>

注:指定上传文件的在服务器上的保存目录,需要在UploadAction中为定义savePath变量并为其添加相应的setter和getter方法,便于Struts2将/uploadFile值赋给savePath属性,即要想在UploadAction中使用savePath变量必须在UploadAction定义。

配置文件过滤类型:

<param name="allowTypes">       image/bmp,image/png,image/gif,image/jpeg   </param>

手动配置文件大小限制

<param name="maximumSize" >1048576</param>

使用Struts2的文件上传拦截器实现文件过滤

Struts2提供了一个文件上传的拦截器—fileUpload,通过配置该拦截器可以方便实现上传文件的过滤。

配置fileUpload拦截器时,可以为其指定两个参数:

§ allowedTypes:指定允许上传的文件类型,多个文件类型之间以英文逗号(,)隔开。

§ maximumSize:指定允许上传的文件大小,单位是字节。

提示:通过配置fileUpload拦截器,可以轻松的实现文过滤,当文件过滤失败后,系统自动转入input逻辑视图,因此必须为该Action配置名为input的逻辑视图,除此之外,还必须显示地为该Action配置defaultStack的拦截器引用。

使用Struts2的拦截器实现文件过滤配置如下:

<action name="uploadFileAction" class="com.actions.UploadFileAction">

<interceptor-ref name="defaultStack">

<!-- 配置允许上传的文件类型,多个用","分隔 -->

<param name="fileUpload.allowedTypes">

image/bmp,image/png,image/gif,image/jpeg,image/jpg

,image/x-png, image/pjpeg

</param>

<!-- 配置允许上传的文件大小,单位字节,本例为:1MB -->

<param name="fileUpload.maximumSize">1048576</param>

</interceptor-ref>

<result name="input">/jsp/oneFileFileupload.jsp</result>

<result name="success">/jsp/result.jsp</result>

</action>

当用户上传失败后,需要有一定的提示信息。在Struts2中,使用<s:fielderror/>标签即可将错误提示信息输出到页面中。

注:要想使用Struts2错误提示信息,则上传文件的Action类,必须继承ActionSupport,否则Struts2不会提供输出错误提示信息功能。

我们可以配置资源文件(.properties)来保存输出给用户的信息。

struts.messages.eror.file.too.large:当上传文件大小超过设定的值时,Struts2将输出该key对应的提示信息。

struts.messages.error.content.type.not.allowed:当上传文件类型不符合设定的值时,Struts2将输出该key对应的提示信息。

struts.messages.error.uploading:当上传文件时出现未知错误时,Struts2将输出该key对应的提示信息。

我们还要将资源文件配置到struts.xml文件中,接下来看看我们的资源文件,已经包含中文了,得把它进行一下转换再配置到工程中。

在struts.xml中设定资源文件:

<constant name="struts.custom.i18n.resources" value="messages"/>或

<constant name="struts.custom.i18n.resources" value="messages_zh_CN"/>

用命令native2ascii  d:\messages.properties d:\messages_zh_CN.properties将原有的资源文件转换成支持中的。

注:保持国际化,资源文件的名称后缀为: *_zh_CN+文件扩展名的形式。

对于多个文件上传的原理同上,但是需要注意的是,多个文件域的name属性名必须相同,而且在Action中应该使用File [] 或者List<File>来接收。

个人觉得用这样的方式进行多个文件上传不是很好。

Struts2进行文件下载:

Struts2提供了stream结果类型,该结果类型专门用于支持文件下载的功能。当指定stream结果类型时,需要配置一个inputName参数,该参数指定了一个输入流,这个输入流是被下载文件的入口(即通过该入口才能实现文件以流的方式实现下载)。

实现文件下载的Action

public class FileDownloadAction implements Action{

//该属性值在配置文件中指定,Struts2会自动进行注入(即赋值),需要为该属性提供setter和 getter方法

private String inputPath;//指定要下载的文件的完整路径(路径名+文件名)

/*

* 实现下载的Action类应该提供一个返回InputStream实例的方法,该方法对应在

<result.../>里的inputName属性值为targetFile

*/

public InputStream getTargetFile() throws Exception{

return  ServletActionContext.getServletContext().getResourceAsStream(inputPath);

}

//处理用户请求的execute方法,该方法返回success字符串

public String execute() throws Exception{

return "success";

}

@Override

public void doIt(FSM arg0, Input arg1) {

// TODO Auto-generated method stub

}

}

对应Action在struts.xml文件中的配置

<action name="download" class="com.FileDownloadAction">

<!--指定被下载资源的位置-->

<param name="inputPath">/uploadFile/demo.txt</param>

<!--配置结果类型为stream的结果-->

<result name="success" type="stream">

<!--指定下载文件的文件类型-->

<param name="contentType"></param>

<!--指定下载文件的文件位置-->

<param name="inputName">targetFile</param>

<!--指定下载文件的下载方式及下载时的保存文件名,filename保存时的文件名必须有扩展名,扩展名指示了下载类型的图标-->

<param name="contentDisposition">

attachment;filename=Struts2.txt

</param>

<!--指定下载文件的缓冲区大小-->

<param name="bufferSize">4096</param>

</result>

</action>

后端代码逻辑大部分是相同的,目前能够支持MySQL,Oracle,SQL。在使用前需要配置一下数据库,可以参考我写的这篇文章:http://blog.ncmem.com/wordpress/2019/08/12/java-http%E5%A4%A7%E6%96%87%E4%BB%B6%E6%96%AD%E7%82%B9%E7%BB%AD%E4%BC%A0%E4%B8%8A%E4%BC%A0/

java解决大文件断点续传的更多相关文章

  1. Java解决大文件读取的内存问题以及文件流的比较

    Java解决大文件读取的内存问题以及文件流的比较 传统方式 读取文件的方式一般是是从内存中读取,官方提供了几种方式,如BufferedReader, 以及InputStream 系列的,也有封装好的如 ...

  2. js解决大文件断点续传

    最近遇见一个需要上传百兆大文件的需求,调研了七牛和腾讯云的切片分段上传功能,因此在此整理前端大文件上传相关功能的实现. 在某些业务中,大文件上传是一个比较重要的交互场景,如上传入库比较大的Excel表 ...

  3. php解决大文件断点续传

    核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开 ...

  4. jsp解决大文件断点续传

    我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用. 这次项目的需求: 支持大文件的上传和续传,要求续传支持所有浏览器,包括ie6,ie7,i ...

  5. java+下载+大文件断点续传

    java两台服务器之间,大文件上传(续传),采用了Socket通信机制以及JavaIO流两个技术点,具体思路如下: 实现思路:1.服:利用ServerSocket搭建服务器,开启相应端口,进行长连接操 ...

  6. .net解决大文件断点续传

    以ASP.NET Core WebAPI 作后端 API ,用 Vue 构建前端页面,用 Axios 从前端访问后端 API ,包括文件的上传和下载. 准备文件上传的API #region 文件上传  ...

  7. asp.net解决大文件断点续传

    以ASP.NET Core WebAPI 作后端 API ,用 Vue 构建前端页面,用 Axios 从前端访问后端 API ,包括文件的上传和下载. 准备文件上传的API #region 文件上传  ...

  8. java之大文件断点续传

    针对某些场景下,面对服务文件大,或者服务端服务器不稳定时使用该模块.功能代码如下: import java.io.File; import java.io.FileOutputStream; impo ...

  9. vue解决大文件断点续传

    一.概述 所谓断点续传,其实只是指下载,也就是要从文件已经下载的地方开始继续下载.在以前版本的HTTP协议是不支持断点的,HTTP/1.1开始就支持了.一般断点下载时才用到Range和Content- ...

随机推荐

  1. golang 网络编程之如何正确关闭tcp连接以及管理它的生命周期

    欢迎访问我的个人网站获取更佳阅读排版 golang 网络编程之如何正确关闭tcp连接以及管理它的生命周期 | yoko blog (https://pengrl.com/p/47401/) 本篇文章部 ...

  2. Bitnami配置域名访问

    安装完成Bitnami后,需要执行以下命令将默认目录改为/wordpress: E:\Bitnami\wordpress-5.2.2-0\apps\wordpress\bnconfig.exe --a ...

  3. APIO2019题解

    T1.桥梁(bridges/restriction) Subtask1:暴力,$O(n^2)$. #include<cstdio> #include<algorithm> #d ...

  4. 勒索病毒,华为/H3C三层交换机/路由器用ACL访问控制实现端口禁用

    前不久勒索病毒横行,很多人都纷纷中招,从公司到个人,损失相当惨重.有些公司在互联网入口上做了控制,但是这样并非完全,万一有人把中了毒的U盘插入网内设备上呢?那我们的内网中很有可能集体中招(打过相关补丁 ...

  5. provide inject应用及和props对比

    之前本人写过几篇element ui源码解析,其中提到provide/inject,当时只是匆匆带过,没有做深入研究,直到后来一次开发,需要实现孙组件更改父组件的值才想起来,原来这一对属性有如此大的用 ...

  6. 《区块链DAPP开发入门、代码实现、场景应用》笔记4——Ethereum Wallet中部署合约

    账号创建完成之后,账号余额是0,但是部署合约是需要消耗GAS的,因此需要获取一定的以太币才能够继续本次实现.在测试网中获取以太币可以通过挖矿的方式,在开发菜单中可以选择打开挖矿模式,但是这需要将Syn ...

  7. 英语foteball足球历史

    foteball n.足球 现代足球 参见:现代足球 现代足球起源地是在英格兰.传说在11世纪,英格兰与丹麦之间有过一场战争,战争结束后,英格兰人在清理战争废墟时发现一个丹麦入侵者的头骨,出于愤恨,他 ...

  8. DataPipeline CTO 陈肃:我们花了3年时间,重新定义数据集成

    目前,中国企业在大数据流通.交换.利用等方面仍处于起步阶段,但是企业应用数据集成市场却是庞大的.根据 Forrester 数据看来,2017 年全球数据应用集成市场纯软件规模是 320 亿美元,如果包 ...

  9. SQL常见的一些面试题(太有用啦)

    SQL常见面试题 1.用一条SQL 语句 查询出每门课都大于80 分的学生姓名 name   kecheng   fenshu张三    语文       81张三     数学       75李四 ...

  10. Android 为TV端助力之解决ViewPager嵌套RecyclerView水平滑动问题

    public class MyViewPager extends ViewPager { private RecyclerView recyclerView; public MyViewPager(@ ...