(四)拦截器和文件上传下载

本文详细介绍了SpringMVC中的拦截器机制,包括自定义拦截器的实现和用户登录验证的示例。同时,讲解了文件上传和下载的处理,涉及到文件上传的配置、Controller处理及文件保存方法。此外,还展示了文件下载的实现步骤,包括设置响应头、读取文件和写出文件。
摘要由CSDN通过智能技术生成

一、拦截器

类似于Servlet开发中的filter,用于对处理进行预处理和后处理
过滤器与拦截器:是AOP思想的应用

过滤器

  • servlet规范中的一部分,任何java web工程都可以使用
  • 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截

拦截器

  • 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
  • 拦截器只会拦截访问的控制器方法, 如果访问的是jsp/html/css/image/js是不会进行拦截的

1.1、自定义拦截器

  1. 自定义拦截器,必须实现 HandlerInterceptor 接口。

    public class MyInterceptor implements HandlerInterceptor {
    	//在请求处理的方法之前执行
    	//如果返回true执行下一个拦截器
    	//如果返回false就不执行下一个拦截器
    	public boolean preHandle(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse, Object o) throws Exception {
    		System.out.println("------------处理前------------");
    		return true;
    	}
    	//在请求处理方法执行之后执行
    	public void postHandle(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    		System.out.println("------------处理后------------");
    	}
    	//在dispatcherServlet处理后执行,做清理工作.
    	public void afterCompletion(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    		System.out.println("------------清理------------");
    	}
    }
    
  2. 在springmvc的配置文件中配置拦截器

<!--关于拦截器的配置-->
<mvc:interceptors>
	<mvc:interceptor>
		<!--/** 包括路径及其子路径-->
		<!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截-->
		<!--/admin/** 拦截的是/admin/下的所有-->
		<mvc:mapping path="/**"/>
		<!--bean配置的就是拦截器-->
		<bean class="com.kuang.interceptor.MyInterceptor"/>
	</mvc:interceptor>
</mvc:interceptors>

1.2、验证用户是否登录

流程:
拦截用户请求,判断用户是否登陆。如果用户已经登陆。放行, 如果用户未登陆,跳转到登陆页面
controller判断用户名密码是否正确。如果正确,向session中写入用户信息。返回登陆成功。

  1. 登录页面

    <body>
    	<form action="${pageContext.request.contextPath}/user/login">
    		用户名:<input type="text" name="uname"> <br>
    		密码: <input type="password" name="pwd"> <br>
    		<input type="submit" value="提交">
    	</form>
    </body>
    
  2. Controller

    @Controller
    @RequestMapping("/user")
    public class UserController {
    	//跳转到登陆页面
    	@RequestMapping("/jumplogin")
    	public String jumpLogin() throws Exception {
    		return "login";
    	}
    	//跳转到成功页面
    	@RequestMapping("/jumpSuccess")
    	public String jumpSuccess() throws Exception {
    		return "success";
    	}
    	//登陆提交
    	@RequestMapping("/login")
    	public String login(HttpSession session, String uname, String pwd) throws Exception {
    		// 向session记录用户身份信息
    		System.out.println("接收前端==="+uname);
    		session.setAttribute("user", username);
    		return "success";
    	}
    	//退出登陆
    	@RequestMapping("logout")
    	public String logout(HttpSession session) throws Exception {
    		// session 过期
    		session.invalidate();
    		return "login";
    	}
    }
    
  3. 登录成功页面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    	<title>Title</title>
    </head>
    <body>
    	<h1>登录成功页面</h1>
    	<hr>
    	${user}
    	<a href="${pageContext.request.contextPath}/user/logout">注销</a>
    </body>
    </html>
    
  4. 在index页面上测试跳转,没有拦截器前,没有登陆的用户也可以进入登陆成功页面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    <title>$Title$</title>
    </head>
    <body>
    <h1>首页</h1>
    <hr>
    <%--登录--%>
    <a href="${pageContext.request.contextPath}/user/jumplogin">登录</a>
    <a href="${pageContext.request.contextPath}/user/jumpSuccess">成功页面
    </a>
    </body>
    </html>
    
  5. 拦截器

    public class LoginInterceptor implements HandlerInterceptor {
    	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
    		// 如果是登陆页面则放行
    		System.out.println("uri: " + request.getRequestURI());
    		if (request.getRequestURI().contains("login")) {
    			return true;
    		}
    		HttpSession session = request.getSession();
    		// 如果用户已登陆也放行
    		if(session.getAttribute("user") != null) {
    			return true;
    		}
    		// 用户没有登陆跳转到登陆页面
    		request.getRequestDispatcher("/WEBINF/jsp/login.jsp").forward(request, response);
    		return false;
    	}
    	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    	}
    	public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    	}
    }
    
  6. 注册拦截器

    <!--关于拦截器的配置-->
    <mvc:interceptors>
    	<mvc:interceptor>
    		<mvc:mapping path="/**"/>
    		<bean id="loginInterceptor"
    		class="com.kuang.interceptor.LoginInterceptor"/>
    	</mvc:interceptor>
    </mvc:interceptors>
    

二、文件上传和下载

如果要使用Spring的文件上传功能,则需要在SpringMVC上下文中配置MultipartResolver。
**前端:**请求方式必须为postenctype设为multipart/form-data。这样浏览器才会把文件以二进制数据发送给服务器。

enctype属性:

  • application/x-www=form-urlencoded:默认方式,只处理表单域中的 value 属性值,将表单域中的值处理成 URL 编码。
  • multipart/form-data:以二进制流的方式来处理表单数据,把文件域指定文件的内容也封装到请求参数中,不会对字符编码。
  • text/plain:把空格转换为 “+” ,其他字符都不做编码处理,这种方式适用直接通过表单发送邮件。
<form action="/upload" enctype="multipart/form-data" method="post">
	<input type="file" name="file"/>
	<input type="submit" value="upload">
</form>

Spring MVC使用Apache Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver。因此,SpringMVC的文件上传还需要依赖Apache Commons FileUpload的组件。

2.1、文件上传

  1. 导入依赖

    <!--文件上传,Maven会自动导入他的依赖包 commons-io包-->
    <dependency>
    	<groupId>commons-fileupload</groupId>
    	<artifactId>commons-fileupload</artifactId>
    	<version>1.3.3</version>
    </dependency>
    <!--servlet-api导入高版本的-->
    <dependency>
    	<groupId>javax.servlet</groupId>
    	<artifactId>javax.servlet-api</artifactId>
    	<version>4.0.1</version>
    </dependency>
    
  2. 配置multipartResolver 的bean

    <!--文件上传配置,id必须为multipartResolver,否则上传文件会报404-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    	<!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->
    	<property name="defaultEncoding" value="utf-8"/>
    	<!-- 上传文件大小上限,单位为字节(10485760=10M) -->
    	<property name="maxUploadSize" value="10485760"/>
    	<property name="maxInMemorySize" value="40960"/>
    </bean>
    
  3. Controller

    @Controller
    public class FileController {
    	//@RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象
    	//批量上传CommonsMultipartFile则为数组即可
    	@RequestMapping("/upload")
    	public String fileUpload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
    		//获取文件名 : file.getOriginalFilename();
    		String uploadFileName = file.getOriginalFilename();
    		//如果文件名为空,直接回到首页!
    		if ("".equals(uploadFileName)){
    			return "redirect:/index.jsp";
    		}
    		System.out.println("上传文件名 : "+uploadFileName);
    		//上传路径保存设置
    		String path = request.getServletContext().getRealPath("/upload");
    		//如果路径不存在,创建一个
    		File realPath = new File(path);
    		if (!realPath.exists()){
    			realPath.mkdir();
    		}
    		System.out.println("上传文件保存地址:"+realPath);
    		InputStream is = file.getInputStream(); //文件输入流
    		OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件输出流
    		//读取写出
    		int len=0;
    		byte[] buffer = new byte[1024];
    		while ((len=is.read(buffer))!=-1){
    			os.write(buffer,0,len);
    			os.flush();
    		}
    		os.close();
    		is.close();
    		return "redirect:/index.jsp";
    	}
    }
    

采用file.Transto 来保存上传的文件

/*
* 采用file.Transto 来保存上传的文件
*/
@RequestMapping("/upload2")
public String fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
	//上传路径保存设置
	String path = request.getServletContext().getRealPath("/upload");
	File realPath = new File(path);
	if (!realPath.exists()){
		realPath.mkdir();
	}
	//上传文件地址
	System.out.println("上传文件保存地址:"+realPath);
	//通过CommonsMultipartFile的方法直接写文件(注意这个时候)
	file.transferTo(new File(realPath +"/"+ file.getOriginalFilename()));
	return "redirect:/index.jsp";
}

2.2、文件下载

文件下载步骤:

  1. 设置 response 响应头
  2. 读取文件 – InputStream
  3. 写出文件 – OutputStream
  4. 执行操作
  5. 关闭流
@RequestMapping(value="/download")
public String downloads(HttpServletResponse response ,HttpServletRequest request) throws Exception{
	//要下载的图片地址
	String path = request.getServletContext().getRealPath("/upload");
	String fileName = "基础语法.jpg";
	//1、设置response 响应头
	response.reset(); //设置页面不缓存,清空buffer
	response.setCharacterEncoding("UTF-8"); //字符编码
	response.setContentType("multipart/form-data"); //二进制传输数据
	//设置响应头
	response.setHeader("Content-Disposition", "attachment;fileName="+URLEncoder.encode(fileName, "UTF-8"));
	File file = new File(path,fileName);
	//2、 读取文件--输入流
	InputStream input=new FileInputStream(file);
	//3、 写出文件--输出流
	OutputStream out = response.getOutputStream();
	byte[] buff =new byte[1024];
	int index=0;
	//4、执行 写出操作
	while((index= input.read(buff))!= -1){
		out.write(buff, 0, index);
		out.flush();
	}
	out.close();
	input.close();
	return null;
}

前端:

<a href="/download">点击下载</a>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值