Java学习笔记-Day73 SpringMVC 框架(五)



一、Spring与SpringMVC的整合


(1)导入Spring与SpringMVC相关的jar包(添加到WebContent/WEB-INF/lib目录中)。
在这里插入图片描述
(2)在Spring的配置文件applicationContext.xml(src目录下)中添加装配bean包路径、AOP配置、事务管理配置等。

<?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"
	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-4.3.xsd">
		
	<!-- 关于IOC注解支持配置 -->
	<!-- <context:annotation-config></context:annotation-config> -->
	<context:component-scan base-package="com.etc"></context:component-scan>
</beans>

(3)在SpringMVC配置文件springmvc.xml(src目录下)中配置控制器的扫描路径、静态资源处理、视图解析器、文件上传、拦截器等。

<?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:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
		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-4.3.xsd">
	<!-- 组件扫描的路径,指定控制器的扫描包 -->
	<context:component-scan base-package="com.etc.controller"></context:component-scan>
	<!-- 视图解析器的配置 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  		<!-- 注入 -->
  		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
  		<!-- 视图的前缀 -->
  		<property name="prefix" value="/WEB-INF/jsp/"></property>
  		<!-- 视图的后缀 -->
  		<property name="suffix" value=".jsp"></property>
	</bean>
	<!--静态资源的处理,我们的前端控制器不处理静态资源 ,注意,请求还是有走前端控制器,只不过不处理 -->
    <mvc:default-servlet-handler/>
    <!-- 这句话要加,否则控制器失效 -->
    <mvc:annotation-driven></mvc:annotation-driven>
</beans>

(4)在web.xml(WebContent/WEB-INF目录下)中配置Spring的ContextLoaderListener和SpringMVC的前端控制器DispatcherServlet。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>spring_users</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  	<!-- needed for ContextLoaderListener -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>

	<!-- Bootstraps the root web application context before servlet initialization -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	
  <!-- 配置前端控制器 DispatcherServlet -->
  <servlet>
  	<servlet-name>springDispatcherServlet</servlet-name>
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  	<init-param>
  		<param-name>contextConfigLocation</param-name>
  		<param-value>classpath:springmvc.xml</param-value>
  	</init-param>
  	<load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
  	<servlet-name>springDispatcherServlet</servlet-name>
  	<url-pattern>/</url-pattern>
  </servlet-mapping>
  
  <!-- spring提供的characterEncodingFilter配置 -->
  <filter>
  	<filter-name>encodingFilter</filter-name>
  	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  	<!-- 给 CharacterEncodingFilter类的对象进行初始化的赋值  request.setCharacterEncoding-->
  	<init-param>
  		<param-name>encoding</param-name>
  		<param-value>UTF-8</param-value>
  	</init-param>
  	<!-- 响应编码的设置 true 设置response -->
  	<init-param>
  		<param-name>forceEncoding</param-name>
  		<param-value>true</param-value>
  	</init-param>
  </filter>
  
  <!-- 过滤器对哪些资源进行过滤 -->
  <filter-mapping>
  	<filter-name>encodingFilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

(5)在Controller、Service、Dao各个层中添加Spring和SpringMVC的注解。

二、SpringMVC的文件上传与下载

1、文件上传


(1)导入 commons-io.jar 和 commons-fileupload.jar。

在这里插入图片描述
(2)在springmvc.xml文件中定义一个类型为CommonsMultipartResolver、id为multipartResolver的bean。在SpringMVC中专门封装了一个CommonsMultipartResolver类来处理文件上传,所以需要在 SpringMVC的配置文件中加入一个bean。

    <!-- 文件上传解析器 -->
	<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver"></bean>

(3)编写前台页面,要在form标签中添加属性enctype="multipart/form-data",添加子标签<input type="file" name="myfile">

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
	<form action="fileupload.do" method="post" enctype="multipart/form-data">
		<input type="text" name="id" value="1"><br/>
		<input type="text" name="name" value="tom"><br/>
		<input type="file" name="myfile"><br/>
		<input type="submit" value="上传"><br/>
	</form>
</body>
</html>

(4)编写文件上传的控制器代码。

@Controller
public class FileUploadController {
    
    

	@PostMapping("fileupload.do")
	public String uploadFile(HttpServletRequest request, int id, String name,
			@RequestParam("myfile") MultipartFile myfile) {
    
    
		// myfile,image/png,图片1.png,583905
		System.out.println(myfile.getName() + "," + myfile.getContentType() + "," + myfile.getOriginalFilename() + ","
				+ myfile.getSize());
		String path = request.getRealPath("/");
		// D:\develop\apache-tomcat-9.0.41\webapps\springmvc06\
		System.out.println("path=" + path);
		File file = new File(path + myfile.getOriginalFilename());
		try {
    
    
			// 文件上传
			myfile.transferTo(file);
		} catch (IllegalStateException | IOException e) {
    
    
			e.printStackTrace();
			return "error";
		}
		return "success";
	}
}

(5)访问 http://127.0.0.1:8080/springmvc06/formfile.jsp

在这里插入图片描述

2、多文件上传


控制器的方法参数类型由MultipartFile变为MultipartFile数组来实现多文件上传。

(1)编写前台页面。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>多文件上传</title>
</head>
<body>
	<form action="fileuploads.do" method="post" enctype="multipart/form-data">
		<input type="text" name="id" value="1"><br/>
		<input type="text" name="name" value="tom"><br/>
		<input type="file" name="myfiles"><br/>
		<input type="file" name="myfiles"><br/>
		<input type="file" name="myfiles"><br/>
		<input type="submit" value="上传"><br/>
	</form>
</body>
</html>

在这里插入图片描述

(2)编写多文件上传的控制器代码。

@Controller
public class FileUploadController {
    
    
	@PostMapping("fileuploads.do")
	public String uploadFiles(HttpServletRequest request, int id, String name,
			@RequestParam("myfiles") MultipartFile[] myfiles) {
    
    
		for (MultipartFile myfile : myfiles) {
    
    
			if(!myfile.getOriginalFilename().isEmpty()) {
    
    
				String path = request.getRealPath("/");
				File file = new File(path + myfile.getOriginalFilename());
				try {
    
    
					// 文件上传
					myfile.transferTo(file);
				} catch (IllegalStateException | IOException e) {
    
    
					e.printStackTrace();
				}
			}
		}
		return "success";
	}
}

3、限制上传文件的大小


(1)在springmvc.xml的文件上传解析器中添加 maxUploadSize 属性。

    <!-- 文件上传解析器 -->
	<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
		<!-- 指定所上传文件的总大小不能超过200KB,如果超过200kb会报一个异常。注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和。 -->
		<property name="maxUploadSize" value="200000"></property>
	</bean>

(2)在进行上传文件操作的时候,如果传递的文件过大( 比如限制大小为200kb,但是实际上传的文件是200kb的几十倍),就会出现重复定向访问。这和Tomcat有关, 如果用户上传文件的大小超过用户提供的限制大小,Tomcat将要优先拦截请求并且重定向。这时需要修改Tomcat的conf目录下的server.xml文件,要将connector 标签中的maxSwallowSize属性的值修改成合适的大小,或者修改成不限制大小(-1)。

    <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" maxSwallowSize="-1"/>

(3)经过步骤(2)之后,网页会从重复定向访问变成500错误,可以在springmvc中添加SimpleMappingExceptionResolver处理异常,这时会跳转到在SimpleMappingExceptionResolver指定的网页。

	<bean id="handlerExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		<property name="exceptionMappings">
			<props>
				<!-- 遇到MaxUploadSizeExceededException异常时,自动跳转到/WEB-INF/jsp/error_fileupload.jsp页面 -->
				<prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">error_fileupload</prop>
			</props>
		</property>
	</bean>

4、文件下载


(1)编写前台页面。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>文件下载</title>
</head>
<body>
 	<input type="text" id="fileName"><br/>
	<a id="download">下载图片</a>
	<script src="js/jquery.min.js"></script>
	<script type="text/javascript">
		$(function(){
			$("#download").click(function(){
				location.href="filedownload.do?fileName="+$("#fileName").val();
			});
		})
	</script>
</body>
</html>

在这里插入图片描述

(2)编写控制器中的文件下载代码(通过IOl流实现)。

@Controller
public class FileDownloadController {
    
    
	@RequestMapping(value = "filedownload.do", method = RequestMethod.GET)
	public void download(HttpServletRequest request,HttpServletResponse response,@RequestParam("fileName") String fileName) throws IOException {
    
    	
		String realpath = request.getServletContext().getRealPath("/");
		File file = new File(realpath,fileName);
		response.addHeader("Content-Disposition", "attachment;fileName="+fileName);
		FileInputStream is = new FileInputStream(file);
		OutputStream os = response.getOutputStream();
		// 获取is的大小
		byte[] bytes = new byte[is.available()];
		
		is.read(bytes);
		os.write(bytes);
		
		is.close();
		os.close();
	}
}

三、SpringMVC的拦截器

1、介绍


SpringMVC 中的Interceptor拦截器是相当有用的,它的主要作用是拦截用户的请求并进行相应的处理,可以用来做日志记录、权限验证、判断用户是否登陆。

SpringMVC 中的Interceptor拦截请求是通过HandlerInterceptor来实现的。拦截器可以定义多个,拦截器不能拦截jsp文件。

在SpringMVC 中定义一个拦截器主要有两种方式:

第一种方式是定义的Interceptor类要实现了Spring 的HandlerInterceptor 接口,或者是这个类继承实现了HandlerInterceptor 接口的类,比如Spring已经提供的实现了HandlerInterceptor接口的抽象类HandlerInterceptorAdapter 。

第二种方式是定义的Interceptor类实现Spring的WebRequestInterceptor接口,或者是继承实现了WebRequestInterceptor接口的类。

2、实现步骤


(1)通过HandlerInterceptor接口实现拦截器。创建一个实现HandlerInterceptor接口的类。

package com.etc.ws.interceptors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.sun.istack.internal.logging.Logger;

public class MyInterceptor implements HandlerInterceptor {
    
    
	
	Logger logger = Logger.getLogger(MyInterceptor.class);
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
    
    
		logger.info("preHandle");
		if(request.getSession().getAttribute("user") == null) {
    
    
			response.sendRedirect("login.html");
			return false;
		}
		return true;
	}
	
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
    
    
		logger.info("postHandle");
		HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
	}
	
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
    
    
		logger.info("afterCompletion");
		HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
	}
}

(2)在springmvc.xml中中配置拦截器:创建拦截器类的bean,同时要配置在哪些地方使用拦截器。

	<!-- SpringMVC拦截器 -->
	<mvc:interceptors>
		<mvc:interceptor>
			<!-- 所有都会拦截,/**包含子目录 -->
			<mvc:mapping path="/**"></mvc:mapping>
			<!-- 此时访问apis/的url则不会被拦截 -->
			<mvc:exclude-mapping path="/apis/*"></mvc:exclude-mapping>
			<bean class="com.etc.ws.interceptors.MyInterceptor"></bean>
		</mvc:interceptor>
	</mvc:interceptors>

猜你喜欢

转载自blog.csdn.net/qq_42141141/article/details/114273162