文章主要完成簡單java web涉及的文件上傳和下載功能。
正文
1. java原生servlet實現:
pom.xml配置:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.</version>
<scope>runtime</scope>
</dependency>
web.xml配置:
<welcome-file-list>
<welcome-file>/WEB-INF/view/jsp/upload/upload.jsp</welcome-file>
</welcome-file-list>
<!-- 聲明Servlet對象 -->
<servlet>
<!-- 指定Servlet對象的名稱 -->
<servlet-name>UploadServlet</servlet-name>
<!-- 指定Servlet對象的完整位置,包含包名和類名 -->
<servlet-class>pers.chaffee.servlet.UploadServlet</servlet-class>
</servlet>
<!-- 映射Servlet -->
<servlet-mapping>
<!--<servlet-name>與上面<Servlet>標簽的<servlet-name>元素相對應,不可以隨便起名 -->
<servlet-name>UploadServlet</servlet-name>
<!-- 用於映射訪問URL -->
<url-pattern>/UploadFileServlet</url-pattern>
</servlet-mapping>
servlet實現:
@WebServlet("/UploadServlet")
public class UploadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
//根據文件擴展名設置文件MIME類型
resp.setContentType(getServletContext().getMimeType("hello.txt"));
//設置下載消息響應,提示文件保存attachment
resp.setHeader("Content-Disposition", "attachment;filename=" + "hello");
/*
* 設置緩沖區
* is.read(b)當文件讀完時返回-1
*/
try {
//輸入流為項目文件,輸出流指向瀏覽器
InputStream is = new FileInputStream("E:\\hello.txt");
// 提供了將二進制數據寫入響應的流
ServletOutputStream os = resp.getOutputStream();
int len = -1;
byte[] b = new byte[1024];
while ((len = is.read(b)) != -1) {
os.write(b, 0, len);
}
//關閉流
is.close();
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
// 文件上傳到本地磁盤工廠類
DiskFileItemFactory factory = new DiskFileItemFactory();
//設置內存緩沖區的大小
factory.setSizeThreshold(20480);
//設置臨時文件目錄,供上傳文件過大時臨時存儲
factory.setRepository(new File("F:\\f"));
//文件上傳操作核心類
ServletFileUpload upload = new ServletFileUpload(factory);
//設置限制單個上傳文件的大小
upload.setFileSizeMax(50480);
//設置限制總上傳文件大小
upload.setSizeMax(80480);
// 這個路徑相對當前應用的目錄
try {
List<FileItem> formItems = upload.parseRequest(req);
if (formItems != null && formItems.size() > 0) {
// 迭代表單數據
for (FileItem item : formItems) {
// 處理不在表單中的字段
if (!item.isFormField()) {
File storeFile = new File("F:\\fromweb_" + item.getName());
// 保存文件到硬盤
item.write(storeFile);
}
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
upload.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>文件上傳實例</h1>
<!--請求編碼類型必須為"multipart/form-data"-->
<form method="post" action="/UploadFileServlet" enctype="multipart/form-data">
選擇一個文件:
<input type="file" name="uploadFile"/>
<input type="file" name="uploadFile2"/>
<br/><br/>
<input type="submit" value="上傳"/>
</form>
<a href="/UploadFileServlet" rel="nofollow">下載</a>
</body>
</html>
2. java web主流框架【ssm】實現:
pom.xml配置
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
web.xml配置
<context-param>
<param-name>contextConfigLocation</param-name>
<!--<param-value>classpath*:applicationContext-*.xml</param-value>-->
<param-value>classpath*:*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
spring-mvc.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- 啟動SpringMVC的注解功能 -->
<mvc:annotation-driven/>
<!-- 掃描controller(controller層注入) -->
<context:component-scan base-package="pers.chaffee.controller"/>
<!-- 對模型視圖添加前后綴 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/view/jsp/" p:suffix=".jsp"/>
<!-- 靜態資源不走controller -->
<mvc:resources mapping="/resources/**" location="/resources/"/>
</beans>
servlet實現:
@RequestMapping(value = "/upload2", method = RequestMethod.POST, consumes = {"multipart/form-data"})
public ModelAndView postUpload(HttpServletRequest request, HttpServletResponse response) {
//文件上傳核心類
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
//判斷request是否有文件上傳
if (multipartResolver.isMultipart(request)) {
//通過MultipartHttpServletRequest解析上傳請求中的文件
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
//獲取上傳請求中的所有文件
Iterator<String> iter = multiRequest.getFileNames();
while (iter.hasNext()) {
//轉換成spring支持的文件類型MultipartFile
MultipartFile file = multiRequest.getFile(iter.next());
if (file != null) {
File localFile = new File("F:\\f\\" + file.getOriginalFilename());
try {
//將上傳文件寫到指定位置,此處是本地文件夾
file.transferTo(localFile);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("upload/upload2");
return modelAndView;
}
@RequestMapping(value = "/download", method = RequestMethod.GET)
public ResponseEntity<byte[]> downLoad() throws IOException {
byte[] responseBody;
//獲取文件
File file = new File("E:\\hello.txt");
InputStream is = new FileInputStream(file);
responseBody = new byte[is.available()];
is.read(responseBody);
HttpHeaders headers = new HttpHeaders();
//設置文件類型
headers.add("Content-Disposition", "attachment;filename=" + file.getName());
//設置Http狀態碼
HttpStatus stateCode = HttpStatus.OK;
//返回數據
ResponseEntity<byte[]> entity = new ResponseEntity<>(responseBody, headers, stateCode);
return entity;
}
小結
截至目前,只初步完成B/S方式的上傳和下載,且文件存儲方式僅限本地磁盤。而C/S方式的文件傳輸可以考慮thrift框架,thrift是一種跨平台跨語言的RPC框架,使用過程中發現在數據量不是很大的情況下thrift應用是一種比較合適的C/S解決方案;另外,文件存儲方式可以根據具體情況選用文件服務器、數據庫等。
詳細的配置信息可以參考這篇文章:
http://blog.ncmem.com/wordpress/2019/08/12/java%e5%ae%9e%e7%8e%b0%e5%a4%a7%e6%96%87%e4%bb%b6%e4%b8%8a%e4%bc%a0%e5%92%8c%e4%b8%8b%e8%bd%bd/