主要内容
MVC 架构模式简介
SpringMVC 简介
SpringMVC 的基本使用
SpringMVC 基于注解开发
获取请求参数
指定处理请求类型
SpringMVC 处理响应
文件上传与下载
静态资源映射 S
pringMVC 的异常处理
SpringMVC 拦截器
SpringMVC 对 Restful 风格的支持
JSON 数据处理
SpringMVC 解决跨域请求问题
SpringMVC 常用注解
SSM 框架整合
基于 Maven 搭建 SSM 整合
一、 MVC 架构模式简介
MVC 是 Model、View 和 Controller 的缩写,分别代表 Web 应用程序中的 3 种职责。
- 模型:用于存储数据以及处理用户请求的业务逻辑。
- 视图:向控制器提交数据,显示模型中的数据。
- 控制器:根据视图提出的请求判断将请求和数据交给哪个模型处理,将处理后的有 关结果交给哪个视图更新显示。 基于 Servlet 的 MVC 模式
- 模型:一个或多个 JavaBean 对象,用于存储数据(实体模型,由 JavaBean 类创建)和处理业务逻辑(业务模型,有一般的Java类创建)。
- 视图:一个或多个JSP页面,向控制器提交数据和为模型提供数据显示,JSP页面主要使用HTML标记和JavaBean标价来显示数据。
- 控制器:一个或多个Servlet对象,根据视图提交的请求 进行控制 ,即将请求转发给处理业务逻辑的JavaBean,并将处理结果存放到实体模型JavaBean中,输出给视图显示。
二、 SpringMVC 简介
1 什么是 SpringMVC
SpringMVC是一个基于MVC模式的Web框架,是Spring框架的一个模块 。它以SpringIOC容器为基础,并利用容器的特性来简化它的配置,所以SpringMVC和Spring可直接整合使用。SpringMVC对MVC流程进行了封装,屏蔽掉很多底层代码,让开发者可以更加轻松快捷的完成基于MVC模式的web开发。
2 SpringMVC中重要的组件
- DispatcherServlet:前端控制器,接受所有请求。
- HandlerMapping:处理器映射器,根据配置的映射规则,找到对应的处理器。
- HandlerAdapter:处理器适配器,执行处理器中处理请求的方法。
- ViewResolver:视图解析器,定位视图。
3 Spring MVC 工作流程
SpringMVC的工作流程如下:
- 客户端请求提交到 DispatcherServlet。
- 由 DispatcherServlet 控制器通过 HandlerMapping,找到处理请求的 Controller。
- DispatcherServlet 将请求提交到 Controller。
- Controller 调用业务逻辑处理后返回 ModelAndView。
- DispatcherServlet 通过 ViewResolver 视图解析器,找到 ModelAndView 指定的视 图。
- 视图负责渲染并将结果显示到客户端。
三、 SpringMVC 的基本使用
1 Jar 包依赖
Spring 核心容器模块
spring-beans-5.2.7.RELEASE.jar
spring-context-5.2.7.RELEASE.jar
spring-core-5.2.7.RELEASE.jar
spring-expression-5.2.7.RELEASE.jar
Commons-Loggin 日志
commons-logging-1.2.jar
Spring AOP 模块
spring-aop-5.2.7.RELEASE.jar
SpringWeb 模块
spring-web-5.2.7.RELEASE.jar
SpringWebMVC 模块
spring-webmvc-5.2.7.RELEASE.jar
Servlet
servlet-api.jar
2 搭建环境
2.1创建项目
2.2创建 springMVC 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
3 配置前端控制器
修改 web.xml
<?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_4_0.xsd"
version="4.0">
<!--配置SpringMVC的前端控制器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--如果未指定springMVC配置文件的路径以及名称,那么前端控制器默认
会去WEB/INF目录中查找一个名称为'springmvc'-servlet.xml-->
<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>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
4 创建 Controller 处理请求
4.1创建 Controller
package com.bjsxt.web.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DemoController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/index.jsp");
modelAndView.addObject("msg","Hello SpringMVC");
return modelAndView;
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
${
msg}
</body>
</html>
4.2配置 Controller
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置Controller-->
<bean id="/demo" class="com.bjsxt.web.controller.DemoController"/>
</beans>
四、 SpringMVC 基于注解的使用方式
在 SpringMVC 的基本使用中我们是以传统方式创建的控制器,它需要实现 Controller 接 口。传统风格的控制器不仅需要在配置文件中配置映射,而且只能编写一个处理方法,不够灵活。
使用基于注解的控制器具有以下两个优点:
- 在基于注解的控制器类中可以编写多个处理方法,进而可以处理多个请求,这就允许将 相关的操作编写在同一个控制器类中,从而减少控制器类的数量,方便以后的维护。
- 基于注解的控制器不需要在配置文件中部署映射,仅需要使用 @RequestMapping 注解 就可以将一个 URI 绑定到类或方法上。
1 注解介绍
1.1@Controller
@Controller 注解用于指定 Bean 对象为控制器。
1.2@RequestMapping
@RequestMapping 用于将一个 URI 绑定到类上或类的方法中。
2 注解使用
2.1创建项目
2.2配置前端控制器
<?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_4_0.xsd"
version="4.0">
<!--配置前端控制器-->
<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:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2.3创建控制器
@Controller
//http://localhost:8888/springmvcanndemo/suibian/ann
@RequestMapping("/suibian")
public class AnnController {
//http://localhost:8888/springmvcanndemo/ann
@RequestMapping("/ann")
public ModelAndView annDemo(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/index.jsp");
modelAndView.addObject("msg","Hello Oldlu");
return modelAndView;
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
${
msg}
<hr/>
${
username}
<hr/>
${
name} ${
age}
<hr/>
${
name} ${
userlike}
<hr/>
${
user} ${
address}
</body>
</html>
2.4配置注解扫描
<?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.xsd" >
<context:component-scan base-package="com.bjsxt.web.controller"/>
</beans>
3 配置注解驱动
在基于注解方式开发控制器时,需要添加<mvc:annotation-driven/>
标签,它是启用 MVC 注解的钥匙。如果没有使用这个标签,而仅仅是使用<context:component-scan/>
标签扫描并 注册了相关的控制器,那么仅是@Controller @RequestMapping
基本功能的注解可以使用除 此以外的相关的注解并不能使用。
<mvc:annotation-driven/>
的作用是提供扩展功能的。
它的处理类 AnnotationDrivenBeanDefinitionParser
会注册很多基于注解开发时所用到的 Bean 对 象 到 容 器 中 。 其 中 包 含 RequestMappingHandlerMapping
、 RequestMappingHandlerAdapter
与 ExceptionHandlerExceptionResolver
三个 bean。
3.1添加 mvc 命名空间
xmlns:mvc="http://www.springframework.org/schema/mvc"
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
3.2配置注解驱动
<?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">
<context:component-scan base-package="com.bjsxt.web.controller"/>
<!-- 配置注解驱动-->
<mvc:annotation-driven/>
</beans>
五、获取请求参数
在 Servlet 中我们通过 request.getParameter(name)
方法获取请求参数。该方式存在 两个问题:
- 请求参数较多时会出现代码冗余的显现。
- 与容器紧耦合。
在 SpringMVC 中可以使用 HttpServletRequest 对象获取请求数据,同时还提供了参数注 入的方式用于获取请求数据。
SpringMVC 参数注入的优点:
- 简化参数接收形式(不需要调用任何方法。需要什么参数,就在控制器方法中提供什么参数)。
- 参数类型不需要自己转换了。如果类型不符会抛出
400异常
。 - 可将参数自动封装为对象。
- 如果没有该参数对应的数据,可为该参数指定默认值。
1 通过 HttpServletRequest 对象获取请求数据
在AnnController.class添加方法
/**
* 通过HttpServletRequest对象获取请求参数
* @return
*/
@RequestMapping("/getData")
public ModelAndView getRequestParameter(HttpServletRequest request){
String username = request.getParameter("name");
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/index.jsp");
modelAndView.addObject("username",username);
return modelAndView;
}
2 通过参数注入获取请求参数
2.1注入多参数
/**
* 通过SpringMVC参数注入方式获取请求参数-注入多参数
* @param username
* @param userage
* @return
*/
@RequestMapping("/addUsers")
public ModelAndView addUsers(String username,int userage){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/index.jsp");
modelAndView.addObject("name",username);
modelAndView.addObject("age",userage);
return modelAndView;
}
2.2@RequestParam 注解
@RequestParam
:将请求参数绑定到控制器的方法参数上。
value
:参数名
required
:是否包含该参数,默认为 true,表示该请求路径中必须包含该参数,如果不 包含就报错。
defaultValue
:默认参数值,如果设置了该值,required=true 将失效,自动为 false,如果没有传该参数,就使用默认值
/**
* @RequestParam使用
* @param username
* @param userage
* @return
*/
@RequestMapping("/addUsers2")
public ModelAndView addUsers2(@RequestParam(value = "name",required = true,defaultValue = "oldlu") String username,@RequestParam("age") int userage){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/index.jsp");
modelAndView.addObject("name",username);
modelAndView.addObject("age",userage);
return modelAndView;
}
2.3 注入集合参数
在SpringMVC请求参数注入中,如果有多请求参数的name相同,那么可以使用String[]
或List
集合来接受请求参数。如果使用的List
类型需要在该参数前添加@RequestParam
注 解,String[]
则不需要。
2.3.1 创建页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="suibian/addUsers3">
用户姓名:<input type="text" name="username"/><br/>
爱好:<br/>
体育<input type="checkbox" value="Sport" name="userlike"/>
音乐<input type="checkbox" value="Music" name="userlike"/>
艺术<input type="checkbox" value="Art" name="userlike"/><br/>
<input type="submit" value="OK"/>
</form>
</body>
</html>
2.3.2 修改控制器
@RequestMapping("/addUsers3")
public ModelAndView addUsers3(String username,@RequestParam List<String> userlike){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/index.jsp");
modelAndView.addObject("name",username);
String temp = "";
for(String str:userlike){
temp+= str+" ";
}
modelAndView.addObject("userlike",temp);
return modelAndView;
}
2.4注入对象参数
在 SpringMVC 的请求参数注入中,可以使用注入 POJO 方式来接收请求参数。要求:请 求参数的 name 必须与 POJO 的属性名相同。
2.4.1 注入单个对象
2.4.1.1 创建 POJO
package com.bjsxt.pojo;
import java.util.List;
import java.util.Map;
public class Users {
private String username;
private List<String> userlike;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public List<String> getUserlike() {
return userlike;
}
public void setUserlike(List<String> userlike) {
this.userlike = userlike;
}
@Override
public String toString() {
return "Users{" +
"username='" + username + '\'' +
", userlike=" + userlike +
'}';
}
}
2.4.1.2 修改控制器
@RequestMapping("/addUsers4")
public ModelAndView addUsers4(Users user){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/index.jsp");
modelAndView.addObject("name",user.getUsername());
String temp = "";
for(String str:user.getUserlike()){
temp+= str+" ";
}
modelAndView.addObject("userlike",temp);
return modelAndView;
}
2.4.2 注入关联对象
SpringMVC 可以根据对象的关联关系实现请求参数的注入。
2.4.2.1 创建 POJO
package com.bjsxt.pojo;
public class Address {
private String phonenumber;
private String postcode;
public String getPhonenumber() {
return phonenumber;
}
public void setPhonenumber(String phonenumber) {
this.phonenumber = phonenumber;
}
public String getPostcode() {
return postcode;
}
public void setPostcode(String postcode) {
this.postcode = postcode;
}
@Override
public String toString() {
return "Address{" +
"phonenumber='" + phonenumber + '\'' +
", postcode='" + postcode + '\'' +
'}';
}
}
package com.bjsxt.pojo;
import java.util.List;
import java.util.Map;
public class Users {
private String username;
private List<String> userlike;
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public List<String> getUserlike() {
return userlike;
}
public void setUserlike(List<String> userlike) {
this.userlike = userlike;
}
@Override
public String toString() {
return "Users{" +
"username='" + username + '\'' +
", userlike=" + userlike +
'}';
}
}
2.4.2.2 创建页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="suibian/addUsers5">
用户姓名:<input type="text" name="username"/><br/>
爱好:<br/>
体育<input type="checkbox" value="Sport" name="userlike"/>
音乐<input type="checkbox" value="Music" name="userlike"/>
艺术<input type="checkbox" value="Art" name="userlike"/><br/>
地址:<br/>
电话号码:<input type="text" name="address.phonenumber"/>
邮编:<input type="text" name="address.postcode"/>
<input type="submit" value="OK"/>
</form>
</body>
</html>
2.4.2.3 修改控制器
@RequestMapping("/addUsers5")
public ModelAndView addUsers5(Users user){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/index.jsp");
modelAndView.addObject("user",user.toString());
modelAndView.addObject("address",user.getAddress().toString());
return modelAndView;
}
2.4.3 向集合中注入对象
在 SpringMVC 中可以向一个集合属性中注入对象。
2.4.3.1 List 集合
2.4.3.1.1 修改 Users
package com.bjsxt.pojo;
import java.util.List;
import java.util.Map;
public class Users {
private String username;
private List<String> userlike;
private Address address;
private List<Address> addressList;
public List<Address> getAddressList() {
return addressList;
}
public void setAddressList(List<Address> addressList) {
this.addressList = addressList;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public List<String> getUserlike() {
return userlike;
}
public void setUserlike(List<String> userlike) {
this.userlike = userlike;
}
@Override
public String toString() {
return "Users{" +
"username='" + username + '\'' +
", userlike=" + userlike +
'}';
}
}
2.4.3.1.2 创建页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="suibian/addUsers6">
用户姓名:<input type="text" name="username"/><br/>
爱好:<br/>
体育<input type="checkbox" value="Sport" name="userlike"/>
音乐<input type="checkbox" value="Music" name="userlike"/>
艺术<input type="checkbox" value="Art" name="userlike"/><br/>
地址:<br/>
电话号码:<input type="text" name="addressList[0].phonenumber"/>
邮编:<input type="text" name="addressList[0].postcode"/>
电话号码:<input type="text" name="addressList[1].phonenumber"/>
邮编:<input type="text" name="addressList[1].postcode"/>
<input type="submit" value="OK"/>
</form>
</body>
</html>
2.4.3.1.3 修改控制器
@RequestMapping("/addUsers6")
public ModelAndView addUsers6(Users user){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/index.jsp");
modelAndView.addObject("user",user.toString());
modelAndView.addObject("address",user.getAddressList());
return modelAndView;
}
2.4.3.2 Map 集合
2.4.3.2.1 修改 Users
package com.bjsxt.pojo;
import java.util.List;
import java.util.Map;
public class Users {
private String username;
private List<String> userlike;
private Address address;
private List<Address> addressList;
private Map<String,Address> addressMap;
public Map<String, Address> getAddressMap() {
return addressMap;
}
public void setAddressMap(Map<String, Address> addressMap) {
this.addressMap = addressMap;
}
public List<Address> getAddressList() {
return addressList;
}
public void setAddressList(List<Address> addressList) {
this.addressList = addressList;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public List<String> getUserlike() {
return userlike;
}
public void setUserlike(List<String> userlike) {
this.userlike = userlike;
}
@Override
public String toString() {
return "Users{" +
"username='" + username + '\'' +
", userlike=" + userlike +
'}';
}
}
2.4.3.2.2 创建页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="suibian/addUsers7" method="post">
用户姓名:<input type="text" name="username"/><br/>
爱好:<br/>
体育<input type="checkbox" value="Sport" name="userlike"/>
音乐<input type="checkbox" value="Music" name="userlike"/>
艺术<input type="checkbox" value="Art" name="userlike"/><br/>
地址:<br/>
电话号码:<input type="text" name="addressMap['one'].phonenumber"/>
邮编:<input type="text" name="addressMap['one'].postcode"/>
电话号码:<input type="text" name="addressMap['two'].phonenumber"/>
邮编:<input type="text" name="addressMap['two'].postcode"/>
<input type="submit" value="OK"/>
</form>
</body>
</html>
2.4.3.2.3 修改控制器
@RequestMapping(value = "/addUsers7")
public ModelAndView addUsers7(Users user){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/index.jsp");
modelAndView.addObject("user",user.toString());
Set<Map.Entry<String,Address>> set = user.getAddressMap().entrySet();
modelAndView.addObject("address",set);
return modelAndView;
}
3 字符编码过滤器
在请求参数中如果含有中文,会出现乱码现象。
3.1Get 请求含有中文乱码解决方案
修改 Tomcat 的 server.xml 配置文件
3.2Post 请求含有中文乱码解决方案
web.xml
<!--Spring 中提供的字符编码过滤器-->
<filter>
<filter-name>encodeFilter</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>
</filter>
<filter-mapping>
<filter-name>encodeFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
六、 指定处理请求类型
1 @RequestMapping
在@RequestMapping 注解中如果并未指定处理请求类型,那么含有该注解的方法既可以 处理 GET 类型请求也可以处理 POST 类型的请求。如果需要指定只能处理某种类型的请求,可以通过 method 属性指定请求类型。
@RequestMapping(value = "/addUsers7",method = RequestMethod.POST)
public ModelAndView addUsers7(Users user){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/index.jsp");
modelAndView.addObject("user",user.toString());
Set<Map.Entry<String,Address>> set = user.getAddressMap().entrySet();
modelAndView.addObject("address",set);
return modelAndView;
}
2 @GetMapping
@GetMapping 注解表示只能处理 Get 类型请求。
@GetMapping("/addUsers7")
public ModelAndView addUsers7(Users user){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/index.jsp");
modelAndView.addObject("user",user.toString());
Set<Map.Entry<String,Address>> set = user.getAddressMap().entrySet();
modelAndView.addObject("address",set);
return modelAndView;
}
3 @PostMapping
@PostMapping 注解表示只能处理 Post 类型请求。
@PostMapping("/addUsers7")
public ModelAndView addUsers7(Users user){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("/index.jsp");
modelAndView.addObject("user",user.toString());
Set<Map.Entry<String,Address>> set = user.getAddressMap().entrySet();
modelAndView.addObject("address",set);
return modelAndView;
}
七、 SpringMVC 处理响应
1 配置视图解析器
在 SpringMVC 中提供了 13 个视图解析器,用于支持不同的视图技术。视图解析器最大 的特点是可以将控制器中处理请求的逻辑和视图中渲染实现解耦。
InternalResourceViewResolver 是 SpringMVC 中默认的视图解析器,用来解析 JSP 视图。 能将视图名映射为 JSP 文件。
<!--配置视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewR esolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
PageController
package com.bjsxt.web.controller;
@Controller
@RequestMapping("/page")
public class PageController {
@RequestMapping("/login")
public String showLogin(){
return "login";
}
}
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
Login.....
</body>
</html>
WEB-INF下目录是不允许通过URL直接访问的
配置视图方法跳转
2 SpringMVC 作用域传值
作用域:“数据共享的范围”,也就是说数据能够在多大的范围内有效。
2.1Request 作用域传值
2.1.1 使用原生的 HttpServletRequest
@RequestMapping("/login")
public String showLogin(HttpServletRequest request){
request.setAttribute("msg","Hello Oldlu");
return "login";
}
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
Login.....${
msg}
</body>
</html>
2.1.2 使用 Map 集合
SpringMVC 会为 Map 接口注入 BindingAwareModelMap 对象。该对象是由 Spring 提供的 一个实现了 Map 接口的对象。SpringMVC 会把该对象中的数据放入到 HttpServletRequest 对 象中,其目的是为了解除控制器与容器的耦合。
@RequestMapping("/login")
public String showLogin(HttpServletRequest request, Map<String,String> map){
map.put("msg","Hello Bjsxt");
return "login";
}
2.1.3 使用 Model 接口
在 SpringMVC 中提供了一个 Model 类型的接口,该接口定义了传递数据的基本行为。 如果 在处 理请求 的方 法中指 定了 Model 类型 的参 数,那 么 SpringMVC 会注 入一个 BindingAwareModelMap 对象,并通过该对象把数据放入到 HttpServletRequest 对象中。
@RequestMapping("/login")
public String showLogin(HttpServletRequest request, Map<String,String> map, Model model){
model.addAttribute("msg","Hello Oldlu");
return "login";
}
2.2 Session 作用域传值
Session 作用域表示在当前会话中有效。在 SpringMVC 中对于 Session 作用域传值,只能 使用 HttpSession 对象来实现。对于 HttpSession 对象的获取方式有两种:
- 通过参数注入方式获取 HttpSession 对象。
- 通过注入 HttpServletRequest 对象,并通过该对象获取 HttpSession。
@RequestMapping("/login")
public String showLogin(HttpServletRequest request, Map<String,String> map, Model model,HttpSession session){
//HttpSession session = request.getSession();
session.setAttribute("msg","Hello Bjsxt");
return "login";
}
2.3Application 作用域传值
Application 作用域表示在整个应用范围都有效。在 SpringMVC 中对于 Application 作用域 传值,只能使用 ServletContext
对象来实现。但是对于该对象的获取方式不能直接向方法中 注入。需要通过 HttpServletRequest
或者 HttpSession
对象获取。
@RequestMapping("/login")
public String showLogin(HttpServletRequest request, Map<String,String> map, Model model,HttpSession session){
//ServletContext servletContext = request.getSession().getServletContext();
ServletContext servletContext = session.getServletContext();
servletContext.setAttribute("msg","Hello Bjsxt");
return "login";
}
3 SpringMVC 的响应方式
3.1请求转发
3.1.1 使用 Servlet API
在 SpringMVC 中可以使用 HttpServletRequest
对象实现请求转发。
@RequestMapping("/login2")
public void showLogin2(HttpServletRequest request, HttpServletResponse response)throws Exception{
request.setAttribute("msg","Oldlu");
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(re quest,response);
}
3.1.2 使用 Forward 关键字实现请求转发跳转
如果使用forward
关键字实现请求转发跳转时,是通过 SpringMVC 的 DispatcherServlet
组件来完成的。不会执行视图解析器,所以需要指定请求跳转页面的完整 URI。
@RequestMapping("/login3")
public String showLogin3(Model model){
model.addAttribute("msg","Bjsxt");
return "forward:/WEB-INF/jsp/login.jsp";
}
3.1.3 使用视图解析器实现请求转发
在 SpringMVC 的视图解析器中使用的是请求转发方式来实现页面跳转。可以在配置视图 解析器时指定视图的前置与后缀。
3.1.3.1 配置视图解析器
<!--配置视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewR esolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
3.1.3.2 请求转发
@RequestMapping("/login4")
public String showLogin4(Model model){
model.addAttribute("msg","ITBZ");
return "login";
}
3.2重定向
在 SpringMVC 需要使用 redirect
关键字实现重定向的跳转。在重定向跳转中是不经过视 图解析器的。
@RequestMapping("/redirectLogin")
public String redirectLogin(){
return "redirect:/page/login4";
}
八、 文件上传与下载
1 文件上传
在 SpringMVC 中提供了用于处理文件上传的组件 CommonsMultipartResolver
(多部件解 析器)。可以通过该组件很方便的实现文件上传。该组件的运行需要依赖于 Apache 的 commons-fileupload
与 commons-io
包。
1.1搭建环境
1.1.1 创建项目并添加 jar 包
1.1.2 添加 springmvc 配置文件
<?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">
<!-- 配置注解扫描-->
<context:component-scan base-package="com.bjsxt.web.controller"/>
<!--配置注解驱动-->
<mvc:annotation-driven/>
<!--配置视图解析器-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--配置多部件解析器-->
<!--多部件解析器的id必须为multipartResolver-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件总容量。单位字节 10M = 10*1024*1024 默认value="-1"表示对上传容量没有限制-->
<property name="maxUploadSize" value="10485760"/>
<!--设置文件名的编码方式-->
<property name="defaultEncoding" value="utf-8"/>
</bean>
</beans>
1.1.3 配置前端控制器
<?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_4_0.xsd"
version="4.0">
<!--配置前端控制器-->
<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:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
1.2实现单文件上传
1.2.1 修改项目的访问路径
1.2.2 创建文件上传页面
singleFile.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/file/singleFile" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username"/><br/>
文件上传:<input type="file" name="file"/><br/>
<input type="submit" value="OKOK"/>
</form>
</body>
</html>
1.2.3 创建成功页面
ok.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
OK......
</body>
</html>
1.2.4 创建页面跳转控制器
package com.bjsxt.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
/**
* 页面跳转控制器
*/
@Controller
@RequestMapping("/page")
public class PageController {
/**
* 跳转单文件上传页面
*/
@RequestMapping("/single")
public String showSingleFile(){
return "singlefile";
}
/**
* 跳转成功页面
*/
@RequestMapping("/ok")
public String showOK(){
return "ok";
}
}
1.3实现文件上传
1.3.1 创建文件上传控制器
package com.bjsxt.web.controller;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.UUID;
/**
* 处理文件上传控制器
*/
@Controller
@RequestMapping("/file")
public class FileUploadController {
/**
* 处理单个文件上传
* 在文件上传时,MultipartFile参数的名称需要与页面的file组件的name相同。
* 如果不同需要使用@RequestParam注解来指定。
*/
@RequestMapping("/singleFile")
public String singleFile(MultipartFile file, String username, HttpServletRequest request){
String fileName = UUID.randomUUID().toString()+file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
String realPath = request.getServletContext().getRealPath("/fileupload");
File temp = new File(realPath,fileName);
try{
file.transferTo(temp);
}catch(Exception e){
e.printStackTrace();
}
return "redirect:/page/ok";
}
}
1.4实现多文件上传
1.4.1 创建多文件上传页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/file/multiFile" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username"/><br/>
文件上传1:<input type="file" name="file"/><br/>
文件上传2:<input type="file" name="file"/><br/>
<input type="submit" value="OKOK"/>
</form>
</body>
</html>
1.4.2 创建页面跳转方法
/**
* 跳转多文件上传页面
*/
@RequestMapping("/multifile")
public String showMultiFile(){
return "multifile";
}
1.5实现多文件上传
1.5.1 创建文件上传控制器
/**
* 处理多文件上传
*/
@RequestMapping("/multiFile")
public String multiFile(MultipartFile file[],String username,HttpServletRequest request){
for(MultipartFile temp:file){
String fileName = UUID.randomUUID().toString()+temp.getOriginalFilename().substring(temp.getOriginalFilename().lastIndexOf("."));
File f = new File(request.getServletContext().getRealPath("/fileupload"),fileName);
try{
temp.transferTo(f);
}catch(Exception e){
e.printStackTrace();
}
}
return "redirect:/page/ok";
}
2 文件下载
2.1显示下载文件
2.1.1 添加 JSTL 标签库 jar 包
jstl.jar
standard.jar
2.1.2 创建下载页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<c:forEach items="${files}" var="file">
<a href="/file/fileDown?fileName=${file}">${
file}</a><br/>
</c:forEach>
</body>
</html>
2.1.3 创建跳转下载页面方法
/**
* 跳转文件下载页面
*/
@RequestMapping("/showFileDown")
public String showFileDown(HttpServletRequest request,Model model){
String realPath = request.getServletContext().getRealPath("/fileupload");
File file = new File(realPath);
String[] arr = file.list();
model.addAttribute("files",arr);
return "filedown";
}
2.2下载文件
2.2.1 创建文件下载控制器
/**
* 实现文件下载
*/
@RequestMapping("/fileDown")
public void fileDown(String fileName, HttpServletRequest request, HttpServletResponse response){
//设置响应头
response.setHeader("Content-Disposition","attachment;filename="+fileName);
//获取绝对路径
String realPath = request.getServletContext().getRealPath("/fileupload");
File file = new File(realPath,fileName);
//获取字节输出流
try{
ServletOutputStream outputStream = response.getOutputStream();
//读文件
outputStream.write(FileUtils.readFileToByteArray(file));
outputStream.flush();
outputStream.close();
}catch(Exception e){
e.printStackTrace();
}
}
九、 静态资源映射
当在 DispatcherServlet 的<url-pattern>
中配置拦截“/”
时,除了*.jsp
不会拦截以外,其 他所有的请求都会经过前端控制器进行匹配,此时静态资源,例如 *.css
、*.js
、*.jpg……
就 会被前端控制器拦截,导致不能访问,出现 404
问题。
1 通过 DefaultServlet 处理静态资源
修改 web.xml
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.png</url-pattern>
</servlet-mapping>
2 通过 SpringMVC 的静态资源映射器处理静态资源
在 spring3.0.4 以后的 SpringMVC 模块提供了静态资源映射器组件。通过 mvc:resources
标签配置静态资源映射器
修改 SpringMVC 配置文件
<!--配置静态资源映射器-->
<!-- mapping:配置请求的 URL
location:配置映射路径-->
<mvc:resources mapping="/img/**" location="/img/"/>
<mvc:resources mapping="/js/**" location="/WEB-INF/js/"/>
3 通过<mvc:default-servlet-handler />处理静态资源
在 SpringMVC 的配置文件中配置<mvc:default-servlet-handler />
后,会在 Spring MVC 上 下文中定义一个 org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler
, 它会像一个检查员,对进入 DispatcherServlet
的 URL 进行筛查,如果发现是静态资源的请求,就将该请求转由 Web 应用服务器默认的 Servlet 处理,如果不是静态资源的请求,才由 DispatcherServlet
继续处理。
修改 SpringMVC 配置文件
<mvc:default-servlet-handler/>
十、 SpringMVC 的异常处理
1 搭建环境
1.1创建项目添加 jar 包
1.2创建 SpringMVC 配置文件
<?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">
<!--配置注解扫描-->
<context:component-scan base-package="com.bjsxt.web.controller"/>
<!--配置注解驱动-->
<mvc:annotation-driven/>
<!--配置视图解析器-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
1.3配置前端控制器
<?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_4_0.xsd"
version="4.0">
<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:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2 使用@ExceptionHandler 注解处理异常
error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
出错了。${
msg}
</body>
</html>
error2.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
Error2 ${
msg}
</body>
</html>
showuser.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
GetUser.....
</body>
</html>
@Controller
@RequestMapping("/user")
public class UsersController {
@RequestMapping("/getUsers")
public String getUsers(){
String str = null;
str.length();
// int flag = 1/0;
/* int[] arr = new int[1];
arr[2]=10;*/
return "showuser";
}
@ExceptionHandler({
java.lang.NullPointerException.class,java.lang.ArithmeticException.class})
public String NullPointExceptionHandle(Exception e, Model model){
model.addAttribute("msg",e);
return "error";
}
@ExceptionHandler({
java.lang.Exception.class})
public String ExceptionHandle(Exception e,Model model){
model.addAttribute("msg",e);
return "error2";
}
}
3 使用@ControllerAdvice 和@ExceptionHandler 处理异常
/**
* 全局异常处理器
*/
//@ControllerAdvice
public class GlobalExceptionHandle {
@ExceptionHandler({
java.lang.NullPointerException.class,java.lang.ArithmeticException.class})
public String NullPointExceptionHandle(Exception e, Model model){
model.addAttribute("msg",e);
return "error";
}
@ExceptionHandler({
java.lang.Exception.class})
public String ExceptionHandle(Exception e,Model model){
model.addAttribute("msg",e);
return "error2";
}
}
4 使用 SimpleMappingExceptionResolver 处理异常
@Configuration
public class GlobalExceptionHandle2 {
@Bean
public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver(){
SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
Properties properties = new Properties();
properties.put("java.lang.NullPointerException","error");
properties.put("java.lang.ArithmeticException","error2");
resolver.setExceptionMappings(properties);
return resolver;
}
}
5 自定义 HandlerExceptionResolve 处理器处理异常
@Configuration
public class GlobalExceptionHandle3 implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView modelAndView = new ModelAndView();
if(e instanceof NullPointerException){
modelAndView.setViewName("error");
}
if(e instanceof ArithmeticException){
modelAndView.setViewName("error2");
}
modelAndView.addObject("msg",e);
return modelAndView;
}
}
十一、 SpringMVC 拦截器
1 拦截器简介
1.1什么是拦截器
Spring MVC 的拦截器(Interceptor)与 Servlet 的过滤器(Filter)类似,它主要用于拦 截用户的请求并做相应的处理,通常应用在权限验证、记录请求信息的日志、判断用户是否 登录等功能上。
1.2拦截器执行流程
1.3拦截器和过滤器的区别
- 拦截器 SpringMVC 组件,而过滤器是 Servlet 组件。
- 拦截器不依赖容器,过滤器依赖容器。
- 拦截器只能对控制器请求起作用,而过滤器则可以对所有的请求起作用。
- 拦截器可以获取 IOC 容器中的各个 bean,而过滤器就不太方便。
2 定义拦截器
在 Spring MVC 中定义一个拦截器需要对拦截器进行创建和配置。创建拦截器时需要实 现 HandlerInterceptor
接口。
2.1拦截器方法介绍
在HandlerInterceptor
接口中包含了三个抽象方法,分别表示拦截的时间点。
2.1.1 preHandle 方法
该方法在控制器的处理请求方法前执行,其返回值表示是否中断后续操作,返回 true
表示继续向下执行,返回 false
表示中断后续操作。
2.1.2 postHandle 方法
该方法在控制器的处理请求方法执行之后、视图解析之前执行,可以通过此方法对请求 域中的模型和视图做进一步的修改。
2.1.3 afterCompletion 方法
该方法在控制器的处理请求方法执行完成后执行,即视图渲染结束后执行,可以通过此 方法实现一些资源清理、记录日志信息等工作。
2.2创建拦截器
2.2.1 创建项目
package com.bjsxt.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/user")
public class UsersController {
@RequestMapping("/getUsers")
public String getUsers(Model model){
model.addAttribute("msg","Hello Oldlu");
return "showuser";
}
}
2.2.2 创建拦截器
package com.bjsxt.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("PreHandle: 在处理请求的目标方法执行之前");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle: 目标方法执行后,视图解析器处理视图之前");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion: 为客户端产生响应之前。");
}
}
2.3配置拦截器
需要在 SpringMVC 的配置文件中,通过<mvc:interceptors>
标签配置拦截器。
<!-- 配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!-- mapping:配置拦截器的作用路径-->
<mvc:mapping path="/**"/>
<!--配置不需要拦截的作用路径-->
<mvc:exclude-mapping path="/user/getUsers"/>
<bean class="com.bjsxt.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
3 定义全局拦截器
全局拦截器是指可以拦截所有被控制器所处理 URL。作用等同于/**
3.1创建全局拦截器
package com.bjsxt.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GlobalInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("Global PreHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("Global PostHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("Global AfterCompletion");
}
}
3.2配置全局拦截器
<!-- 配置拦截器-->
<mvc:interceptors>
<!--配置全局拦截器-->
<bean class="com.bjsxt.interceptor.GlobalInterceptor"/>
<mvc:interceptor>
<!-- mapping:配置拦截器的作用路径-->
<mvc:mapping path="/**"/>
<!--配置不需要拦截的作用路径-->
<!--<mvc:exclude-mapping path="/user/getUsers"/>-->
<bean class="com.bjsxt.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
4 多拦截器执行顺序
如果一个 URL 能够被多个拦截器所拦截,全局拦截器最先执行,其他拦截器根据配置 文件中配置的上下顺序来决定执行顺序的。先配置谁, 谁就先执行。
package com.bjsxt.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor2 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor2 PreHandler");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor2 PostHandler");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MyInterceptor2 AfterCompletion");
}
}
<!-- 配置拦截器-->
<mvc:interceptors>
<!--配置全局拦截器-->
<bean class="com.bjsxt.interceptor.GlobalInterceptor"/>
<mvc:interceptor>
<!-- mapping:配置拦截器的作用路径-->
<mvc:mapping path="/**"/>
<!--配置不需要拦截的作用路径-->
<!--<mvc:exclude-mapping path="/user/getUsers"/>-->
<bean class="com.bjsxt.interceptor.MyInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.bjsxt.interceptor.MyInterceptor2"/>
</mvc:interceptor>
</mvc:interceptors>
5 拦截器应用案例
5.1需求
在响应的结果中将 Oldlu 字符串更换为*****
。
5.2创建拦截器
package com.bjsxt.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
public class ContentReplaceInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
Map<String, Object> model = modelAndView.getModel();
String str = (String)model.get("msg");
if(str.contains("Oldlu")) {
String newStr = str.replaceAll("Oldlu", "*****");
model.put("msg", newStr);
}
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
5.3配置拦截器
<?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">
<!-- 配置注解扫描-->
<context:component-scan base-package="com.bjsxt.web.controller"/>
<!--配置注解驱动-->
<mvc:annotation-driven/>
<!--配置视图解析器-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 配置拦截器-->
<mvc:interceptors>
<!--配置全局拦截器-->
<bean class="com.bjsxt.interceptor.GlobalInterceptor"/>
<mvc:interceptor>
<!-- mapping:配置拦截器的作用路径-->
<mvc:mapping path="/**"/>
<!--配置不需要拦截的作用路径-->
<!--<mvc:exclude-mapping path="/user/getUsers"/>-->
<bean class="com.bjsxt.interceptor.MyInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.bjsxt.interceptor.MyInterceptor2"/>
</mvc:interceptor>
<!--对响应内容做字符串替换-->
<mvc:interceptor>
<mvc:mapping path="/user/getUsers"/>
<bean class="com.bjsxt.interceptor.ContentReplaceInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
十二、SpringMVC 对 Restful 风格的支持
1 Restful 简介
REST:Representational State Transfer(表象层状态转变),是一种设计风格。它的主要 作用是充分并正确利用 HTTP 协议的特性,规范资源获取的 URI 路径。通俗的讲,RESTful 风格的设计允许将参数通过 URL 拼接传到服务端,目的是让 URL 看起来更简洁实用。
传统 URL:http://localhost:8888/user/addUsers?username=oldlu&userage=30
Restful 风格:http://localhost:8888/user/addUsers/oldlu/30
restful 的优点:
它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。
2 处理 Restful 风格的请求
2.1占位符{}
用于绑定 uri 中的占位符。例如:浏览器请求 uri 是/delete/10
,在 SpringMVC 处 理请求的方法中,在绑定 uri 时需要用占位符来表示需要获取 uri 中的哪个路径的值。 @RequestMapping("/delete/{id}")
,这个{id}
就是 uri 占位符。uri 支持占位符是 spring3.0 之后加入的。是 springmvc 支持 restful 风格的一个重要标志。
添加一个adduser页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
AddUsers....${
msg}
</body>
</html>
2.2@PathVaribale
通过 @PathVariable 可以将 uri 中占位符参数绑定到控制器处理方法的入参中。
package com.bjsxt.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 完成页面跳转控制器
*/
@Controller
@RequestMapping("/page")
public class PageController {
@RequestMapping("/{page}/{userid}")
public String showPage(@PathVariable("page") String p, @PathVariable int userid, Model model){
model.addAttribute("msg",userid);
return p;
}
}
十三、 JSON 数据处理
在 SpringMVC 中使用的是 Jackson API 实现对 JSON 格式数据处理。需要添加 Jackson 的 jar 包。
jackson-annotations-2.11.0.jar
jackson-core-2.11.0.jar
jackson-databind-2.11.0.jar
1 搭建环境
1.1创建项目添加依赖
1.2添加 Jquery.js
2 处理请求中的 JSON 格式数据
在处理请求中的 JSON 格式数据时需要使用@RequestBody
注解。
创建 SpringMVC 配置文件
<?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">
<!-- 配置注解扫描-->
<context:component-scan base-package="com.bjsxt.web.controller"/>
<!--配置注解驱动-->
<mvc:annotation-driven/>
<!--配置视图解析器-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 配置静态资源映射器-->
<mvc:resources mapping="/js/**" location="/WEB-INF/js/"/>
</beans>
配置前端控制器
<?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_4_0.xsd"
version="4.0">
<!--配置前端控制器-->
<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:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2.1@RequestBody
@RequestBody
注解可以将 JSON 格式的数据转为 Java 对象。但是要求 content-type
不是 默认的 application/x-www-form-urlcoded
编码的内容。一般情况下来说常用其来处理 application/json
类型。
2.2创建 Users
package com.bjsxt.pojo;
public class Users {
private String username;
private int userage;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getUserage() {
return userage;
}
public void setUserage(int userage) {
this.userage = userage;
}
@Override
public String toString() {
return "Users{" +
"username='" + username + '\'' +
", userage=" + userage +
'}';
}
}
2.3创建页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="/js/jquery.js"></script>
<script>
$(function(){
$("#but").click(function(){
var name = $("#username").val();
var age = $("#userage").val();
var obj = {
username:name,
userage:age
};
var user = JSON.stringify(obj);
$.ajax({
url:"/user/addUsers",
contentType:"application/json",
type:"post",
data:user,
success:function(res){
alert(res);
//$("#username").val(res.username);
//$("#userage").val(res.userage);
}
});
});
});
</script>
</head>
<body>
用户姓名:<input type="text" id="username"/><br/>
用户年龄:<input type="text" id="userage"/><br/>
<input type="button" value="OK" id="but"/>
</body>
</html>
2.4创建页面跳转控制器
package com.bjsxt.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/page")
public class PageController {
@RequestMapping("/{page}")
public String showPage(@PathVariable String page){
return page;
}
}
2.5创建处理 JSON 的控制器
@Controller
@RequestMapping("/user")
public class UsersController {
@RequestMapping("/addUsers")
public void addUsers(@RequestBody Users users, HttpServletResponse response)throws Exception{
System.out.println(users);
PrintWriter writer = response.getWriter();
writer.print("ok");
writer.flush();
writer.close();
}
}
3 处理响应中的 JSON 格式数据
将响应结果转换成 JSON 格式数据时,需要使用@ResponseBody 注解。
3.1@ResponseBody
@ResponseBody
注解的作用是将处理请求方法返回的对象通过转换器转换为 JSON
格式 数据,同时写入到 response
对象的 body
区,通常用来返回JSON
数据。需要注意,在使用此注解之后不会再走视图解析器,而是直接将数据写入到输出流中,他的效果等同于通过response
对象输出指定格式的数据。 如果处理请求方法返回的是 String
时,@ResponseBody
注解不会进行 JSON
转换。响应 的 Content-Type
为 text/plain;charset=ISO-8859-1
。 如果处理请求方法返回的是除了String
类型以外的其他 Object
类型时,@ResponseBody
注解会进行JSON
转换。响应的 Content-Type
为 application/json
。
3.2修改控制器
@Controller
@RequestMapping("/user")
public class UsersController {
@RequestMapping(value = "/addUsers",produces = MediaType.APPLICATION_JSON_VALUE+";charset=utf-8")
@ResponseBody
public Object addUsers(@RequestBody Users users)throws Exception{
System.out.println(users);
return users;
}
}
3.3解决响应的 JSON 数据中文乱码问题
@RequestMapping(value = "/addUsers",produces = MediaType.APPLICATION_JSON_VALUE+";charset=utf-8")
十四、 SpringMVC 解决请求跨域问题
1 什么是同源策略
同源策略是浏览器的一个安全功能,所谓的同源,指的是协议,域名,端口相同。浏览 器处于安全方面的考虑,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。
哪些不受同源策略限制:
- 页面中的链接,重定向以及表单提交是不会受到同源策略限制的。
- 跨域资源的引入是可以的。如嵌入到页面中的
<script src="..."></script>
,<img src="...">
,<link href="...">
,<iframe src="...">
等。
2 什么是跨域请求
在 JavaScript 的请求中当一个请求 URL 的协议、域名、端口三者之间任意一个与当前页 面 URL 不同时即为跨域。浏览器执行 JavaScript 脚本时,会检查当前请求是否同源,如果不 是同源中的资源,就不会被执行。
跨域异常:
3 通过@CrossOrigin 解决跨域
@CrossOrigin
注解用于处理跨域请求访问。是 SpringMVC4.2 版本中推出的注解。
origins
: 允许可访问的域列表
maxAge
:准备响应前的缓存持续的最大时间(以秒为单位)。
@Controller
@RequestMapping("/user")
public class UsersController {
@RequestMapping(value = "/addUsers",produces = MediaType.APPLICATION_JSON_VALUE+";charset=utf-8")
@ResponseBody
@CrossOrigin(origins ="http://localhost:8888")
public Object addUsers(@RequestBody Users users)throws Exception{
System.out.println(users);
return users;
}
}
十五、 SpringMVC 常用注解
1 @Controller
@Controller
用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller
对象。
2 @RequestMapping
@RequestMapping
是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上, 表示类中的所有处理请求的方法都是以该地址作为父路径。
value
:指定请求的实际地址; method:指定请求的
method
类型, GET、POST、PUT、DELETE 等;
produces
: 指定返回的内容类型;
3 @GetMapping
@GetMapping
是用来指定处理 Get 请求类型的注解。表示该方法只能处理 Get 类型的 请求。
value
:指定请求的实际地址;
4 @PostMapping
@PostMapping
是用来指定处理 Post 请求类型的注解。表示该方法只能处理 Post 类型请 求。
value
:指定请求的实际地址;
5 @PathVariable
@PathVariable
用于将请求 URL 中的模板变量映射到功能处理方法的参数上,即取出 uri 模板中的变量作为参数。
name
:指定 uri 模板中的标识名称;
6 @RequestParam
@RequestParam
用于在控制器方法中获取请求参数;
defaultValue
: 表示设置默认值;
required
:设置是否是必须要传入的参数,类型为
boolean
; name:指定请求参数名称;
7 @RequestBody
@RequestBody
将请求中的 JSON 格式数据转换为 Java 对象;
8 @ResponseBody
@ResponseBody
将响应的对象转换为 JSON 格式数据;
9 @RequestHeader
@RequestHeader
将请求头的数据,映射到处理请求的方法参数上。
name
:指定请求头 name;
10 @CookieValue
@CookieValue
注解主要是将请求的 Cookie 数据,映射到处理请求的方法参数上。
name
:指定 CookieName;
11 @CrossOrigin
@CrossOrigin
注解用于处理跨域请求访问。
十六、 SSM 框架整合
1 SSM 框架整合介绍
1.1整合步骤
- 创建项目,添加 jar 包
- 创建包,创建实体与 Mapper
- 添加连接数据库的 properties 文件
- 添加 Log4j 配置文件
- 添加 Spring 配置文件
- 添加 SpringMVC 配置文件
- 修改 web.xml 文件
1.2 jar 包依赖
ssm 整合 jar 包依赖共计 27 个 jar 包。
1.2.1 Mybatis(12 个)
asm-7.1.jar
cglib-3.3.0.jar
commons-logging-1.2.jar
javassist-3.27.0-GA.jar
log4j-1.2.17.jar
log4j-api-2.13.3.jar
log4j-core-2.13.3.jar
ognl-3.2.14.jar
slf4j-api-1.7.30.jar
slf4j-log4j12-1.7.30.jar
mybatis-3.5.5.jar
mybatis-spring-2.0.4.jar
1.2.2 Aspectjweaver(1 个)
aspectjweaver-1.9.5.jar
1.2.3 Spring(8 个)
spring-beans-5.2.7.RELEASE.jar
spring-context-5.2.7.RELEASE.jar
spring-core-5.2.7.RELEASE.jar
spring-expression-5.2.7.RELEASE.jar
spring-jdbc-5.2.7.RELEASE.jar
spring-tx-5.2.7.RELEASE.jar
spring-aop-5.2.7.RELEASE.jar
spring-aspects-5.2.7.RELEASE.jar
1.2.4 SpringMVC(2 个)
spring-web-5.2.7.RELEASE.jar
spring-webmvc-5.2.7.RELEASE.jar
1.2.5 Servlet(1 个)
servlet-api.jar
1.2.6 JSTL(2 个)
jstl.jar
standard.jar
1.2.7 Mysql(1 个)
mysql-connector-java-5.1.48.jar
2 搭建整合环境
2.1创建表
CREATE TABLE `users` (
`userid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) NOT NULL,
`userpwd` varchar(30) NOT NULL, PRIMARY KEY (`userid`),
UNIQUE KEY `username_uk` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2.2搭建环境
2.2.1 创建项目并添加 jar 包
2.2.2 创建包,创建实体类与 Mapper
3 配置 SSM 整合
3.1添加数据库与 log4j 配置文件
3.1.1 添加连接数据的 properties 文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.username=root
jdbc.password=root
3.1.2 添加 log4j 配置文件
log4j.rootLogger=info,console
### appender.console输出到控制台 ###
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=<%d> %5p (%F:%L) [%t] (%c) - %m%n
log4j.appender.console.Target=System.out
### appender.logfile输出到日志文件 ###
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=SysLog.log
log4j.appender.logfile.MaxFileSize=500KB
log4j.appender.logfile.MaxBackupIndex=7
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=<%d> %p (%F:%L) [%t] %c - %m%n
3.2添加 Spring 配置文件
在 SSM 框架整合时为了能够清晰的对 Spring 配置项进行管理,我们可以采用“分而治 之”的方式来定义 Spring 配置文件。将 Spring 配置文件分解成三个配置文件,在不同的配 置文件中配置不同的内容。
applicationContext-dao.xml
该配置文件的作用是用来配置与 Mybatis 框架整合。
applicationContext-trans.xml
该配置文件的作用是用来配置 Spring 声明式事务管理。
applicationContext-service.xml
该配置文件的作用是用来配置注解扫描以及其他的 Spring 配置。
3.2.1 配置整合 Mybatis
applicationContext-dao.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"
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">
<!--配置解析Properties文件的工具类-->
<context:property-placeholder location="classpath:db.properties"/>
<!--配置数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--配置SqlSessionFactory-->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="com.bjsxt.pojo"/>
</bean>
<!--配置MapperScannerConfigurer-->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.bjsxt.mapper"/>
</bean>
</beans>
3.2.2 配置声明式事务管理
applicationContext-trans.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--配置事务管理器的切面-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置事务属性-->
<tx:advice id="myAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="modify*" propagation="REQUIRED"/>
<tx:method name="drop*" propagation="REQUIRED"/>
<tx:method name="userLogin" propagation="REQUIRED"/>
<tx:method name="find*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!--配置切点-->
<aop:config>
<aop:pointcut id="myPointcut" expression="execution(* com.bjsxt.service.*.*(..))"/>
<aop:advisor advice-ref="myAdvice" pointcut-ref="myPointcut"/>
</aop:config>
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
3.2.3 配置注解扫描
applicationContext-service.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"
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">
<!-- 配置注解扫描-->
<context:component-scan base-package="com.bjsxt.service,com.bjsxt.aop"/>
</beans>
3.3配置 SpringMVC
springmvc.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">
<!--配置注解扫描-->
<context:component-scan base-package="com.bjsxt.web.controller"/>
<!-- 配置注解驱动-->
<mvc:annotation-driven/>
<!-- 配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--配置静态资源映射器-->
<mvc:resources mapping="/js/**" location="/WEB-INF/js/"/>
<mvc:resources mapping="/img/**" location="/WEB-INF/img/"/>
<mvc:resources mapping="/css/**" location="/WEB-INF/css/"/>
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/page/login"/>
<mvc:exclude-mapping path="/user/userLogin"/>
<mvc:exclude-mapping path="/page/error"/>
<bean class="com.bjsxt.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
3.4Spring 与 SpringMVC 父子容器问题
在 Spring 与 Springmvc 同时使用时,Spring 的 ContextLoaderListener
会创建的 SpringIOC 容器,SpringMVC 的DispatcherServlet
会创建 SpringMVC 的 IOC 容器。SpringMVC 会将 SpringIOC 容器设置为父容器。
父容器对子容器是可见的,所以在子容器中可以访问父容器的 Bean 对象,而子容器对 父容器不可见的,所以在父容器中无法获取子容器的 Bean 对象。
注解扫描时需要注意:
如果在 SpringMVC 的配置文件中扫描所有注解,会出现声明式事务失效。因为 Spring 声明式事务管理的切面位于 Spring 的 IOC 容器,而子容器对父容器不可见,所以事务管理器 的切面无法对 SpringIOC 容器中的 Bean 对象实现事务控制。
如果在 Spring 的配置文件中扫描所有注解,会出现无法找到控制器而报 404
的异常。 因为HandleMapping
在根据 URI 查找控制器时,只会去 SpringMVC 的 IOC 容器中查找控制器, 而在 SpringMVC 的 IOC 容器并没有控制器对象,所以会出现404
的异常。
正确使用方式
:
在 SpringMVC 的配置文件中扫描@Controller 注解,在 Spring 的配置文件中扫描除了 @Controller 以外的其他注解。在 SpringMVC 的控制器可以注入 SpringIOC 容器中的 Bean 对 象,因为父容器对子容器是可见的。
3.5配置 web.xml
<?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_4_0.xsd"
version="4.0">
<!--指定Spring配置文件的位置以及名称-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-*.xml</param-value>
</context-param>
<!--配置启动Spring框架的监听器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--配置SpringMVC的前端控制器-->
<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:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</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>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
4 实现用户登录业务
需求:实现用户登录业务,同时记录用户的登录日志。登录日志要求记录用户名、登录 时间以及登录的 IP 地址。
4.1实现用户登录
4.1.1 创建业务层
package com.bjsxt.service;
import com.bjsxt.pojo.Users;
public interface UsersService {
Users userLogin(Users users);
}
package com.bjsxt.service.impl;
import com.bjsxt.exception.UserNotFoundException;
import com.bjsxt.mapper.UsersMapper;
import com.bjsxt.pojo.Users;
import com.bjsxt.pojo.UsersExample;
import com.bjsxt.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 用户登录业务层
*/
@Service
public class UsersServiceImpl implements UsersService {
@Autowired
private UsersMapper usersMapper;
/**
* 用户登录
* @param users
* @return
*/
@Override
public Users userLogin(Users users) {
UsersExample usersExample = new UsersExample();
UsersExample.Criteria criteria = usersExample.createCriteria();
criteria.andUsernameEqualTo(users.getUsername());
criteria.andUserpwdEqualTo(users.getUserpwd());
List<Users> list = this.usersMapper.selectByExample(usersExample);
if(list == null || list.size() <= 0){
throw new UserNotFoundException("用户名或密码有误!");
}
return list.get(0);
}
}
4.1.2 创建自定义异常
package com.bjsxt.exception;
/**
* 自定义异常,表示用户登录状态
*/
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(){
}
public UserNotFoundException(String msg){
super(msg);
}
public UserNotFoundException(String msg,Throwable throwable){
super(msg,throwable);
}
}
4.1.3 创建用户登录控制器
package com.bjsxt.web.controller;
import com.bjsxt.pojo.Users;
import com.bjsxt.pojo.UsersExt;
import com.bjsxt.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* 用户管理控制器
*/
@Controller
@RequestMapping("/user")
public class UsersController {
@Autowired
private UsersService usersService;
/**
* 处理用户登录请求
*/
@RequestMapping("/userLogin")
public String userLogin(Users users, HttpSession session){
Users user = this.usersService.userLogin(users);
session.setAttribute("user",user);
return "redirect:/page/index";
}
}
4.1.4 全局异常处理器
package com.bjsxt.web.controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
/**
* 全局异常处理器
*/
@ControllerAdvice
public class GlobalExceptionController {
@ExceptionHandler({
com.bjsxt.exception.UserNotFoundException.class})
public String userNotFoundExceptionHandler(Exception e, Model model){
model.addAttribute("msg",e.getMessage());
return "login";
}
@ExceptionHandler({
java.lang.Exception.class})
public String exceptionHandler(Exception e){
return "redirect:/page/error";
}
}
4.1.5 创建用户登录页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${
msg}
<form action="/user/userLogin" method="post">
登录名:<input type="text" name="username"/><br/>
密码:<input type="password" name="userpwd"/><br/>
<input type="submit" value="OK"/>
</form>
</body>
</html>
4.1.6 创建异常提示页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
出错了!请求与管理员联系:oldlu@bjsxt.com
</body>
</html>
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
欢迎访问index。。。。
</body>
</html>
4.1.7 创建页面跳转控制器
package com.bjsxt.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 页面跳转控制器
*/
@Controller
public class PageController {
/**
* 请求首页
*/
@RequestMapping("/")
public String showIndex(){
return "index";
}
/**
* 处理页面跳转请求
*/
@RequestMapping("/page/{page}")
public String showPage(@PathVariable String page){
return page;
}
}
4.1.8 创建判断用户是否登录的拦截器
package com.bjsxt.interceptor;
import com.bjsxt.pojo.Users;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 判断用户是否登录
*/
public class LoginInterceptor implements HandlerInterceptor {
/**
* 判断用户是否登录
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
Users user = (Users) session.getAttribute("user");
if(user == null || user.getUsername().length() <= 0){
response.sendRedirect("/page/login");
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
4.1.9 配置拦截器
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/page/login"/>
<mvc:exclude-mapping path="/user/userLogin"/>
<mvc:exclude-mapping path="/page/error"/>
<bean class="com.bjsxt.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
4.2记录用户登录日志
4.2.1 创建表
CREATE TABLE `logs` (
`logid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) DEFAULT NULL,
`ip` varchar(30) DEFAULT NULL,
`logtime` date DEFAULT NULL,
PRIMARY KEY (`logid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
4.2.2 创建实体类与 Mapper
4.2.3 创建日志记录切面
package com.bjsxt.aop;
import com.bjsxt.mapper.LogsMapper;
import com.bjsxt.pojo.Logs;
import com.bjsxt.pojo.Users;
import com.bjsxt.pojo.UsersExt;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 用户登录日志记录切面
*/
@Aspect
@Component
public class UsersLoginLogAOP {
@Autowired
private LogsMapper logsMapper;
/**
* 配置切点
*/
@Pointcut("execution(* com.bjsxt.service.UsersService.userLogin(..))")
public void myPointcut(){
}
/**
* 在后置通知中记录登录日志
*/
@AfterReturning("myPointcut()")
public void userLoginLog(JoinPoint joinPoint){
Object[] objects = joinPoint.getArgs();
UsersExt users = (UsersExt)objects[0];
Logs logs = new Logs();
logs.setLogtime(new Date());
logs.setUsername(users.getUsername());
logs.setIp(users.getIp());
this.logsMapper.insertSelective(logs);
}
}
4.2.4 创建 Users 扩展实体类
package com.bjsxt.pojo;
public class UsersExt extends Users {
private String ip;
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
}
4.2.5 修改控制器
/**
* 用户管理控制器
*/
@Controller
@RequestMapping("/user")
public class UsersController {
@Autowired
private UsersService usersService;
/**
* 处理用户登录请求
*/
@RequestMapping("/userLogin")
public String userLogin(UsersExt users, HttpSession session, HttpServletRequest request){
String ip= request.getRemoteAddr();
users.setIp(ip);
Users user = this.usersService.userLogin(users);
session.setAttribute("user",user);
return "redirect:/page/index";
}
}
4.2.6 配置切面
applicationContext-service.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"
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">
<!-- 配置注解扫描-->
<context:component-scan base-package="com.bjsxt.service,com.bjsxt.aop"/>
</beans>
applicationCotnext-trans.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--配置事务管理器的切面-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置事务属性-->
<tx:advice id="myAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="modify*" propagation="REQUIRED"/>
<tx:method name="drop*" propagation="REQUIRED"/>
<tx:method name="userLogin" propagation="REQUIRED"/>
<tx:method name="find*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!--配置切点-->
<aop:config>
<aop:pointcut id="myPointcut" expression="execution(* com.bjsxt.service.*.*(..))"/>
<aop:advisor advice-ref="myAdvice" pointcut-ref="myPointcut"/>
</aop:config>
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
十七、 通过 Maven 搭建 SSM 整合
1 创建 Maven 项目
2 添加 jar 包
在 Maven 中通过坐标管理构件(jar 包或插件)的。需要去 Maven 的中央仓库查找依赖构 件的坐标,并将该坐标添加到 Maven 的 POM 文件中。构件下载完毕以后会放到本地仓库中。 本地仓库默认路径为 C:\Users\用户名\.m2\repository
目录中。在 Idea 中可配置本地仓库路 径。
Maven 查找构件的顺序:先从本地仓库中查找,如果本地仓库没有则会去中央仓库下载 并保存到本地仓库中。
中央仓库地址:https://mvnrepository.com/
2.1配置镜像地址
中央仓库为国外站点,下载构件较慢,可配置国内的阿里镜像或其他镜像地址。
配置镜像地址时需要 Maven 的 settings.xml 配置文件。该配置文件需要从 Apache 下载的 Maven 中获取。最后需要在 Idea 中指定该配置文件。
<mirror>
<!-- 指定镜像 ID -->
<id>nexus-aliyun</id>
<!-- 匹配中央仓库。--> <mirrorOf>central</mirrorOf>
<!-- 指定镜像名称 -->
<name>Nexus aliyun</name>
<!-- 指定镜像路径 -->
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
2.2配置依赖 jar 包的坐标
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjsxt</groupId>
<artifactId>mavenssmdemo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<!--添加jar包依赖-->
<dependencies>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
</dependencies>
</project>
3 配置 Tomcat 插件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjsxt</groupId>
<artifactId>mavenssmdemo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<!--添加jar包依赖-->
<dependencies>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<!-- 配置Tomcat监听端口 -->
<port>8080</port>
<!-- 配置项目的访问路径(Application Context) -->
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
4 配置资源拷贝路径
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
5 创建包、实体类、接口与映射配置文件
6 配置框架整合
7 实现用户查询
7.1创建业务层
package com.bjsxt.service;
import com.bjsxt.pojo.Users;
import java.util.List;
public interface UsersService {
List<Users> findUsersAll();
}
package com.bjsxt.service.impl;
import com.bjsxt.mapper.UsersMapper;
import com.bjsxt.pojo.Users;
import com.bjsxt.pojo.UsersExample;
import com.bjsxt.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 用户管理业务层
*/
@Service
public class UsersServiceImpl implements UsersService {
@Autowired
private UsersMapper usersMapper;
/**
* 查询所用用户
* @return
*/
@Override
public List<Users> findUsersAll() {
UsersExample example = new UsersExample();
return this.usersMapper.selectByExample(example);
}
}
7.2创建控制器
package com.bjsxt.web.controller;
import com.bjsxt.pojo.Users;
import com.bjsxt.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
/**
* 处理用户操作控制器
*/
@Controller
@RequestMapping("/user")
public class UsersController {
@Autowired
private UsersService usersService;
/**
* 处理查询用户请求
*/
@RequestMapping("/findUsersAll")
public String findUsersAll(Model model){
List<Users> list = this.usersService.findUsersAll();
model.addAttribute("list",list);
return "showusers";
}
}
7.3创建页面
showuser.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<table border="1" align="center">
<tr>
<th>用户ID</th>
<th>用户姓名</th>
<th>用户密码</th>
</tr>
<c:forEach items="${list}" var="user">
<tr>
<td>${
user.userid}</td>
<td>${
user.username}</td>
<td>${
user.userpwd}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
下一篇:【LomBok】