一、文件上傳:文件上傳是項目開發中最常用的功能。為了能上傳文件,必須將表單的method設置為post,將enctype設置為multipart/form-data。只有在這種情況下,瀏覽器才會把用戶選擇的文件二進制數據發送給服務器
1、導入相應的jar包(上傳組件):
commons-fileupload.jar
common-io.jar
2、上傳的頁面文件:
<form action="upload" enctype="multipart/form-data" method="post">
<label>請選擇文件:</label>
<input type="file" name="file">
<br><br>
<input type="submit" value="上傳">
</form>
3、上傳控制器:
@Controller
public class FileUploadController {
@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) throws Exception{
//如果文件不為空
if(!file.isEmpty()) {
String path = "E:\\upload";//上傳路徑
String filename = file.getOriginalFilename();//獲取上傳文件的原名
File filepath = new File(path,filename);
//判斷路徑是否存在,如果不存在就創建一個
if(!filepath.getParentFile().exists()) {
filepath.getParentFile().mkdirs();
}
//將上傳文件保存到一個目標文件中
file.transferTo(new File(path+File.separator+filename));
System.out.println("上傳路徑為:"+(path+File.separator+filename));
return "success";
}else {
return "error";
}
}
}
4、配置SpringMVC
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize">
<value>10345789</value>
</property>
<property name="defaultEncoding">
<value>utf-8</value>
</property>
</bean>
5、MultipartFile對象:SpringMVC回將上傳文件綁定到
MultipartFile對象。MultipartFile對象提供了獲取上傳文件內容、文件名等方法。通過transferTo()方法可以將文件上傳。MultipartFile對象中的常用方法如下:
(1)byte[] getBytes():獲取文件數據
(2)String getContentType():獲取文件MIME類型,如image/jpeg等
(3)InputStream getInputStream():獲取文件流
(4)String getName():獲取表單中文件組件的名稱
(5)String getOriginalFilename():獲取上傳文件的原名
(6)long getSize():獲取文件的字節大小,單位為byte
(7)boolean isEmpty():是否有上傳文件
(8)void transferTo(File dest):將上傳文件保存到一個目標文件中
6、實例:使用對象接收上傳文件
(1)上傳頁面:
<form action="objectUploade" enctype="multipart/form-data" method="post"
<label>用戶名:</label>
<input type="text" name="username">
<br><br>
<label>請選擇頭像:</label>
<input type="file" name="image">
<br><br>
<input type="submit" value="上傳">
</form>
(2)接收上傳文件的類:
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String username;
private MultipartFile image;
}
(3)上傳控制器:
@PostMapping("/objectUploade")
public String register(HttpServletRequest request,
@ModelAttribute User user,
Model model) throws Exception {
System.out.println(user.getUsername());
if(!user.getImage().isEmpty()) {
String path = request.getServletContext().getRealPath("/images");
String filename = user.getImage().getOriginalFilename();
File filepath = new File(path,filename);
if(!filepath.getParentFile().exists()) {
filepath.getParentFile().mkdirs();
}
user.getImage().transferTo(new File(path+File.separator+filename));
model.addAttribute("filename",user.getImage().getOriginalFilename());
System.out.println("上傳文件路徑:"+(path+File.separator+filename));
return "userInfo";
}else {
return "error";
}
}
(4)下載頁面(userInfo.jsp)
<a href="javascript:window.location.href='download?filename='+encodeURIComponent('${requestScope.filename }')">
${requestScope.filename }
</a>
注:因為傳遞的文件名有可能是中文字符,所以超鏈接中使用了encodeURIComponent函數進行編碼
二、文件下載:SpringMVC提供了ResponseEntity類型,使用它可以很方便的定義返回的BodyBuilder、HttpHeaders和HttpStatus
BodyBuilder對象用來構建返回的Body;
HttpHeaders代碼Http協議中的頭信息
HttpStatus代表Http協議中的狀態
接上例,定義下載的控制器:
@GetMapping("/download")
public ResponseEntity<byte[]> download(HttpServletRequest request,
@RequestParam("filename") String filename,
@RequestHeader("User-Agent") String userAgent) throws Exception{
String path =request.getServletContext().getRealPath("/images");
File file = new File(path+File.separator+filename);
BodyBuilder builder = ResponseEntity.ok();//ok表示http協議中的狀態200
builder.contentLength(file.length());//內容長度
//application_octet_stream二進制流數據(最常見的文件下載),MediaType表示互聯網媒體類型,即MIME類型
builder.contentType(MediaType.APPLICATION_OCTET_STREAM);
//使用URLEncoder.encode對文件名進行解碼
filename = URLEncoder.encode(filename,"utf-8");
//設置實際的響應文件名,告訴瀏覽器文件要以附件的形式打開
//不同的瀏覽器,處理方式不同,要根據瀏覽器版本進行區別判斷
if(userAgent.indexOf("MSIE")>0) {
//如果是IE,只需要用utf-8字符集進行URL編碼即可
builder.header("Content-Disposition","attachment;filename="+filename);
}else {
//如果是fireFox、Chrome等瀏覽器,則需要說明編碼的字符集
//注意在filename后面有個*號,在utf-8后面有兩個單引號
builder.header("Content-Disposition", "attachment;filename*=utf-8''"+filename);
}
return builder.body(FileUtils.readFileToByteArray(file));
}
三、攔截器:Inteceptor攔截器是SpringMVC中非常重要的功能,它的主要作用是攔截用戶的請求並進行相應的處理。比如通過攔截器來進行用戶權限驗證、或判斷用戶是否已經登錄等。
1、SpringMVC攔截器是可插拔的。如果需要只需在配置文件中配置即可,如果不需要在配置文件取消配置即可
2、SpringMVC攔截器攔截請求是通過實現HandlerInterceptor接口來完成的,在該接口中定義了三個方法來對用戶的請求進行攔截
(1)boolean preHandle(request,response,object):該方法在請求處理之前進行調用
(2)void postHandle(request,response,handler,modelAndView)在Controller方法調用之后執行
(3)
void afterHandle(request,response,handler,modelAndView):進行資源清理
3、示例:實現登錄驗證
(1)請求控制器:模擬在數據庫中查找用戶,判斷用戶登錄
@PostMapping(value="/login")
public ModelAndView login(String loginname,String password,
ModelAndView mv,HttpSession session) {
if(loginname!=null&&loginname.equals("jaskon")&&password!=null&&password.equals("12345")) {
User user = new User();
user.setLoginname(loginname);
user.setPassword(password);
user.setUsername("管理員");
session.setAttribute("user",user);
mv.setViewName("redirect:main");
}else {
mv.addObject("message","登錄名或密碼錯誤,請重新輸入!");
mv.setViewName("loginForm");
}
return mv;
}
(2)主頁面控制器(main)
@Controller
public class BookController {
@RequestMapping(value="/main")
public String Main(Model model) {
model.addAttribute("Info","歡迎管理員");
return "main";
}
}
(3)自定義攔截器:MyInterceptor
public class MyInterceptor implements HandlerInterceptor {
private static final String[] IGNORE_URI = {"/loginForm","/login"};
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("MyInterceptor preHandle...");
boolean flag = false;
String servletPath = request.getServletPath();
for(String s : IGNORE_URI) {
if(servletPath.contains(s)) {
flag = true;
break;
}
}
if(!flag) {
User user= (User)request.getSession().getAttribute("user");
if(user == null) {
System.out.println("MyInterceptor攔截請求");
request.setAttribute("message","請先登錄");
request.getRequestDispatcher("/WEB-INF/views/loginForm.jsp").forward(request, response);
}else {
System.out.println("MyInterceptor放行請求");
flag = true;
}
}
return flag;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor postHandle...");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("MyInterceptor afterCompletion...");
}
}
(4)配置攔截器:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/*"/>
<bean class="com.cn.filter.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
(5)頁面(main.jsp)
<h2>${sessionScope.user.username }</h2>
<h2>${Info }</h2>