Spring-MVC
2019-06-14
Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块,可以取代Servlet,构建轻量级框架。
SpringMVC基本配置
编写Spring控制器
@Controller
public class LoginController{
//给处理方法添加RequestMapping注解
//对应前端请求地址http://localhost:8080/TestApp/login.do
@RequestMapping("/login.do")
public String login(Users users) {
if ("admin".equals(users.getUsername())
&& "123456".equals(users.getPassword())) {
return "index";
} else {
return "login";
}
}
}
可以使用@RequestMapping添加类级别注解
@Controller
@RequestMapping ("/UsersController")
public class UsersController {
@RequestMapping ("/login.do")
public String login() {
return "login";
}
@RequestMapping ("/register.do")
public String register () {
return "register";
}
}
//对应地址http://localhost:8080/TestApp/UsersController/login.do
SpringMVC默认的响应类型为服务器转发,如果不想通过视图解析器进行响应,可以使用如下语句:
return "redirect:/xxx.jsp" //重定向
return "forward:/xxx.jsp" //服务器转发
编写SpringMVC核心配置文件 spring-mvc.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
<!--启用spring mvc注解 -->
<mvc:annotation-driven />
<!--设置使用注解的类所在的包路径 -->
<context:component-scan base-package="com.jevon.controller" />
<!--视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--prefix和suffix:配置视图页面的前缀和后缀(前缀[逻辑视图名]后缀 -->
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
<!--JstlView视图类 -->
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="contentType">
<value>text/html;charset=utf-8</value>
</property>
</bean>
<!-- 静态资源不经过controller -->
<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/css/**" location="/css/" />
<mvc:resources mapping="/js/**" location="/js/" />
</beans>
配置web.xml,启动Spring
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--指定配置文件路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--通过ContextLoaderListener启用spring容器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--请求监听器 -->
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<!--核心控制器 -->
<servlet>
<servlet-name>springmvc</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>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!--请求编码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<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>
<!--启动页 -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>login.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
请求处理方法的参数
如果需要在请求处理方法中使用Servlet API类型,可以将这些类型作为请求参数来接收处理。
可以编写控制器父类拦截Servlet API进行封装。
public class GenericController {
protected HttpServletRequest request;
protected HttpServletResponse response;
protected HttpSession session;
protected ServletContext application;
//被@ModelAttribute注释的方法会在此controller每个方法执行前被执行, 可以用来拦截请求、控制登录权限等
@ModelAttribute
public void setServletApi(HttpServletRequest request,HttpServletResponse response) {
this.request = request;
this.response = response;
this.session = request.getSession();
this.application = request.getServletContext();
}
}
参数类型自动转换
在SpringMVC框架中,对于常用的数据类型,开发者无须手动进行类型转换,SpringMVC框架有许多内置的类型转换器用于完成常用的类型转换。
ModelAndView返回值
SpringMVC提供了org.springframework.web.servlet.ModelAndView类封装逻辑视图及返回值。该类可以添加Map结构数据。
new ModelAndView(逻辑视图);
new ModelAndView(逻辑视图,键,值);
ModelAndView mv = new ModelAndView();
mv.setViewName(逻辑视图);
mv.addObject(键,值);
SpringMVC的工作流程

- 客户端请求被DispatcherServlet(前端控制器)接收,然后根据url映射到业务控制器,然后调用业务控制器的方法做业务逻辑处理。
- 业务控制器返回ModelAndView对象(逻辑视图)给DispatcherServlet。
- DispatcherServlet将获取的逻辑视图传给ViewResolver视图解析器,将逻辑视图解析成物理视图。
- ViewResolver将物理视图返回给DispatcherServlet。
- DispatcherServlet将渲染后的物理视图响应给客户端。
Ajax响应
与Servlet用法基本相同,通过上面的controller父类获取到response对象,拿到输出流写入即可
Spring4的控制器可以使用response对象做出ajax响应,并利用@ResponseBody注解自动将数据生成json响应给浏览器。
@RequestMapping("/UsersController_findById.do")
public @ResponseBody Users findById(String id) {
return this.usersService.findById(id);
}
@RequestMapping("/UsersController_findAll.do")
public @ResponseBody List<Users> findAll() {
List<Users> lists = this.usersService.findAll();
return lists;
}
@RequestMapping("/UsersController_findAllByMap.do")
public @ResponseBody List<Map<String, String>> findAllByMap () {
List<Map<String, String>> lists = this.usersService.findAll();
return results;
}
文件上传
SpringMVC框架的文件上传基于commons-fileupload组件实现,只不过SpringMVC框架在原有文件上传组件上做了进一步封装,简化了文件上传的代码实现。
上传表单
<form action="FileController_upload.do" method="post" enctype="multipart/form-data">
<p>
请选择照片:<input type="file" name="photo" />
</p>
<input type="submit" value="上传" />
</form>
控制器
//处理文件上传 如果上传多个文件,
//可以设定MultipartFile数组或List集合参数 List<MultipartFile> photo
@RequestMapping("/FileController_upload.do")
public String upload(MultipartFile photo) throws Exception {
if (photo.isEmpty()) {
System.out.println("文件未上传");
return "error";
} else {
System.out.println("文件名: " + file.getOriginalFilename());
System.out.println("文件类型: " + file.getContentType());
System.out.println("文件大小: " + file.getSize());
System.out.println("========================================");
String fileName = photo.getOriginalFilename();
String ext = fileName.substring(fileName.lastIndexOf("."),
fileName.length());// 获得上传文件的扩展名
String newFileName = new SimpleDateFormat("yyyyMMddhhmmssSSS")
.format(new Date())+ (10000 + new Random().nextInt(90000)) + ext;
File destFile = new File(this.application
.getRealPath("upload"), newFileName); // 创建目标文件
photo.transferTo(destFile);// 复制文件
return "success";
}
}
spring-mvc.xml文件上传配置
<!--文件上传处理器 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
<!-- 指定所上传文件的总大小不能超过512K。
注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和
-->
<property name="maxUploadSize" value="512000"/>
</bean>
<!--文件上传异常处理器 -->
<bean id="exceptionResolver"
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!-- 抛出异常时,自动跳转到指定页面 -->
<prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">
error
</prop>
</props>
</property>
</bean>
MultipartFile API说明
返回值 | 方法名 | 说明 |
---|---|---|
byte[] | getBytes() | 以字节数组类型返回文件内容 |
String | getContentType() | 获取文件类型 |
InputStream | getInputStream() | 获取稳健的输入流 |
String | getName() | 返回参数名称多部分的形式 |
String | getOriginalFilename | 返回文件名 |
long | getSize() | 返回文件大小(字节) |
boolean | isEmpty() | 判断是否为空 |
void | transferTo() | 复制文件到指定文件 |
文件下载
@RequestMapping("/FileController_download.do")
public void downLoad(String id) throws Exception {
String path = this.application.getRealPath("upload") + "\\2017090102581803133040.jpg";
File file = new File(path);
this.response.setContentType("application/x-msdownload;charset=utf-8");
this.response.setHeader("Content-disposition","attachment; filename="
+ new String(file.getName().getBytes("UTF-8"), "iso-8859-1"));
this.response.setHeader("Content-Length", String.valueOf(file.length()));
InputStream input = new FileInputStream(file);
byte data[] = new byte[(int) file.length()];
input.read(data);
input.close();
OutputStream out = this.response.getOutputStream();
out.write(data);
out.close();
}
springmvc异常统一处理
在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种异常需要处理。如果每个过程都单独手动用try-catch处理,则系统的代码耦合度高,工作量大且不好统一,维护的工作量也很大。 Spring MVC提供了统一处理异常的解决方案。
Spring MVC处理异常有3种方式:
- 使用Spring MVC提供的异常处理器SimpleMappingExceptionResolver;
- 实现Spring的异常处理接口HandlerExceptionResolver 自定义异常处理器;
- 使用@ExceptionHandler注解实现异常处理;
修改spring-mvc.mxl
<!-- 异常处理器 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 定义默认的异常处理页面 -->
<property name="defaultErrorView" value="error"></property>
<!-- 定义异常处理页面用来获取异常信息的变量名,默认名为exception -->
<property name="exceptionAttribute" value="ex"></property>
<!-- 定义需要特殊处理的异常,用类名或完全路径名作为key,异常处理页名作为值 -->
<property name="exceptionMappings">
<props>
<prop key="com.exception.MyException">error_myexception</prop>
<!-- 这里还可以继续扩展对不同异常类型的处理 -->
</props>
</property>
</bean>