目录
一、文件上传
1.概述
-
SpringMVC会将上传文件绑定到MultipartFile对象中。MultipartFile提供了获取上传文件内容、方法名等方法。通过transferTo()方法还可以将文件存储到硬件中。
方法 | 描述 |
---|---|
byte[] getBytes() | 获取文件数据 |
String getContentType() | 获取文件MIME类型,如image/jpeg等 |
InputStream getInputStream() | 获取文件流 |
String getName() | 获取表单中文件组件的名字 |
String getOriginalFilename() | 获取上传文件的原名 |
long getSize() | 获取文件的字节大小 |
boolean isEmpty() | 是否有上传的文件 |
void transferTo(File dest) | 将上传文件保存到一个目标文件中 |
-
Spring MVC 上下文中默认没有装配 MultipartResovler,因此默认情况下不能处理文件的上传工作,如果想使用 Spring 的文件上传功能,需现在上下文中配置 MultipartResolver
2.案例
uploadForm.jsp
<form action="upload" enctype="multipart/form-data" method="post">
用户名:<input type="text" name="username"><br/>
请上传头像:<input type="file" name="image"><br/>
<input type="submit" value="提交">
</form>
FileUploadController.java
@RequestMapping("/upload")
public String upload(HttpServletRequest request,
@RequestParam("username") String username, @RequestParam("image") MultipartFile image, Model model) throws Exception {
System.out.println(username);
//如果文件不为空
if (!image.isEmpty()) {
//上传文件路径
String path = request.getServletContext().getRealPath("/images");
System.out.println("path:" + path);
//上传文件名
String filename = image.getOriginalFilename();
System.out.println("filename:" + filename);
File filepath = new File(path, filename);
//判断路径是否存在,如果不存在就创建一个
if (!filepath.getParentFile().exists()) {
filepath.getParentFile().mkdirs();
}
//将上传文件保存到一个目标文件中
image.transferTo(new File(path + File.separator + filename));
//跳转到下载页面
return "success";
} else {
return "error";
}
}
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 默认使用基于注释的适配器和映射器 -->
<mvc:annotation-driven/>
<!-- 只把动态信息当做controller处理,忽略静态信息 -->
<mvc:default-servlet-handler/>
<!--自动扫描包中的Controlller -->
<context:component-scan base-package="com.itheima.controller"/>
<!-- 配置视图解析器: 如何把 handler 方法返回值解析为实际的物理视图 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/><!-- 前缀 -->
<property name="suffix" value=".jsp"/><!-- 后缀,自动拼接 -->
</bean>
<!-- 配置 MultipartResolver -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上传文件大小上限 -->
<property name="defaultEncoding" value="UTF-8"></property>
<!-- 请求的编码格式,必须和jsp的pageEncoding属性一致 -->
<property name="maxUploadSize" value="1024000"></property>
</bean>
</beans>
二.拦截器
1.HandlerInterceptor接口
-
SpringMVC中的Interceptor拦截器拦截请求是通过实现HandlerInterceptor接口来完成的。若要自定义一个拦截器,只需要实现HandlerInterceptor接口或者继承抽象类HandlerInterceptorAdapter。
-
HandlerInterceptor接口中定义了三个方法
方法 | 描述 |
---|---|
preHandle(request,response) | 在请求处理之前被调用 |
postHandle(request,response) | 在Controller方法被调用之后,视图返回渲染之前被调用 |
afterCompletion(request,response) | 在视图返回渲染之前被调用,一般用来资源清理 |
2.案例:拦截器实现用户权限验证
-
用户必须登录之后才可以访问到网站首页,如果没有登录,则跳转到登陆页面,并提示错误消息
loginForm.jsp
<font color="red">${requestScope.message}</font><br/>
<form action="login" method="post">
登录名:<<input type="text" name="loginname" id="loginname"><br/>
密码:<<input type="text" name="password" id="password"><br/>
<input type="submit" value="登陆">
</form>
UserController.java
@RequestMapping("/{formName}")
public String loginForm(@PathVariable String formName, Model model) {
//model.addAttribute("user1",new User1());
//动态跳转页面
return formName;
}
@RequestMapping("/login")
public ModelAndView login(String loginname, String password, ModelAndView modelAndView, HttpSession session){
//模拟数据库查找判断是否有该用户名及密码
if(loginname!=null&&loginname.equals("admin")&&password!=null&&password.equals("123456")){
//模拟创建用户
Admin admin=new Admin(loginname,password);
//登陆成功,将admin对象设置到HttpSession域对象中
session.setAttribute("admin",admin);
//转发到main请求
modelAndView.setViewName("redirect:main");
}else{
//登录失败,设置失败信息,跳转到登陆页面
modelAndView.addObject("message","用户名或密码错误");
modelAndView.setViewName("loginForm");
}
return modelAndView;
}
@RequestMapping("/main")
public String main(Model model){
//模拟数据库获得所有图书
List<Book> book_list=new ArrayList<>();
book_list.add(new Book("Spring实战",58));
book_list.add(new Book("深入浅出MyBatis",69));
book_list.add(new Book("java并发编程实战",77));
model.addAttribute("book_list",book_list);
return "main";
}
main.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:forEach items="${requestScope.book_list}" var="book">
${book.name}<br/>
${book.price}<br/>
<hr/>
</c:forEach>
AuthorizationInterceptor.java
package com.itheima.interceptor;
import com.itheima.domain.Admin;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class AuthorizationInterceptor implements HandlerInterceptor {
//不拦截的请求
private static final String[] IGNORE_URI={"/loginForm","/login"};
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
boolean flag=false;
String servletPath= httpServletRequest.getServletPath();
//判断请求是否需要拦截
for (String s : IGNORE_URI) {
if(servletPath.contains(s)){
flag=true;
break;
}
}
if(!flag){
//1.获取session中的用户
Admin admin=(Admin)httpServletRequest.getSession().getAttribute("admin");
//2.判断用户是否登陆
if(admin==null){
httpServletRequest.setAttribute("message","请先登录");
httpServletRequest.getRequestDispatcher("loginForm").forward(httpServletRequest,httpServletResponse);
}else{
flag=true;
}
}
return flag;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("postHandler...");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("afterCompletion...");
}
}
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 默认使用基于注释的适配器和映射器 -->
<mvc:annotation-driven/>
<!-- 只把动态信息当做controller处理,忽略静态信息 -->
<mvc:default-servlet-handler/>
<!--自动扫描包中的Controlller -->
<context:component-scan base-package="com.itheima.controller"/>
<!-- 配置视图解析器: 如何把 handler 方法返回值解析为实际的物理视图 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/><!-- 前缀 -->
<property name="suffix" value=".jsp"/><!-- 后缀,自动拼接 -->
</bean>
<!-- SpringMVC拦截器定义-->
<mvc:interceptors>
<mvc:interceptor>
<!-- 拦截所有请求 -->
<mvc:mapping path="/*"/>
<bean class="com.itheima.interceptor.AuthorizationInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>