文章目录
SSM
SSM 整合开发
- SpringMVC + Spring + MyBatis 整合
- SpringMVC:视图层、界面层;负责接收请求,显示处理结果
- Spring:业务层;管理 service、dao、工具类对象
- MyBatis:持久层;访问数据库
- Java EE 开发框架
- 实质就是将 MyBatis 整合入 Spring
- 两种方式
- XML 配置方式
- 基于注解
用户发起请求 → SpringMVC 接收 → Spring 中 service 对象 → MyBatis 处理数据
- 再将获得的结果按顺序返回,显示在页面
SSM 整合
- 容器问题:整合中存在不同容器
- SpringMVC 容器,管理 Controller 控制器对象
- Spring 容器,管理 service、dao、工具类对象
- SpringMVC 容器是 Spring 容器的子容器
- 类似 Java 继承关系,子容器可以访问父容器内容
- 将使用的对象放到合适的容器创建、管理
- Controller 和 Web 开发相关对象放到 SpringMVC 容器
- 声明在 SpringMVC 配置文件
- service、dao 对象放到 Spring 容器
- 声明在 Spring 配置文件
- Controller 和 Web 开发相关对象放到 SpringMVC 容器
实现步骤
- 创建 Maven 项目
- 添加依赖
- springmvc、spring、mybatis 框架依赖
- jackson 依赖、mysql 驱动、druid 连接池、jsp、servlet 依赖
- 编写 web.xml
- 注册 DispatcherServlet
- 用来创建 SpringMVC 容器,创建 Controller 类对象
- 创建 servlet 后才能接收用户请求
- 注册 Spring 的监听器 ContextLoaderListener
- 创建 Spring 容器对象之后才能创建 service、dao 等对象
- 注册字符集过滤器
- 解决 post 请求乱码
- 注册 DispatcherServlet
- 创建包结构
- controller、service、dao、实体类包
- 编写配置文件
- SpringMVC 配置文件
- Spring 配置文件
- MyBatis 配置文件
- 数据库连接属性配置文件
- 业务逻辑实现
- java 业务代码
- 前端 jsp 页面
简单整合
仅实现最简单的注册、登录功能
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
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>ssm</groupId>
<artifactId>ssm_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
<dependencies>
<!-- Spring 依赖 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.16</version>
</dependency>
<!-- spring 事务处理 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.16</version>
</dependency>
<!-- Spring 事务处理 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.16</version>
</dependency>
<!-- mybatis依赖 -->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<!-- mybatis-spring 整合依赖 -->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
<!-- 数据库连接驱动 -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!-- druid 连接池依赖 -->
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<!-- springMVC 依赖 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.16</version>
</dependency>
<!-- Jackson依赖,转换 json 格式数据 -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.1</version>
</dependency>
<!-- Jackson 依赖 -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.1</version>
</dependency>
<!-- servlet 依赖 -->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- jsp 依赖 -->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
conf
applicationContext.xml
- 组件扫描器
- 创建 service 对象
- 数据源配置
- 导入属性配置文件
- 创建 SqlSessionFactory 对象
- 声明 MyBatis 扫描器,创建 dao 对象
- 事务处理
- 文件上传处理
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://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
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 声明组件扫描器,扫描注解创建 service 对象 -->
<context:component-scan base-package="ssm_demo.service"/>
<!-- 导入属性配置文件 -->
<context:property-placeholder location="classpath:conf/jdbc.properties" file-encoding="UTF-8"/>
<!-- 配置连接池数据源 -->
<bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="maxActive" value="20"/>
<property name="initialSize" value="5"/>
</bean>
<!-- 声明 SqlSessionFactoryBean 创建 sqlSessionFactory 对象 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="datasource"/>
<property name="configLocation" value="classpath:conf/mybatis-config.xml"/>
</bean>
<!-- 声明 MyBatis 扫描器,创建 dao 对象 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="ssm_demo.dao"/>
</bean>
<!-- 声明事务管理器 -->
<bean id="manager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"/>
</bean>
<!-- 配置方法事务属性 -->
<tx:advice id="interceptor" transaction-manager="manager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" isolation="DEFAULT" read-only="false" />
<tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT" read-only="false" />
<tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT" read-only="false" />
<tx:method name="query*" propagation="REQUIRED" isolation="DEFAULT" read-only="true" />
<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 关联切入点和事务切面 -->
<aop:config>
<aop:pointcut id="servicePt" expression="execution(* *..service..*.*(..))"/>
<aop:advisor advice-ref="interceptor" pointcut-ref="servicePt"/>
</aop:config>
<!-- 文件上传配置 -->
<bean id="resolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 请求的编码格式,必须和 jsp 的 pageEncoding属性一致,以便正常填写表单 -->
<property name="defaultEncoding" value="UTF-8"/>
<!-- 阈值,低于此值只保留在内存中。超过后生成硬盘的临时文件 -->
<property name="maxInMemorySize" value="40960"/>
<!-- 上传文件大小限制 10485760=10M -->
<property name="maxUploadSize" value="10485760"/>
</bean>
</beans>
jdbc.properties
-
数据源连接的信息
-
jdbc.url=jdbc:mysql://localhost:3306/demo01 jdbc.username=root jdbc.password=123456
-
不可使用
username
作为 key- 对 key 引用时 ${username} 会默认引用系统用户而非配置文件值,造成异常
-
springmvc-config.xml
- 组件扫描器:创建 controller、全局异常处理对象
- 视图解析器:辅助定位视图资源文件
- 注解驱动
- 访问静态资源
- 进行 JSON 数据格式转换
- 拦截器
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://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/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 组件扫描器,@Controller 注解所在包,创建 controller 对象 -->
<context:component-scan base-package="ssm_demo.controller, ssm_demo.exception"/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 注解驱动 -->
<mvc:annotation-driven/>
<!-- 声明拦截器,可以有 0 或多个 -->
<mvc:interceptors>
<!-- 声明一个拦截器 -->
<mvc:interceptor>
<!-- 指定拦截的请求 url 地址 -->
<!-- path 就是 url 地址,可以使用 通配符 **表示任意字符,文件或多级目录和目录中文件 -->
<!-- 请求地址由 user 开头时都会被拦截 -->
<mvc:mapping path="/user/**"/>
<bean class="ssm_demo.interceptor.MyInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<!-- 所有请求都会被拦截 -->
<mvc:mapping path="/**"/>
<bean class="ssm_demo.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
mybatis-config.xml
- 指定 Maper 映射
- 输出日志到控制台
<?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>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<mappers>
<!-- <package name="ssm_demo/dao"/>-->
<mapper resource="ssm_demo/dao/DemoDao.xml"/>
</mappers>
</configuration>
domain
Demo.java
package ssm_demo.domain;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Demo {
private int id;
private String name;
private int age;
private Date date;
public Demo() {
}
public Demo(int id, String name, int age, Date date) {
this.id = id;
this.name = name;
this.age = age;
this.date = date;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
private String date2String(Date date){
return new SimpleDateFormat("yyyy-MM-dd").format(date);
}
@Override
public String toString() {
return "基本信息:" +
"\t 姓名 = " + name +
",\t 年龄 = " + age +
",\t 生日 = " + date2String(date);
}
}
dao
DemoDao.java
package ssm_demo.dao;
import ssm_demo.domain.Demo;
import java.util.List;
public interface DemoDao {
//添加数据
int add(Demo demo);
//查询所有数据
List<Demo> queryAll();
//根据姓名模糊查询
List<Demo> queryByName(String name);
//根据对象参数内容模糊查询
List<Demo> queryBy(Demo demo);
//根据 id、name 精确查询
Demo queryByIdName(Demo demo);
}
DemoDao.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
mybatis-3-mapper.dtd:约束文件名,拓展名 dtd
约束文件作用:限制、检查当前文件中出现的标签、属性名必须符合 MyBatis 要求
-->
<!-- namespace:命名空间,自定义唯一值;使用 dao 接口全限定名 -->
<mapper namespace="ssm_demo.dao.DemoDao">
<resultMap id="Demo" type="ssm_demo.domain.Demo">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="date" property="date"/>
</resultMap>
<insert id="add">
insert into demo(name, age, date)
values (#{name}, #{age},
<if test="date != null">
#{date}
</if>
<if test="date == null">
now()
</if>
)
</insert>
<select id="queryAll" resultMap="Demo">
select `name`, age, `date`
from demo
</select>
<select id="queryByName" resultMap="Demo">
select `name`, age, `date`
from demo
where `name` like '%' #{name} '%'
</select>
<select id="queryBy" resultMap="Demo">
select `name`, age, `date` from demo
<where>
id is null
<if test="id != 0">
or id = #{id}
</if>
<if test="name != null">
or `name` like '%' #{name} '%'
</if>
<if test="age != 0">
and age >= #{age}
</if>
<if test="date != null">
and `date` <= #{date}
</if>
</where>
</select>
<select id="queryByIdName" resultMap="Demo">
select `name`, age, `date`
from demo
where id = #{id}
and `name` = #{name}
</select>
</mapper>
service
DemoService.java
package ssm_demo.service;
import ssm_demo.domain.Demo;
import java.util.List;
public interface DemoService {
//添加数据
int add(Demo demo);
//查询所有或根据姓名模糊查询
List<Demo> query(Demo demo);
//模糊查询
List<Demo> queryBy(Demo demo);
//根据 id、姓名 精确查询
Demo queryByIdName(Demo demo);
}
DemoDerviceImpl.java
package ssm_demo.service;
import org.springframework.stereotype.Service;
import ssm_demo.dao.DemoDao;
import ssm_demo.domain.Demo;
import javax.annotation.Resource;
import java.util.List;
@Service
public class DemoServiceImpl implements DemoService {
@Resource
private DemoDao demoDao;
@Override
public int add(Demo demo) {
System.out.println(demoDao);
return demoDao.add(demo);
}
@Override
public List<Demo> query(Demo demo) {
if (demo.getName() != null) {
return demoDao.queryByName(demo.getName());
} else {
return demoDao.queryAll();
}
}
@Override
public List<Demo> queryBy(Demo demo) {
return demoDao.queryBy(demo);
}
@Override
public Demo queryByIdName(Demo demo) {
return demoDao.queryByIdName(demo);
}
}
controller
MyController.java
package ssm_demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import ssm_demo.domain.Demo;
import ssm_demo.service.DemoService;
import javax.annotation.Resource;
@Controller
public class MyController {
@Resource
private DemoService service;
@RequestMapping("/register.do")
public String doRegister(){
return "registerImpl";
}
@RequestMapping("/registerImpl.do")
public ModelAndView doRegisterImpl(Demo demo){
int rows = service.add(demo);
ModelAndView mv = new ModelAndView();
if (rows > 0){
mv.addObject("result", "注册成功");
}else {
mv.addObject("result", "注册失败");
}
mv.setViewName("show");
return mv;
}
@RequestMapping("/dengLu.do")
public String doDengLu(){
return "dengLuImpl";
}
@RequestMapping("/dengLuImpl.do")
public ModelAndView doDengLuImpl(Demo demo){
Demo demo1 = service.queryByIdName(demo);
ModelAndView mv = new ModelAndView();
if (demo1 != null){
mv.addObject("result" , "登陆成功");
}else {
mv.addObject("result", "登陆失败");
}
mv.setViewName("show");
return mv;
}
}
exception
MyExceptionController
- 对项目全局范围内的异常进行拦截统一处理
package ssm_demo.exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
/**
* 全局异常处理类
*/
@ControllerAdvice
public class MyException {
/*
* 处理 NullPointerException 异常
*/
@ExceptionHandler(NullPointerException.class)
public ModelAndView doNull(Exception e){
ModelAndView mv = new ModelAndView();
mv.addObject("type", "未知异常");
mv.addObject("message", e.getMessage());
mv.setViewName("exception");
return mv;
}
/*
* 默认处理所有类型异常,不指定注解 value 属性
* 可以处理 controller 抛出的所有类型异常
*/
@ExceptionHandler
public ModelAndView doDefault(Exception e){
ModelAndView mv = new ModelAndView();
mv.addObject("type", "未知异常");
mv.addObject("message", e.getMessage());
mv.setViewName("exception");
return mv;
}
}
interceptor
MyInterceptor
- 拦截器
- 拦截请求在处理周期内进行验证等处理
package ssm_demo.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 {
/**
* 预处理方法:整个项目的入口
* 执行在 控制器方法之前,用户请求先到达此方法
* 可验证用户是否登录、是否有权限访问某个连接地址(url)
* 验证失败拦截请求,请求不能被处理,到此截止
* 验证成功放行请求,此时控制器方法才能执行
* @param request
* @param response
* @param handler 被拦截的控制器对象
* @return true:通过验证 false:验证失败
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
return HandlerInterceptor.super.preHandle(request, response, handler);
}
/**
* 后处理方法
* 在处理器方法之后执行
* 可获取处理器方法返回值,且可以修改 ModelAndView 中的数据和视图
* 能影响到最后执行结果,主要对原来的结果进行 二次修正
* @param request
* @param response
* @param handler 被拦截的处理器对象
* @param modelAndView 处理器方法返回值
*/
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
/**
* 最后执行的方法
* 在请求处理完成后完成:视图处理完成后,对视图进行了 forward认为是请求完成
* 一般做资源回收工作:程序请求过程中创建的对象可在此删除以释放空间
* @param request
* @param response
* @param handler 被拦截的处理器对象
* @param ex 程序中的异常
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
WEB-INF
jsp
dengLuImpl.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册</title>
</head>
<body>
<form action="dengLuImpl.do" method="post">
请输入用户id<br/><input type="text" name="id"/><br/>
请输入用户名<br/><input type="text" name="name"/><br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
registerImpl.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册</title>
</head>
<body>
<form action="registerImpl.do">
请输入姓名<br/><input type="text" name="name"/><br/>
请输入年龄<br/><input type="text" name="age"/><br/>
<br/><input type="submit" value="提交"/>
</form>
</body>
</html>
show.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册</title>
</head>
<body>
<h3>result: ${result}</h3>
</body>
</html>
web.xml
- 注册 servlet
- 创建 springMVC 容器
- 注册 servlet 映射关系
- 注册 字符过滤器
- 注册 字符过滤器范围
- 注册 spring 容器
- 使用 监听器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
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>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/springmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 指定 servlet 映射关系 -->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 注册字符过滤器 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!-- 指定字符过滤器映射关系 -->
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 注册 Spring 容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/applicationContext.xml</param-value>
</context-param>
<!-- 监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
index.jsp
<%--
Created by IntelliJ IDEA.
User: 欧尼熊
Date: 2022-02-23
Time: 16:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Demo 测试</title>
</head>
<body>
<div align="center">
<h2> 测试注册、 登录 功能 </h2>
<br/>
<a href="register.do"> 注册</a>
<a href="dengLu.do">登录</a>
<img src="Pictures/全家福.jpg" alt="暂时无法显示">
</div>
</body>
</html>
```# SSM
SSM 整合开发
- SpringMVC + Spring + MyBatis 整合
- SpringMVC:视图层、界面层;负责接收请求,显示处理结果
- Spring:业务层;管理 service、dao、工具类对象
- MyBatis:持久层;访问数据库
- Java EE 开发框架
- 实质就是将 MyBatis 整合入 Spring
- 两种方式
- XML 配置方式
- 基于注解
用户发起请求 → SpringMVC 接收 → Spring 中 service 对象 → MyBatis 处理数据
- 再将获得的结果按顺序返回,显示在页面
## SSM 整合
- 容器问题:整合中存在不同容器
- SpringMVC 容器,管理 Controller 控制器对象
- Spring 容器,管理 service、dao、工具类对象
- SpringMVC 容器是 Spring 容器的子容器
- 类似 Java 继承关系,子容器可以访问父容器内容
- 将使用的对象放到合适的容器创建、管理
- Controller 和 Web 开发相关对象放到 SpringMVC 容器
- 声明在 SpringMVC 配置文件
- service、dao 对象放到 Spring 容器
- 声明在 Spring 配置文件
### 实现步骤
1. 创建 Maven 项目
2. 添加依赖
- springmvc、spring、mybatis 框架依赖
- jackson 依赖、mysql 驱动、druid 连接池、jsp、servlet 依赖
3. 编写 web.xml
- 注册 DispatcherServlet
- 用来创建 SpringMVC 容器,创建 Controller 类对象
- 创建 servlet 后才能接收用户请求
- 注册 Spring 的监听器 ContextLoaderListener
- 创建 Spring 容器对象之后才能创建 service、dao 等对象
- 注册字符集过滤器
- 解决 post 请求乱码
4. 创建包结构
- controller、service、dao、实体类包
5. 编写配置文件
- SpringMVC 配置文件
- Spring 配置文件
- MyBatis 配置文件
- 数据库连接属性配置文件
6. 业务逻辑实现
- java 业务代码
- 前端 jsp 页面
### 简单整合
仅实现最简单的注册、登录功能
#### pom.xml
```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
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>ssm</groupId>
<artifactId>ssm_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
<dependencies>
<!-- Spring 依赖 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.16</version>
</dependency>
<!-- spring 事务处理 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.16</version>
</dependency>
<!-- Spring 事务处理 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.16</version>
</dependency>
<!-- mybatis依赖 -->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<!-- mybatis-spring 整合依赖 -->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
<!-- 数据库连接驱动 -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!-- druid 连接池依赖 -->
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<!-- springMVC 依赖 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.16</version>
</dependency>
<!-- Jackson依赖,转换 json 格式数据 -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.1</version>
</dependency>
<!-- Jackson 依赖 -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.1</version>
</dependency>
<!-- servlet 依赖 -->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- jsp 依赖 -->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
conf
applicationContext.xml
- 组件扫描器
- 创建 service 对象
- 数据源配置
- 导入属性配置文件
- 创建 SqlSessionFactory 对象
- 声明 MyBatis 扫描器,创建 dao 对象
- 事务处理
- 文件上传处理
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://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
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 声明组件扫描器,扫描注解创建 service 对象 -->
<context:component-scan base-package="ssm_demo.service"/>
<!-- 导入属性配置文件 -->
<context:property-placeholder location="classpath:conf/jdbc.properties" file-encoding="UTF-8"/>
<!-- 配置连接池数据源 -->
<bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="maxActive" value="20"/>
<property name="initialSize" value="5"/>
</bean>
<!-- 声明 SqlSessionFactoryBean 创建 sqlSessionFactory 对象 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="datasource"/>
<property name="configLocation" value="classpath:conf/mybatis-config.xml"/>
</bean>
<!-- 声明 MyBatis 扫描器,创建 dao 对象 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="ssm_demo.dao"/>
</bean>
<!-- 声明事务管理器 -->
<bean id="manager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"/>
</bean>
<!-- 配置方法事务属性 -->
<tx:advice id="interceptor" transaction-manager="manager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" isolation="DEFAULT" read-only="false" />
<tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT" read-only="false" />
<tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT" read-only="false" />
<tx:method name="query*" propagation="REQUIRED" isolation="DEFAULT" read-only="true" />
<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 关联切入点和事务切面 -->
<aop:config>
<aop:pointcut id="servicePt" expression="execution(* *..service..*.*(..))"/>
<aop:advisor advice-ref="interceptor" pointcut-ref="servicePt"/>
</aop:config>
<!-- 文件上传配置 -->
<bean id="resolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 请求的编码格式,必须和 jsp 的 pageEncoding属性一致,以便正常填写表单 -->
<property name="defaultEncoding" value="UTF-8"/>
<!-- 阈值,低于此值只保留在内存中。超过后生成硬盘的临时文件 -->
<property name="maxInMemorySize" value="40960"/>
<!-- 上传文件大小限制 10485760=10M -->
<property name="maxUploadSize" value="10485760"/>
</bean>
</beans>
jdbc.properties
-
数据源连接的信息
-
jdbc.url=jdbc:mysql://localhost:3306/demo01 jdbc.username=root jdbc.password=123456
-
不可使用
username
作为 key- 对 key 引用时 ${username} 会默认引用系统用户而非配置文件值,造成异常
-
springmvc-config.xml
- 组件扫描器:创建 controller、全局异常处理对象
- 视图解析器:辅助定位视图资源文件
- 注解驱动
- 访问静态资源
- 进行 JSON 数据格式转换
- 拦截器
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://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/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 组件扫描器,@Controller 注解所在包,创建 controller 对象 -->
<context:component-scan base-package="ssm_demo.controller, ssm_demo.exception"/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 注解驱动 -->
<mvc:annotation-driven/>
<!-- 声明拦截器,可以有 0 或多个 -->
<mvc:interceptors>
<!-- 声明一个拦截器 -->
<mvc:interceptor>
<!-- 指定拦截的请求 url 地址 -->
<!-- path 就是 url 地址,可以使用 通配符 **表示任意字符,文件或多级目录和目录中文件 -->
<!-- 请求地址由 user 开头时都会被拦截 -->
<mvc:mapping path="/user/**"/>
<bean class="ssm_demo.interceptor.MyInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<!-- 所有请求都会被拦截 -->
<mvc:mapping path="/**"/>
<bean class="ssm_demo.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
mybatis-config.xml
- 指定 Maper 映射
- 输出日志到控制台
<?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>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<mappers>
<!-- <package name="ssm_demo/dao"/>-->
<mapper resource="ssm_demo/dao/DemoDao.xml"/>
</mappers>
</configuration>
domain
Demo.java
package ssm_demo.domain;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Demo {
private int id;
private String name;
private int age;
private Date date;
public Demo() {
}
public Demo(int id, String name, int age, Date date) {
this.id = id;
this.name = name;
this.age = age;
this.date = date;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
private String date2String(Date date){
return new SimpleDateFormat("yyyy-MM-dd").format(date);
}
@Override
public String toString() {
return "基本信息:" +
"\t 姓名 = " + name +
",\t 年龄 = " + age +
",\t 生日 = " + date2String(date);
}
}
dao
DemoDao.java
package ssm_demo.dao;
import ssm_demo.domain.Demo;
import java.util.List;
public interface DemoDao {
//添加数据
int add(Demo demo);
//查询所有数据
List<Demo> queryAll();
//根据姓名模糊查询
List<Demo> queryByName(String name);
//根据对象参数内容模糊查询
List<Demo> queryBy(Demo demo);
//根据 id、name 精确查询
Demo queryByIdName(Demo demo);
}
DemoDao.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
mybatis-3-mapper.dtd:约束文件名,拓展名 dtd
约束文件作用:限制、检查当前文件中出现的标签、属性名必须符合 MyBatis 要求
-->
<!-- namespace:命名空间,自定义唯一值;使用 dao 接口全限定名 -->
<mapper namespace="ssm_demo.dao.DemoDao">
<resultMap id="Demo" type="ssm_demo.domain.Demo">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="date" property="date"/>
</resultMap>
<insert id="add">
insert into demo(name, age, date)
values (#{name}, #{age},
<if test="date != null">
#{date}
</if>
<if test="date == null">
now()
</if>
)
</insert>
<select id="queryAll" resultMap="Demo">
select `name`, age, `date`
from demo
</select>
<select id="queryByName" resultMap="Demo">
select `name`, age, `date`
from demo
where `name` like '%' #{name} '%'
</select>
<select id="queryBy" resultMap="Demo">
select `name`, age, `date` from demo
<where>
id is null
<if test="id != 0">
or id = #{id}
</if>
<if test="name != null">
or `name` like '%' #{name} '%'
</if>
<if test="age != 0">
and age >= #{age}
</if>
<if test="date != null">
and `date` <= #{date}
</if>
</where>
</select>
<select id="queryByIdName" resultMap="Demo">
select `name`, age, `date`
from demo
where id = #{id}
and `name` = #{name}
</select>
</mapper>
service
DemoService.java
package ssm_demo.service;
import ssm_demo.domain.Demo;
import java.util.List;
public interface DemoService {
//添加数据
int add(Demo demo);
//查询所有或根据姓名模糊查询
List<Demo> query(Demo demo);
//模糊查询
List<Demo> queryBy(Demo demo);
//根据 id、姓名 精确查询
Demo queryByIdName(Demo demo);
}
DemoDerviceImpl.java
package ssm_demo.service;
import org.springframework.stereotype.Service;
import ssm_demo.dao.DemoDao;
import ssm_demo.domain.Demo;
import javax.annotation.Resource;
import java.util.List;
@Service
public class DemoServiceImpl implements DemoService {
@Resource
private DemoDao demoDao;
@Override
public int add(Demo demo) {
System.out.println(demoDao);
return demoDao.add(demo);
}
@Override
public List<Demo> query(Demo demo) {
if (demo.getName() != null) {
return demoDao.queryByName(demo.getName());
} else {
return demoDao.queryAll();
}
}
@Override
public List<Demo> queryBy(Demo demo) {
return demoDao.queryBy(demo);
}
@Override
public Demo queryByIdName(Demo demo) {
return demoDao.queryByIdName(demo);
}
}
controller
MyController.java
package ssm_demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import ssm_demo.domain.Demo;
import ssm_demo.service.DemoService;
import javax.annotation.Resource;
@Controller
public class MyController {
@Resource
private DemoService service;
@RequestMapping("/register.do")
public String doRegister(){
return "registerImpl";
}
@RequestMapping("/registerImpl.do")
public ModelAndView doRegisterImpl(Demo demo){
int rows = service.add(demo);
ModelAndView mv = new ModelAndView();
if (rows > 0){
mv.addObject("result", "注册成功");
}else {
mv.addObject("result", "注册失败");
}
mv.setViewName("show");
return mv;
}
@RequestMapping("/dengLu.do")
public String doDengLu(){
return "dengLuImpl";
}
@RequestMapping("/dengLuImpl.do")
public ModelAndView doDengLuImpl(Demo demo){
Demo demo1 = service.queryByIdName(demo);
ModelAndView mv = new ModelAndView();
if (demo1 != null){
mv.addObject("result" , "登陆成功");
}else {
mv.addObject("result", "登陆失败");
}
mv.setViewName("show");
return mv;
}
}
exception
MyExceptionController
- 对项目全局范围内的异常进行拦截统一处理
package ssm_demo.exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
/**
* 全局异常处理类
*/
@ControllerAdvice
public class MyException {
/*
* 处理 NullPointerException 异常
*/
@ExceptionHandler(NullPointerException.class)
public ModelAndView doNull(Exception e){
ModelAndView mv = new ModelAndView();
mv.addObject("type", "未知异常");
mv.addObject("message", e.getMessage());
mv.setViewName("exception");
return mv;
}
/*
* 默认处理所有类型异常,不指定注解 value 属性
* 可以处理 controller 抛出的所有类型异常
*/
@ExceptionHandler
public ModelAndView doDefault(Exception e){
ModelAndView mv = new ModelAndView();
mv.addObject("type", "未知异常");
mv.addObject("message", e.getMessage());
mv.setViewName("exception");
return mv;
}
}
interceptor
MyInterceptor
- 拦截器
- 拦截请求在处理周期内进行验证等处理
package ssm_demo.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 {
/**
* 预处理方法:整个项目的入口
* 执行在 控制器方法之前,用户请求先到达此方法
* 可验证用户是否登录、是否有权限访问某个连接地址(url)
* 验证失败拦截请求,请求不能被处理,到此截止
* 验证成功放行请求,此时控制器方法才能执行
* @param request
* @param response
* @param handler 被拦截的控制器对象
* @return true:通过验证 false:验证失败
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
return HandlerInterceptor.super.preHandle(request, response, handler);
}
/**
* 后处理方法
* 在处理器方法之后执行
* 可获取处理器方法返回值,且可以修改 ModelAndView 中的数据和视图
* 能影响到最后执行结果,主要对原来的结果进行 二次修正
* @param request
* @param response
* @param handler 被拦截的处理器对象
* @param modelAndView 处理器方法返回值
*/
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
/**
* 最后执行的方法
* 在请求处理完成后完成:视图处理完成后,对视图进行了 forward认为是请求完成
* 一般做资源回收工作:程序请求过程中创建的对象可在此删除以释放空间
* @param request
* @param response
* @param handler 被拦截的处理器对象
* @param ex 程序中的异常
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
WEB-INF
jsp
dengLuImpl.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册</title>
</head>
<body>
<form action="dengLuImpl.do" method="post">
请输入用户id<br/><input type="text" name="id"/><br/>
请输入用户名<br/><input type="text" name="name"/><br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
registerImpl.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册</title>
</head>
<body>
<form action="registerImpl.do">
请输入姓名<br/><input type="text" name="name"/><br/>
请输入年龄<br/><input type="text" name="age"/><br/>
<br/><input type="submit" value="提交"/>
</form>
</body>
</html>
show.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>注册</title>
</head>
<body>
<h3>result: ${result}</h3>
</body>
</html>
web.xml
- 注册 servlet
- 创建 springMVC 容器
- 注册 servlet 映射关系
- 注册 字符过滤器
- 注册 字符过滤器范围
- 注册 spring 容器
- 使用 监听器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
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>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/springmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 指定 servlet 映射关系 -->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 注册字符过滤器 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!-- 指定字符过滤器映射关系 -->
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 注册 Spring 容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/applicationContext.xml</param-value>
</context-param>
<!-- 监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
index.jsp
<%--
Created by IntelliJ IDEA.
User: 欧尼熊
Date: 2022-02-23
Time: 16:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Demo 测试</title>
</head>
<body>
<div align="center">
<h2> 测试注册、 登录 功能 </h2>
<br/>
<a href="register.do"> 注册</a>
<a href="dengLu.do">登录</a>
<img src="Pictures/全家福.jpg" alt="暂时无法显示">
</div>
</body>
</html>