1、Spring整合MyBatis:
-
在子工程中加入所需要的依赖
-
准备jdbc.properties
-
创建spring的配置文件、整合spring和mybatis
-
在spring的配置文件中加载jdbc.properties
-
配置数据源
-
测试数据库连接
-
配置SqlSessionFactoryBean
-
装配数据源
-
指定XXXMapper.xml文件的位置
-
指定mybatis的全局配置问价的位置
-
-
配置mapperscannerConfigurer
-
测试是否可以装配xxxMapper接口访问数据库
1.1、在子工程中加入所需要的依赖:
注意:
dependencesManagement标签,在父类工程中的所有的依赖只是声明并没有真实的引入依赖,他只是起到一个管理的作用,在子类项目中,可以按需选择所要引入的依赖,之所以有这个标签是因为可以方便的进行依赖的版本的控制。子类项目只需要引入依赖(不用指定版本)。
<!-- Spring 依赖 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<!-- MyBatis 与 Spring 整合 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</dependency>
<!-- MyBatis 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
</dependency>
<!-- Spring 进行 JSON 数据转换依赖 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- JSTL 标签库 -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
1.2、准备jdbc.properties:
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/project_crowd?useUnicode=true&characterEncoding=UTF-8
jdbc.password=10100109
jdbc.username=root
1.3、创建spring的配置文件:
1.3.1 创建mybatis-config.xml文件
暂时没有配置,主要是设置一些全局配置其他整合在别的配置文件中
1.3.2 创建创建spring-persist-mybatis.xml文件
<!--加载外部属性文件: jdbc.properties-->
<context:property-placeholder location="jdbc.properties"/>
<!--配置数据源-->
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="password" value="${jdbc.password}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
</bean>
1.3.3 测试数据库连接
@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations = {"classpath:spring-persist-mybatis.xml"})
public class CrowdTest {
@Autowired
private DataSource dataSource;
@Test
public void testConnection() throws SQLException {
System.*out*.println(dataSource.getConnection());
}}
这里使用的是Spring对junt5的整合,然后使用的两个注解,还有一种方式是使用一种注解,
@SpringJUnitConfig(locations = "classpath:spring-persist-mybatis.xml")
1.3.4 配置SqlSessionFactoryBean
<!--配置SqlSessionFactoryBean-->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--指定myabtis全局配置文件的位置-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!--指定mapper.xml映射文件的位置-->
<property name="mapperLocations" value="classpath:mybatis/mapper/*.xml"/>
<!--指定数据源-->
<property name="dataSource" ref="druidDataSource"/>
</bean>
<!--配置mapperScannerConfigurer 来扫描mapper接口所在的包-->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.songzhishu.crowd.mapper"/>
</bean>
配置文件一定要好好的、细心的、认认真真的配置,我在测试的时候myabtis的核心配置文件我使用的是我自己的模板,然后创建完我也没有修改里面的配置文件导致一致出错,然后我一直以为是我导入的依赖的版本太高了,最后仔仔细细的看异常信息才解决问题!!!
2、日志系统:
2.1、导入logback日志文件的依赖:
<!--日志-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
2.1、配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>/ProjectLog/Crowd/Crowd.log.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>100MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!--mybatis log configure-->
<logger name="com.apache.ibatis" level="TRACE"/>
<logger name="java.sql.Connection" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>
<!-- 日志输出级别,logback日志级别包括五个:TRACE < DEBUG < INFO < WARN < ERROR -->
<root level="DEBUG">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
在这个配置文件中可以设置日志级别,以及设置日志信息输入的位置(控制台,本地化存储)。
3、声明式事务:
3.1、传统事务(编程式事务):
try {
// 核心操作前:开启事务(关闭自动提交)
// 对应 AOP 的前置通知
connection.setAutoCommit(false);
// 核心操作
adminService.updateXxx(xxx, xxx);
// 核心操作成功:提交事务
// 对应 AOP 的返回通知
connection.commit();
}catch(Exception e){
// 核心操作失败:回滚事务
// 对应 AOP 的异常通知
connection.rollBack();
}finally{
// 不论成功还是失败,核心操作终归是结束了
// 核心操作不管是怎么结束的,都需要释放数据库连接
// 对应 AOP 的后置通知
if(connection != null){
connection.close();
}
}
3.2、声明式事务:
3.2.1、执行过程:
3.2.2 导入依赖:
<!-- AOP 所需依赖 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<!-- AOP 所需依赖 -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
</dependency>
3.2.3 配置事务:
<!--spring的事务的配置-->
<!--配置自动扫描包:为啦让Service扫描到IOC容器-->
<context:component-scan base-package="com.songzhishu.crowd.service"/>
<!--配置事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="druidDataSource"/>
</bean>
<!--配置事务切面-->
<aop:config>
<!--切点 考虑到后面整合SpringSecurity,避免UserDetailsService加入事务控制 将切入点表达是定位ServiceImpl-->
<aop:pointcut id="txPointcut" expression="execution(* *..*ServiceImpl.*(..))"/>
<!--将切入点表达式式和事通知关联起来-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>
<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!--配置事务属性-->
<tx:attributes>
<!--查询方法,配置为只读-->
<tx:method name="get*" read-only="true" />
<tx:method name="find*" read-only="true" />
<tx:method name="query*" read-only="true" />
<tx:method name="count*" read-only="true"/>
<!--增删改: 配置事务的传播行为,回滚异常
propagation属性值:
REQUIRED 默认值 表示当前的方法在工作中必须有事务,如果当前线程中没有事务那么自己开启,如果有那么加入
用别人的如果别人错啦,自己可能被回滚
REQUIRED_NEW 建议使用的 表示当前方法必须在啊事务中,如果没有自己开启,如果有那么不加入就用自己的
牛死啦,不受别人的影响
rollback-for属性: 设置的异常和异常的子类都回滚
默认:运行时异常回滚
建议:编译时异常和运行时异常都要回滚
-->
<tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
<tx:method name="remove*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
<tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
<tx:method name="batch*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
</tx:attributes>
</tx:advice>
3.2.4 测试事务配置:
业务层:
@Service
public class AdminServiceImpl implements AdminService {
@Autowired
private AdminMapper adminMapper;
@Override
public void saveAdmin(Admin admin) {
adminMapper.insert(admin);
}
}
测试
/*测试事务*/
@Test
public void testTx() {
Admin admin = new Admin(null, "jerry", "123456", "杰瑞", "jerry@qq.com", null);
adminService.saveAdmin(admin);
}
4、表述层配置:
4.1、Spring整合SpringMVC的思路:
4.2、web.xml的配置:
4.2.1、配置 ContextLoaderListener:
<!--ContextLoaderListener:加载 Spring 的配置文件,根据 Spring 的配置文件初始化 IOC 容器。-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-persist-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
这里讲一下classpath:spring-persist-*.xml 这种方式好像不太可以,后面我在测试的时候发生错误啦,然后我就一个一个的写的,没有用这个!
4.2.2、CharacterEncodingFilter:
解决 POST 请求的字符乱码问题。需要注意的是:在 web.xml 中存在多个 Filter时,让这个 Filter 作为过滤器链中的第一个 Filter。request.setCharacterEncoding(encoding) 要求必须在所有request.getParameter(xxx)操作前面,response.setCharacterEncoding(encoding)要求必须在所有 response.getWriter()操作前面,不满足这个顺序要求字符集设定无法生效。
<!-- 配置 CharacterEncodingFilter 解决 POST 请求的字符乱码问题 -->
<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>
4.2.3、HiddenHttpMethodFilter:
<!--HiddenHttpMethodFilter-->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
4.2.4、前端控制器:
<!--前端控制器-->
<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:spring-web-mvc.xml</param-value>
</init-param>
<!--Servlet默认生命周期中,初始化创建对象是在第一次收到请求
dispatcherServlet创建对象后有大量的框架初始化,不适合第一次请求的时候去完成
设置load-on-startup 是为啦让DispacherServlet在web应用启动的时候来创建对象以及初始化
-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!--<url-pattern>/</url-pattern> 拦截所有的请求-->
<!--<url-pattern>*.html</url-pattern>
静态资源不经过SpringMVC,不需要特殊处理
可以实现伪静态 看起来是html文件,但是实际上是经过java代码运算
缺点:不符合RESTFul风格
-->
<url-pattern>*.html</url-pattern>
<!--如果AJAX请求的拓展名是html,但是实际上返回的是json数据,两者不匹配会报错406-->
<url-pattern>*.json</url-pattern>
</servlet-mapping>
4.3、SpringMVC的配置:
<!--自动扫描-->
<context:component-scan base-package="com.songzhishu.crowd.mvc"/>
<!--配置springMVC的注解驱动-->
<mvc:annotation-driven/>
<!--配置视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
4.4、测试SSM整合:
index发送请求:
<%--
Created by IntelliJ IDEA.
User: 斗痘侠
Date: 2023/10/28
Time: 20:34
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/test/ssm.html">测试SSM整合的环境</a>
</body>
</html>
controller:
@Controller
public class TestController {
@Autowired
private AdminService adminService;
@RequestMapping(value = "/test/ssm.html")
public String testSSM(ModelMap modelMap){
List<Admin> adminList=adminService.getAll();
modelMap.addAttribute("adminList",adminList);
return "target";
}
}
这里的Service层和mapper持久化层就不讲啦,有一个知识点比较薄弱就是对于MyBatis的逆向工程生成的复杂查询的使用不是很灵活,也可能是之前学的忘掉啦,反正就是要复习复习!
响应页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>success</h1>
${requestScope.adminList}
</body>
</html>
测试中间出现一个问题,就是在运行的时候说我的No qualifying bean of type 'com.songzhishu.crowd.service.api.AdminService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)大概的意思就是这东西不能自动装配,我刚开始以为是我没有注入或者是没有扫描到这个包,肯定不是因为byType而导致的,因为接口有一个实现类,后来经过排查和查资料,原来是我在web.xml中加载 Spring 的配置文件,根据 Spring 的配置文件初始化 IOC 容器的配置出啦问题。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-persist-mybatis.xml,classpath:Spring-persist-tx.xml</param-value>
</context-param>
一开始我加载配置文件使用的是spring-persist-*.xml,想着懒省事,结果不支持!!!然后就换啦一种写法。完美整合!!!
4.5、base标签:
<base href="http://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/"/>
需要注意的点
-
base 标签必须写在 head 标签内部
-
base 标签必须在所有“带具体路径”的标签的前面
-
serverName 部分 EL 表达式和 serverPort 部分 EL 表达式之间必须写“:”
-
serverPort 部分 EL 表达式和 contextPath 部分 EL 表达式之间绝对不能写“/”
-
原因:contextPath 部分 EL 表达式本身就是“/”开头
-
如果多写一个“/”会干扰 Cookie 的工作机制
-
serverPort 部分 EL 表达式后面必须写“/”
-
4.6、SpringMVC 环境下的 Ajax 请求
4.6.1、前端发送过来,后端要处理的请求有两种:
-
普通请求:后端处理完成后返回页面,浏览器使用使用页面替换整个窗口中的内容
-
Ajax 请求:后端处理完成后通常返回 JSON 数据,jQuery 代码使用 JSON 数据对页面局部更新
使用@RequestBody和@ResponseBody需要导入jackon的依赖!
<!-- Spring 进行 JSON 数据转换依赖 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
而且要开启mvc注解驱动!
4.6.2、AJAX发送数组的方式:
方式一:
$("#but1").click(function () {
/* $.get()和$.post()想要响应数据的话状态码必须是200
* $.ajax() 不管是什么状态码都可以响应*/
$.ajax({
"url": "send/array/one.html",//请求地址
"type": "post",//请求方式
"data": {
"array": [1, 2, 3, 4, 5, 6]
}, //请求参数
"dataType": "text",//响应的数据的处理方式
"success": function (response) {
alert(response);
//成功的回调函数
},
"error":function (response) {
alert(response);
//失败的回调函数
}
});
});
controller:
@RequestMapping(value = "/send/array/one.html")
public String testReceiverArrayOne(@RequestParam("array[]") List<Integer> array) {
array.forEach(System.out::println);
return "target";
}
你看明明传递的参数是array,但是想要接收请求参数要使用array[],离谱呀!
方式二:
$("#but2").click(function () {
/* $.get()和$.post()想要响应数据的话状态码必须是200
* $.ajax() 不管是什么状态码都可以响应*/
$.ajax({
"url": "send/array/two.html",//请求地址
"type": "post",//请求方式
"data": {
"array[0]": 5,
"array[1]": 4,
"array[2]": 3,
"array[3]": 1,//相当于是1,只有1
}, //请求参数
"dataType": "text",//响应的数据的处理方式
"success": function (response) {
alert(response);
//成功的回调函数
},
"error":function (response) {
alert(response);
//失败的回调函数
}
});
这个想要接受的话比较麻烦,需要创建一个实体类,如果是和业务相关的还好,但是如果没有关系就显得很多多余。
方式三:
$("#but3").click(function () {
/* $.get()和$.post()想要响应数据的话状态码必须是200
* $.ajax() 不管是什么状态码都可以响应*/
//要发送的数据
var array = [1, 2, 3, 4, 5];
//将数组转化为json字符串
var requestBody = JSON.stringify(array);
$.ajax({
"url": "send/array/three.html",//请求地址
"type": "post",//请求方式
"data": requestBody, //请求体
"contentType":"application/json;charset=UTF-8",//请求体的内容类型
"dataType": "text",//响应的数据的处理方式
"success": function (response) {
alert(response);
//成功的回调函数
},
"error": function (response) {
alert(response);
//失败的回调函数
}
});
});
controller:
@ResponseBody
@RequestMapping(value = "/send/array/three.html")
public String testReceiverArrayThree(@RequestBody List<Integer> array) {
Logger logger = LoggerFactory.getLogger(TestController.class);
array.forEach(logger::equals);
return "target";
}
这种方式的话,使用的是请求体和相应体的注解。
前端:
-
首先准备好要发送的 JSON 数据: JSON 对象 JSON 数组
-
将 JSON 对象或 JSON 数组转换为 JSON 字符串
-
var arrayStr = JSON.stringify(array);
-
-
将 JSON 字符串直接赋值给 data 属性
-
"data":arrayStr
-
"contentType":"application/json;charset=UTF-8"
-
后端
-
加入 jackson 依赖
-
开启注解驱动
-
使用注解
4.6.3、对Ajax请求做规范:
package com.songzhishu.crowd.util;
/**
* @BelongsProject: CrowdFunding-parent
* @BelongsPackage: com.songzhishu.crowd.util
* @Author: 斗痘侠
* @CreateTime: 2023-10-29 10:50
* @Description:
* @Version: 1.0
*/
public class ResultEntity<T> {
public static final String SUCCESS="SUCCESS";
public static final String FAILED="FAILED";
/**
* 封装请求结果是成功还是失败
*/
private String result;
/**
* 请求失败返回的错误信息
*/
private String message;
/**
* 要返回的数据
*/
private T data;
/**
* 成功只用一个成功信息,不携带其他参数
*/
public static <Type> ResultEntity<Type> successWithoutData(){
return new ResultEntity<Type>(SUCCESS,null,null);
}
/**
* 成功,需要携带消息
*/
public static <Type> ResultEntity<Type> successWithData(Type data){
return new ResultEntity<Type>(SUCCESS,null,data);
}
/**
* 失败,需要携带消息
*/
public static <Type> ResultEntity<Type> failed(String message){
return new ResultEntity<Type>(FAILED,message,null);
}
public ResultEntity() {
}
public ResultEntity(String result, String message, T data) {
this.result = result;
this.message = message;
this.data = data;
}
/**
* 获取
* @return result
*/
public String getResult() {
return result;
}
/**
* 设置
* @param result
*/
public void setResult(String result) {
this.result = result;
}
/**
* 获取
* @return message
*/
public String getMessage() {
return message;
}
/**
* 设置
* @param message
*/
public void setMessage(String message) {
this.message = message;
}
/**
* 获取
* @return data
*/
public T getData() {
return data;
}
/**
* 设置
* @param data
*/
public void setData(T data) {
this.data = data;
}
public String toString() {
return "ResultEntity{result = " + result + ", message = " + message + ", data = " + data + "}";
}
}
4.7、异常映射:
4.7.1、基于xml
在SpringMVC的配置文件
<!--配置基于xml的异常映射机制-->
<bean id="simpleMappingExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!--配置异常类型和具体视图页面的对应关系-->
<property name="exceptionMappings">
<props>
<!--key代表异常的全类名-->
<!--标签体里面是对应的视图-->
<prop key="java.lang.Exception">system-error</prop>
</props>
</property>
</bean>
4.7.1、基于注解
判断请求的类型的util
package com.songzhishu.crowd.util;
import javax.servlet.http.HttpServletRequest;
/**
* @BelongsProject: CrowdFunding-parent
* @BelongsPackage: com.songzhishu.crowd.util
* @Author: 斗痘侠
* @CreateTime: 2023-10-29 12:23
* @Description: 判断请求类型 普通还是AJAX
* @Version: 1.0
*/
public class CrowdUtil {
/**
* @description: true为AJAX
* @author: 斗痘侠
* @date: 2023/10/29 12:38
* @param: request
* @return: boolean
**/
public static boolean judgeRequestType(HttpServletRequest request) {
//获取请求头
String acceptHeader = request.getHeader("Accept");
String xRequestHeader = request.getHeader("X-Requested-With");
//判断
return (acceptHeader != null && acceptHeader.contains("application/json")) || (xRequestHeader != null && xRequestHeader.equals("XMLHttpRequest"));
}
}