SpringMVC 使用
SpringMVC
Spring:IOC 和 AOP
SpringMVC :执行流程
MVC:模型(dao,service)视图(jsp)控制器(servlet)
dao:连接数据库
service:实现业务
servlet:请求转发(地址不变),重定向(变)
jsp(本质是 servlet):视图
前端:数据传输 实体类
实体类有:用户名,密码,生日,爱好。。。
前端只需要:用户名和密码,name 我们就创建新的实体类比如 UserVo:只包含用户名和密码
职责分析
Model 模型
- 业务逻辑
- 保存数据状态
View 视图
- 显示页面
Controller
- 取得表单数据
- 调用业务逻辑
- 转向指定的页面
mvc 要做的事
- 将 url 映射到 java 类或 java 类方法
- 封装用户提交数据
- 处理请求——调用相关业务处理——封装响应数据
- 将响应的数据进行渲染,jsp/html 等表示层数据
SpringMVC 特点:
- 轻量级,简单易学
- 高效,基于请求响应的 mvc 框架
- 与 Spring 兼容性好,无缝结合
- 约定优于配置
- 功能强大:Restful 风格、数据验证、格式化、本地化、主题等
- 简洁灵活
实现原理(面试)
- DispatcherServlet表示前置控制器,整个 SpringMVC 的控制中心,用户发送的请求,DispatcherServlet接收请求并拦截请求
- 我们假设请求的 url 为:http://localhost:8080/SpringMvc/hello
- url可拆分为 3 部分
- http://localhost:8080服务器域名
- SpringMvc 部署服务器上的站点名
- hello 表示控制器
- 通过分析,url 表示为:请求位于服务器 localhost:8080上的 SpringMvc 站点的 hello 控制器
- HandlerMapping 为处理器映射,DispatcherServle调用HandlerMapping,HandlerMapping 根据请求 url Handler(处理器)
- HandlerExecution 表示具体的 Handler。主要作用是根据 url 查找控制器,如上 url 被查找控制器就是 hello
- HandlerExecution 将解析后的信息传递给DispatcherServlet
- HandlerAdapter 表示处理器适配器,其按照特定的规则去执行 Handler(适配的 controller具体类)
- Handler 让具体的 Controller 执行
- Controller 将具体执行的信息返回给 HandlerAdapter,如图携带的 ModelAndView
- HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet
- DispatcherServlet调用视图解析器(viewResolve)来解析HandlerAdapter传递的逻辑视图名
- 视图解析器将解析厄逻辑视图名传给DispatcherServlet
- DispatcherServlet根据视图解析器的视图结果,调用具体视图
- 最终把内容呈现给用户
以上流程可大致分为三步:第一步根据请求通过映射器找到处理器,第二步根据处理器找到适配器从而找到该请求的controller类,通过 controller 去执行并返回相应的结果,第三步通过视图解析器解析并将结果展示给用户
代码实现
- 跳转页面.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
- web.xml 配置DispatcherServlet
<?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">
<!-- 配置 dispatchServlet 这是 SpringMvc 的核心:请求分发器/前端控制器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- DispatcherServlet要绑定 spring 配置 wenj-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-servlet.xml</param-value>
</init-param>
<!-- 启动级别为 1,服务器启动就启动-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--
在 SpringMvc 中
/:只会去匹配所有的请求,不包含 jsp
/*:会去匹配所有的请求,包含 jsp
-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
- spring-servlet 配置HandlerMapping,HandlerAdapter以及具体请求的 handler
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 处理器映射器-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!-- 处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- 视图解析器
1.获得数据
2.解析视图名字
3.拼接视图名字,找到对应视图
4.将数据渲染到视图上
-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 配置 Handler-->
<bean id="/hello" class="com.study.controller.HelloController"/>
</beans>
- controller 类
public class HelloController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mv = new ModelAndView();
//业务代码
String str ="hello SpringMvc";
mv.addObject("msg",str);
//视图跳转
mv.setViewName("hello");
return mv;
}
}
- 测试(这里有个大坑)
通过注解使用 SpringMvc
- 配置 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">
<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-servlet.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>
- spring-servlet.xml 配置文件注册注解和注解扫描
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- 注解扫描-->
<context:component-scan base-package="com.study.controller"/>
<!-- 放行静态资源 js,html,css,mp3,mp4...-->
<mvc:default-servlet-handler/>
<!-- mvc 注解
在 spring 中一般采用@RequestMapping 注解完成映射关系,要想使用@RequestMapping 注解生效
必须向上下文中注册 DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter实例
这两个实例分别在类级别和方法级别处理,而 annotation-driver 配置帮助我们自动完成注入
-->
<mvc:annotation-driven/>
<!-- 视图解析器
1.获得数据
2.解析视图名字
3.拼接视图名字,找到对应视图
4.将数据渲染到视图上
-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
- controller
@Controller
@RequestMapping("/h")
public class HelloController {
//访问路径就是 http:localhost:8080/h/hello
@RequestMapping("/hello")
public String show(Model model) {
//封装数据
model.addAttribute("msg", "HelloSpringMvc");
return "hello";
}
}
Controller使用
- 通过实现 Controller,一个控制器只能写一个方法,如果要多个方法则需要定义多个 controller,比较麻烦不建议使用
//只要实现接口,说明这就是一个控制器
public class ControllerTest1 implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("msg","t1");
modelAndView.setViewName("test");
return modelAndView;
}
}
<?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-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean id="/t" class="com.study.controller.ControllerTest1"/>
</beans>
- 使用注解方式@Controller 推荐使用,有这个注解的类会被 spring 接管。所有的方法如果返回值都是 String,这样就会走视图解析器
@Component 组件
@Service service
@Controller controller
@Retository dao
RequestMapping
RequestMapping注解用于映射 url 到控制器类或特定的处理程序方法,可以用于类或方法上,用于类上,表示类中所有响应请求的方法都是以该地址作为父路径。也就是类上的路径必须在请求上加入再加入方法路径
@Controller
//访问路径: http://localhost:8080/test/hello
@RequestMapping("/test")
public class Controller3 {
@RequestMapping("/hello")
public String test(Model model){
model.addAttribute("msg","hello");
return "hello";
}
}
RestFul 风格
需要使用@PathVariable来进行映射,使用这种风格可以更安全,简介,高效
@Controller
public class RestfulTest {
//原始请求方式:http://localhost:8080/add?a=1&b=2
//restful 请求方式:http://localhost:8080/add/1/3
@RequestMapping("/add/{a}/{b}")
@GetMapping("/add/{a}/{b}")//只能用 get 方式提交
@PostMapping("/add/{a}/{b}")//只能用 post 方式提交
public String test(@PathVariable int a, @PathVariable int b, Model model){
model.addAttribute("msg", a+b);
return "hello";
}
}
ModelAndView
设置 ModelAndView 对象,根据视图解析器和 view 的名称,跳转到制定页面
页面:视图解析器前缀+viewName+视图解析器后缀
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
//不需要走视图解析器
@Controller
public class ModelTest1 {
@RequestMapping("/m1/t1")
public String test(HttpServletRequest request, HttpServletResponse response, Model model){
//没有视图解析器
//请求转发
return "/index.jsp";
//重定向(改变地址)
return "redirect:/index.jsp";
}
}
// 有视图解析器
@Controller
public class ModelTest2 {
@RequestMapping("/m2/t2")
public String test1(){
//转发
return "test";
}
@RequestMapping("/res/m2")
public String test2(){
//重定向,不走视图解析器
return "redirect:/index.jsp";
}
}
接收请求参数及数据回显
@Controller
@RequestMapping("/user")
public class UserController {
//http://localhost:8080/user/t1?name1=lisi
//参数名和属性名一致的请求,不一致需要需要加@RequestParam
@GetMapping("/t1")
public String test1(@RequestParam("name1") String name, Model model){
//接收前端参数
System.out.println("接收到前端参数:"+name);
//将返回的结果传递给前端
model.addAttribute("msg", name);
return "hello";
}
//前端接收对象: id name age
/**
* 接收对象,需要接收的属性名和接收名一致;若不一致则返回 null
*/
@GetMapping("/t2")
public String test2(User user,Model model){
model.addAttribute("msg", user);
return "hello";
}
@GetMapping("/t3")
public String test3(ModelMap modelMap){
return "hello";
}
}
数据回显的三种方式及区别
Model 精简版,只有寥寥无几个方法只适用于存储数据,简化新手对于 Model 对象的操作和理解
ModelMap 继承了 LinkedMap,除了实现自身一些方法,通用继承了LinkedMap 的方法和特性
ModelAndView 可以在存储数据的同时,可以进行设置返回的逻辑视图。进行控制展示层的跳转
解决中文乱码问题
修改
web.xml文件 ,配置 springmvc 提供的 filter
<filter>
<filter-name>filter</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>filter</filter-name>
<!-- 包含 .jsp-->
<url-pattern>/*</url-pattern>
</filter-mapping>
这里需要注意的是需要拦截.jsp 则需要使用/*否则无法拦截 jsp
/和/*区别
<!-- 使用/*才会拦截 jsp,/不会拦截 jsp
<url-pattern>/</url-pattern>:
会匹配到/springmvc这样的路径型url,不会匹配到模式为*.jsp这样的后缀型url。
<url-pattern>/*</url-pattern>:
会匹配所有的url:路径型的和后缀型的url(包括/springmvc,.jsp,.js和.html等)
-->
JSON使用
前后端分离时代:
后端部署后端,提供接口,提供数据:
前端独立部署,负责渲染后端的数据:
json 简介
JSON(JavaScript Object Notation) 是一种基于字符串的轻量级的数据交换格式。易于人阅读和编写,同时也易于机器解析和生成。JSON 是 JavaScript 数据类型的子集。
JSON 的语法规则
JSON 是按照特定的语法规则所生成的字符串结构。
- 大括号表示 JSON 的字符串对象。{ }
- 属性和值用冒号分割。{"属性":"value"}
- 属性和属性之间用逗号分割。{"属性":"value","属性":"value",...} 中括号表示数组。[{"属性":"value"...},{"属性":"value"...}]
{"name":"张三","age":3,"sex":"男"}
简单使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript">
//编写 javaScript 对象
var user={
name:"战三",
age:3,
sex:"男"
};
//将 js 对象转换成 jaon 对象
var json=JSON.stringify(user);
console.log(json);
console.log("------------")
//将 json 对象转换为 js 对象
var obj=JSON.parse(json);
console.log(obj)
</script>
</head>
<body>
</body>
</html>
Jackson
Jackson 是一种解析 JSON 格式数据的 API,也是最流行,速度最快的 JSON API。在 SpringMVC 中默认使用 Jackson API 处理 JSON 格式的数据。这里使用 objectMapper 对象,进行 将字符串转换成 jason 字符串
基本使用
依赖导入
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.3</version>
</dependency>
具体实现
对象转换和普通字符串方式一样;对象转换;日期格式转换
package com.study.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.study.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.text.SimpleDateFormat;
import java.util.Date;
@Controller
public class JacksonDemo1 {
/**
* 将对象转换成 jason 格式字符串
*/
@ResponseBody
@RequestMapping("/d0")
public String test0() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
User user = new User(1, "李四", 18);
//若是多个多条 user 直接使用 list 接收即可
return mapper.writeValueAsString(user);
}
/**
* 将日期格式使用基础方法转换成 jason 字符串格式
*/
@ResponseBody //不走视图解析器,直接输出结果
@RequestMapping("/d1")
public String test1() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//转换成特定格式字符串
String format = sdf.format(date);
//转换成 jason 格式字符串
String string = mapper.writeValueAsString(format);
return string;
}
/**
* 使用 ObjectMapper 直接将日期转换成字符串
*
* @return json 字符串
*/
@RequestMapping("/d2")
@ResponseBody //不能忘记加这个注解,否则报错
public String test2() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
//不用时间戳,也就是不使用现在至1970 年的毫秒数
mapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false);
//转换的格式类型
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
mapper.setDateFormat(sdf);
Date date = new Date();
String string = mapper.writeValueAsString(date);
return string;
}
}
上述内容有很多重复的代码,可以进行封装提取工具类
JasonUtils
package com.study.utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.text.SimpleDateFormat;
public class JsonUtils {
public static String getJson(Object object) {
return getJson(object, "yyyy-MM-dd HH:mm:ss");
}
public static String getJson(Object object, String pattern) {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false);
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
mapper.setDateFormat(sdf);
try {
return mapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}
FastJson(阿里巴巴)
导入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.70</version>
</dependency>
具体实现
/**
* 使用 fastJson 来实现
*/
@RequestMapping("/d3")
@ResponseBody
public String test3() {
User user1 = new User(1, "张三 1", 18);
User user2 = new User(2, "张三 2", 18);
User user3 = new User(3, "张三 3", 18);
User user4 = new User(4, "张三 4", 18);
ArrayList<User> list = new ArrayList<>();
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
System.out.println("=======java 对象转 json 字符串====");
String st1 = JSON.toJSONString(list);
String us1 = JSON.toJSONString(user1);
System.out.println(st1);
System.out.println("=======Json 字符串转 java 对象====");
User u = JSON.parseObject(us1, User.class);
System.out.println(u);
System.out.println("=======java 对象转 JSON 对象====");
JSONObject o = (JSONObject) JSON.toJSON(user1);
System.out.println(o);
System.out.println("=======json 对象转 java 对象====");
User us = JSON.toJavaObject(o, User.class);
System.out.println(us);
return "hello";
}
输出结果
处理 json 乱码配置
<!-- json 乱码配置,将原来的标签内进行添加-->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
整合 ssm
依赖
<?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>org.example</groupId>
<artifactId>ssmbuild</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 依赖 junit,数据库驱动,连接池,servlet,jsp,mybatis,mybatis-spring,springmvc,spring-jdbc-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<!-- 连接池这里使用 c3p0-->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<!-- 事务-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
<!-- 偷懒包-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
</dependencies>
<!-- 静态资源导出-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
mybatis 层
配置文件
- 主要用于设置日志,取别名,绑定 mapper
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置数据源,交给 spring 去做-->
<!--添加日志-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!-- 取别名-->
<typeAliases>
<package name="com.study.pojo"/>
</typeAliases>
<!-- 绑定 mapper-->
<mappers>
<mapper class="com.study.mapper.BookMapper"/>
</mappers>
</configuration>
建立数据库
create DATABASE `ssmbuild`;
use `ssmbuild`;
create table `books`(
`bookId` int(10) not null auto_increment comment '书id',
`bookName` varchar(100) not null comment '书名',
`bookCounts` varchar(11) not null comment '数量',
`detail` varchar(200) not null comment '描述',
key `bookId` (`bookId`)
) engine=innodb default charset=utf8
insert into `books`(`bookId`,`bookName`,`bookCounts`,`detail`)values
(1,'java',1,'入门到放弃'),
(2,'mysql',10,' 删库到跑路'),
(3,'Linux',1,'入进门到进牢');
pojo
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Books {
private int bookId;
private String bookName;
private int bookCounts;
private String detail;
}
mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.study.mapper.BookMapper">
<insert id="addBook" parameterType="books">
insert into books(bookName,bookCounts,detail)
values (#{bookName},#{bookCounts},#{detail});
</insert>
<delete id="deleteBookById" parameterType="_int">
delete from books
where bookId=#{bookId}
</delete>
<update id="updateBook" parameterType="books">
update books set bookName=#{bookName},bookCounts=#{bookCounts},detail=#{detail}
where bookId=#{bookId}
</update>
<select id="selectBookById" parameterType="_int" resultType="books">
select * from books
where bookId=#{bookId}
</select>
<select id="selectAll" resultType="books">
select * from books;
</select>
<select id="selectByName" resultType="books">
select * from books where bookName =#{bookName}
</select>
</mapper>
service
/**
* 业务层制作数据的查询工作,页面展示不用管
*/
public class BookServiceImpl implements BookService {
//业务层调 mapper;
private BookMapper bookMapper;
public void setBookMapper(BookMapper bookMapper) {
this.bookMapper = bookMapper;
}
@Override
public int addBook(Books books) {
return bookMapper.addBook(books);
}
@Override
public int deleteBookById(int id) {
return bookMapper.deleteBookById(id);
}
@Override
public int updateBook(Books books) {
return bookMapper.updateBook(books);
}
@Override
public Books selectBookById(int id) {
return bookMapper.selectBookById(id);
}
@Override
public List<Books> selectAll() {
return bookMapper.selectAll();
}
@Override
public Books selectByName(String bookName) {
return bookMapper.selectByName(bookName);
}
}
Spring 层
springMVC 层
配置文件
spring-dao数据库相关 bean
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 关联数据库配置文件-->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 连接池
dbcp:半自动化操作
c3p0:自动化操作(自动化加载配置文件,并且可以自动设置到对象中)
druid,hikari
-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- c3p0 的部分属性-->
<property name="maxPoolSize" value="30"/>
<property name="minPoolSize" value="10"/>
<!-- 关闭连接后不知道 commit-->
<property name="autoCommitOnClose" value="false"/>
<!-- 超市时间-->
<property name="loginTimeout" value="10000"/>
<!-- 连接失败重试次数-->
<property name="acquireRetryAttempts" value="2"/>
</bean>
<!-- sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据源-->
<property name="dataSource" ref="dataSource"/>
<!-- 绑定 mybatis 配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!-- 配置mapper接口扫描包,可以动态实现接口注入到 spring 容器中,通过反射实现这样就无需在通过 sqlSession 获取连接,直接能得到 mapper-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入 sqlSessionFactory-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!-- 扫描包-->
<property name="basePackage" value="com.study.mapper"/>
</bean>
</beans>
- spring-service 业务类相关,配置事务和业务层注入
<?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:c="http://www.springframework.org/schema/c"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 扫描包-->
<context:component-scan base-package="com.study.service"/>
<!--将我们所有业务类注入 spring,可以通过配置,可以通过注解-->
<bean id="bookService" class="com.study.service.BookServiceImpl">
<property name="bookMapper" ref="bookMapper"/>
</bean>
<!-- 声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 结合 aop 实现事务-->
<!-- 配置事务的类-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 给那些方法配置事务
配置事务传播特性-->
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 配置事务切入-->
<aop:config>
<aop:pointcut id="pointCut" expression="execution(* com.study.service.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
</aop:config>
</beans>
- srping-mvc 控制层相关
<?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-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- 注解驱动-->
<mvc:annotation-driven/>
<!-- 静态资源过滤-->
<mvc:default-servlet-handler/>
<!-- 视图解析器-->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 扫描包:controller-->
<context:component-scan base-package="com.study.controller"/>
</beans>
web.xml 主要用于配置 dispatchServlet 和拦截器
<?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">
<!-- DispatcherServlet-->
<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:applicationContext.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>filter</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>filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 默认 session 过期时间 单位分钟-->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
controller
@Controller
@RequestMapping("/book")
public class BookController {
@Autowired
private BookService bookService;
//查询全部书籍并返回页面
@RequestMapping("/allBook")
public String selectAll(Model model) {
List<Books> books = bookService.selectAll();
model.addAttribute("msg", books);
return "allBook";
}
//跳转增加书籍页面
@RequestMapping("/add")
public String addBook() {
return "addBook";
}
//增加书籍
@RequestMapping("/addBook")
public String addSuccess(Books books) {
bookService.addBook(books);
return "redirect:/book/allBook";
}
@RequestMapping("/delete/{id}")
public String delete(@PathVariable int id) {
bookService.deleteBookById(id);
return "redirect:/book/allBook";
}
//修改书籍
@RequestMapping("/update")
public String update(int id, Model model) {
Books books = bookService.selectBookById(id);
model.addAttribute("book", books);
return "updateBook";
}
// 这里需要注意 id 的添加
@RequestMapping("/updateBooks")
public String updateBook(Books books) {
bookService.updateBook(books);
return "redirect:/book/allBook";
}
@RequestMapping("/queryBookName")
public String queryByBookName(String bookName, Model model) {
Books book = bookService.selectByName(bookName);
List<Books> list = new ArrayList<>();
list.add(book);
if (book == null) {
list = bookService.selectAll();
model.addAttribute("error", "未查询到此书");
}
model.addAttribute("msg", list);
return "allBook";
}
}
拦截器
拦截器和 servlet 区别
过滤器
- servlet 规范中的一部分,任何 java web 工程都可以使用
- url-pattern 中配置/*之后,可以对任意访问资源进行拦截
拦截器
- 拦截器是 AOP 思想的应用
- 拦截器是 SpringMvc 框架的,只有使用 SpringMvc 框架才能使用
- 拦截器只会拦截访问的控制器方法,如果访问的是 jsp/html/css/image/js 是不会进行拦截
自定义拦截器只需要使用 HandlerInterceptor
public class MyInterceptor implements HandlerInterceptor {
/**
*
* @param request
* @param response
* @param handler
* @return
* @throws Exception
* return true 执行下一个拦截器,放行;
* return false;不执行下一个拦截器
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("处理前");
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 {
}
}