本文主要介绍如何通过http请求springmvc接口,来实现上传文件到服务器,或者读取文件里的内容,实现一些业务需求。
我们知道,上传文件到服务器,可以通过jsp表单提交到接口。这里介绍的是通过http请求实现上传,不通过前台页面jsp表单。具体用apache.commons包下的httpclient来实现。代码如下:
/**
* 将文件作为参数上传到接口中
* @param url
* @param filepath
* @return
*/
private static String uploadFile(String url, String filepath) {
String result = "";
PostMethod postMethod = new PostMethod(url);
try {
File file = new File(filepath);
// SubFilePart filePart = new SubFilePart("file", file);
FilePart filePart = new FilePart("file", file);
filePart.setCharSet("utf-8");
StringPart stringPart = new StringPart("fileSuffix", ".xlsx");
Part[] parts = {filePart, stringPart};
MultipartRequestEntity requestEntity = new MultipartRequestEntity(parts, postMethod.getParams());
postMethod.setRequestEntity(requestEntity);
HttpClient httpClient = new HttpClient();
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(50000);
int status = httpClient.executeMethod(postMethod);
if(status == HttpStatus.SC_OK) {
InputStream in = postMethod.getResponseBodyAsStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
StringBuffer sb = new StringBuffer();
String str = null;
while((str = br.readLine()) != null) {
sb.append(str);
}
br.close();
return sb.toString();
} else {
result = "request fail";
}
} catch (Exception e) {
e.printStackTrace();
result = "requst exception";
} finally {
postMethod.releaseConnection();
}
return result;
}
文件作为参数去请求接口,主要用到MultipartRequestEntity这种类型的请求实体。MultipartRequestEntity里面的参数parts包含FilePart,也可以包含StringPart,其中StringPart的参数可以直接在接口里用request.getParameter()来获取。
还有一个请求实体StringRequestEntity,这个一般用来传递字符参数,就是传一串字符到接口,而没有对应的参数名,字符将以流的形式传递到接口中,在接口里要获取,就必须用流的形式,request.getInputStream()是获取请求中流形式存在的参数,再把流里的字符内容读取出来即可。
上面是请求接口的代码,下面写接口。
/**
* 上传文件,通过接口读取上传过来的文件
* @param request
* @param response
*/
@RequestMapping(value = "uploadFile")
public void uploadFile(HttpServletRequest request, MultipartFile file, HttpServletResponse response) {
String fileSuffix = request.getParameter("fileSuffix");
logger.info("fileSuffix = " + fileSuffix);
String filename = file.getOriginalFilename();
logger.info("filename = " + filename);
FileOutputStream fos = null;
InputStream in = null;
try {
in = file.getInputStream();
File localFile = createLocalFile(filename);
fos = new FileOutputStream(localFile);
byte b[] = new byte[1024];
int len = -1;
while((len = in.read(b)) != -1) {
fos.write(b, 0, len);
}
fos.flush();
response.getWriter().write("读取文件并写入服务器成功^_^");
} catch (IOException e) {
logger.error("uploadFile", e);
} finally {
try {
if(fos != null) {
fos.close();
}
if(in != null) {
in.close();
}
} catch (IOException e) {
logger.error("outstream close error : ", e);
}
}
}
其中参数里的MultipartFile file 就是接收请求接口里的FilePart filePart = new FilePart("file", file);这个FilePart的文件,参数名必须一致(file和"file")。
String fileSuffix = request.getParameter("fileSuffix");是直接读取请求里的StringPart的参数。
取得文件后,后续就是一些简单的读写文件操作了。
private File createLocalFile(String filename) {
String timeStr = DateUtils.format(new Date(), "yyMMddHHmmss");
String filenamePrefix = filename.substring(0, filename.lastIndexOf("."));
String filenameSuffix = filename.substring(filename.lastIndexOf("."));
String filepath = "D:\\file\\excel\\" + filenamePrefix + "_" + timeStr + filenameSuffix;
logger.info("createLocalFile filepath = " + filepath);
File file = new File(filepath);
return file;
}
这里需要注意的是如果上传的文件名是中文的,那String filename = file.getOriginalFilename();这里获取的会是乱码。
看FilePart的源码,发现标题是通过ACSIC码编码的,所以才导致乱码,如下:
如果修改成通过utf-8的编码方式,则不会有乱码,需要重写FilePart的sendDispositionHeader()方法。所以写一个类继承FilePart,再重写sendDispositionHeader()方法,将文件名的编码形式改成EncodingUtil.getBytes(filename, getCharSet())即可,getCharSet()是指FilePart的编码方式。如下所示:
如果修改成通过utf-8的编码方式,则不会有乱码,需要重写FilePart的sendDispositionHeader()方法。所以写一个类继承FilePart,再重写sendDispositionHeader()方法,将文件名的编码形式改成EncodingUtil.getBytes(filename, getCharSet())即可,getCharSet()是指FilePart的编码方式。如下所示:
public class SubFilePart extends FilePart {
private static Logger logger = LoggerFactory.getLogger(SubFilePart.class);
public SubFilePart(String name, File file) throws FileNotFoundException {
super(name, file);
}
@Override
protected void sendDispositionHeader(OutputStream out) throws IOException {
logger.info("sendDispositionHeader SubFilePart 设置文件名重写...");
out.write(CONTENT_DISPOSITION_BYTES);
out.write(QUOTE_BYTES);
out.write(EncodingUtil.getAsciiBytes(getName()));
out.write(QUOTE_BYTES);
String filename = this.getSource().getFileName();
logger.info("sendDispositionHeader filename = " + filename);
if (filename != null) {
out.write(EncodingUtil.getAsciiBytes(FILE_NAME));
out.write(QUOTE_BYTES);
out.write(EncodingUtil.getBytes(filename, getCharSet()));
out.write(QUOTE_BYTES);
}
}
}
然后将之前请求接口的代码FilePart filePart = new FilePart("file", file);改成SubFilePart filePart = new SubFilePart("file", file);即可。
当然有些需求是这样的,上传的文件并不是一定要保存到服务器,有些可能只是需要读取文件里的内容做一些其他的需求。其实没什么改变,只是将保存文件到服务器的部分改成读取文件内容即可。
/**
* 上传文件,通过接口读取上传文件里的内容并存到数据库表中
* @param request
* @param response
*/
@RequestMapping(value = "readFile")
public void readFileAndSave(HttpServletRequest request, MultipartFile file, HttpServletResponse response) {
InputStream in = null;
BufferedReader br = null;
List<TMobile> tMobiles = new ArrayList<>();
int num = 0;
try {
in = file.getInputStream();
br = new BufferedReader(new InputStreamReader(in));
String line = null;
while((line = br.readLine()) != null) {
tMobiles.add(createTMobile(line));
num ++;
if(num == 1000) {
addBatch(tMobiles);
num = 0;
tMobiles = new ArrayList<>();
}
}
if(tMobiles.size() > 0) {
addBatch(tMobiles);
}
response.getWriter().write("读取文件并保存成功^_^");
} catch (IOException e) {
logger.error("uploadFile", e);
} finally {
try {
if(br != null) {
br.close();
}
if(in != null) {
in.close();
}
} catch (IOException e) {
logger.error("uploadFile close stream error : ", e);
}
}
}
private TMobile createTMobile(String mobile) {
TMobile tMobile = new TMobile();
tMobile.setMobile(mobile);
return tMobile;
}
private void addBatch(List<TMobile> tMobiles) {
try {
Integer addBack = tMobileService.addBatch(tMobiles);
logger.info("addBatch 批量插入 " + tMobiles.size() + " 条记录,成功插入 " + addBack + " 条");
if(addBack <= 0) {
add(tMobiles);
}
} catch (Exception e) {
logger.error("addBatch error : ", e);
add(tMobiles);
}
}
private void add(List<TMobile> tMobiles) {
int failNum = 0;
for(TMobile tMobile : tMobiles) {
try {
tMobileService.add(tMobile);
} catch (Exception e) {
failNum ++;
logger.error("add error : ", e);
}
}
logger.info("add 单次插入成功 " + (tMobiles.size() - failNum) + " 条记录");
}
核心的代码都是一样的。
相关推荐
这个接口封装了上传文件的基本信息,如文件名、大小、内容等。在控制器方法中,我们可以声明一个`MultipartFile`参数来接收上传的文件。 3. **配置SpringMVC以支持文件上传**: 在SpringMVC的配置文件中,我们需要...
- **MultipartFile接口**:`SpringMVC`提供了一个名为`MultipartFile`的接口,用于处理上传的文件。通过这个接口,我们可以获取文件名、文件大小、内容类型等信息,并将其保存到服务器。 - **Controller配置**:在...
multipart请求是HTTP协议中用于上传文件的一种特殊类型,它可以包含多个部分,每个部分可以是一个表单字段或者一个文件。 **单文件上传** 对于单文件上传,我们需要在表单中添加`<input type="file">`元素,然后在...
同时,确保前端和后端的安全性,比如使用CSRF令牌防止跨站请求伪造,以及对上传文件进行适当的权限控制。 最后,项目中的"新建文件夹"可能表示在服务器端需要创建一个目录来存储上传的文件。你可以使用Java的`java....
这通常在`WebMvcConfigurerAdapter`的`configureMultipartSettings`方法中完成,设置最大上传文件大小等相关参数。 5. **控制器方法** 控制器中需要定义一个接收`MultipartFile[]`类型的参数的方法,用于接收上传...
上传文件时要考虑安全性,包括防止文件覆盖、恶意文件上传(如脚本注入)、文件权限设置等。应验证文件类型、大小,并对文件名进行清理,避免特殊字符和路径遍历攻击。 9. **最佳实践** 使用流式处理文件,减少...
每个`CommonsMultipartFile`对象代表一个单独的上传文件,可以获取文件名、大小、类型等信息,并支持文件内容的读取和保存。 3. **配置MultipartResolver**: 在Spring MVC配置中,我们需要添加一个`Multipart...
-- 设置最大上传文件大小 --> ``` 在Controller中,同样可以使用`@RequestParam`接收文件: ```java @PostMapping("/upload") public String handleFileUpload(@RequestParam("file") MultipartFile file...
在SpringMVC中,文件上传主要通过`CommonsMultipartResolver`解析器实现,它利用了`FileUpload`接口和`FileItem`接口来处理上传的文件。`FileUpload`负责将HTTP请求的多部分数据分割为单独的`FileItem`对象,而`...
其中,`maxUploadSize`属性用来限制上传文件的大小,防止过大文件导致服务器资源耗尽。 3. **前端表单** 在HTML页面中,创建一个`<form>`元素,并设置`enctype="multipart/form-data"`,表示这是一个支持文件上传...
在IT行业中,文件上传是常见的功能之一,尤其是在Web应用...总的来说,SpringMVC实现跨服务器文件上传涉及文件上传处理、网络通信以及文件服务器接口的调用。了解并掌握这些知识,有助于开发高效、安全的文件管理系统。
Apache Commons FileUpload库提供了`MultipartFile`接口,它是Spring MVC中处理上传文件的核心类。`MultipartFile`封装了文件的名称、内容、大小等信息,并提供了读取文件内容的方法。通过这个接口,开发者可以在...
在本文中,我们将深入探讨如何在Spring MVC框架中实现AJAX文件上传,以及通过表单提交方式上传文件。这两种方法都是在Web应用中处理用户上传文件的常见方式,特别是当需要在后台处理文件且不刷新整个页面时,AJAX...
`MultipartFile`是Spring提供的接口,用于处理单个或多个文件上传。 - 为了处理多文件上传,需要将`<input type="file">`改为`<input type="file" multiple>`,允许用户选择多个文件。 - 配置Spring MVC的`...
在Spring MVC框架中,文件上传是一项常见的功能,用于允许用户通过Web应用程序上传文件。要实现这一功能,我们需要依赖一些特定的库和配置。本篇文章将详细介绍如何在Spring MVC中实现文件上传,并涉及到所需的jar包...
在这个项目中,SpringMVC作为后端控制器,处理WebUploader上传的文件请求,进行文件存储和状态管理。 4. **SSM框架**: SSM是Spring、SpringMVC和MyBatis的组合,是Java开发中常用的Web开发框架。Spring负责依赖...
此外,为了提供文件列表功能(`/upload/list`),我们需要额外创建一个方法,返回服务器上已上传文件的信息。这个信息通常包括文件名、URL和缩略图等,以便KindEditor展示在文件管理器中。 总的来说,整合Spring ...
"SpringMVC_RequestPart_文件上传_example.rar"这个压缩包文件很可能是包含一个示例项目,演示了如何在Spring MVC中实现文件上传功能。我们将深入探讨Spring MVC中的文件上传,以及与之相关的知识点。 首先,Spring...
同时,我们还需要在HTML页面上使用`<form>`元素配合`enctype="multipart/form-data"`属性来上传文件。文件会被临时存储在服务器的一个目录下,然后通过MyBatis的Mapper接口将其保存到数据库。 对于多文件上传,我们...