拦截器
三个抽象方法
package com.atguigu.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class MyInterceptor1 implements HandlerInterceptor {
//Controller方法执行之前
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("1-我是拦截器之前");
return true;
//true请求放行 false 请求拦截
}
//拦截器业务执行之后
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("2-我是拦截器业务之后,记录/处理返回值的");
}
//业务处理完成,数据返回的最后一步
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("业务处理完成,数据返回的最后一步");
}
}
拦截器执行顺序
先执行,最后返回
拦截器配置文件中的配置
拦截器在springmvc.xml中的配置
<!--6.配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<!--
路径解释:
/** 表示拦截所有路径
/* 表示拦截一级路径 比如拦截 /user 但不拦截 /user/getMsg
-->
<ref bean="myInterceptor1"></ref>
</mvc:interceptor>
</mvc:interceptors>
拦截器与过滤器的区别
SpringMVC中异常处理机制
异常的说明
在业务执行过程中,如果频繁的添加try-catch 则影响代码的结构,耦合性高,所以应该使用动态代理机制简化代码. 所以在框架中使用AOP机制解决该问题
只拦截Controller层, SpringMVC针对AOP机制进行优化 全局异常处理机制
关系: 动态代理 -> AOP机制 -> Controller层 -> SpringMVC全局异常处理机制
基于配置的处理方式
需要手动书写配置的异常(基本不使用)
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!--
properties的键表示处理器方法执行过程中出现的异常
properties的值表示若出现指定异常时,设置一个新的视图名称,跳转到指定页面
-->
<prop key="java.lang.ArithmeticException">error</prop>
</props>
</property>
<!--
exceptionAttribute属性设置一个属性名,将出现的异常信息在请求域中进行共享
-->
<property name="exceptionAttribute" value="ex"></property>
</bean>
关于SpringMVC中的静态资源问题说明
制作一个错误跳转的界面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>页面错误</title>
<base th:href="@{/}">
</head>
<body>
<img src="static/img/error.png">
</body>
</html>
通过地址栏跳转发现跳转不过去
观察报错是404
问题出现在框架上,Servlet要拦截所有路径,包括error在内
拦截路径为 '/' 拦截所有请求, 包含静态资源 不包含jsp等动态资源
解决方案: 应该让SpringMVC放行静态资源(图片/音频/视频/css/js/html等),只拦截用户的真实请求
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
解决方法:在springmvc.xml文件中加入放行静态资源的配置
<!--
放行静态资源
用户的请求先经过Servlet进行处理,如果匹配不到资源,则查找本地目录下的webapp
如果依然匹配不到则报错返回,如果找到则返回静态资源
-->
<mvc:default-servlet-handler/>
基于注解的异常处理
不选择使用 return "error"; 是因为跳转之后路径还是 http://localhost:8080/springmvc/hello
使用重定向 http://localhost:8080/springmvc/error 路径转为更为严谨
同时,选择使用重定向是路径访问,通过Servlet通过上面说明的静态资源问题中的配置转到error.html
两个注解
@ControllerAdvice -> 全局异常处理机制的注解
@ExceptionHandler -> 处理异常的方法注解
package com.atguigu.advice;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
//全局异常处理机制的注解 SpringMVC负责
@ControllerAdvice
public class ExceptionAdvice {
//@ExceptionHandler表示发生异常时,处理异常的方法 后面跟异常的类型
@ExceptionHandler(RuntimeException.class)
public String error(Exception e){
e.printStackTrace();
//不使用return是因为地址栏访问hello却出现404 所以选择重定向
// return "error";
//重定向是路径通过Servlet解析后,找不到error相关的方法然后才寻找静态资源
//因为error.html在webapp目录下,只能通过Servlet访问
return "redirect:/error";
}
}
注解配置SpringMVC(了解即可)
使用注解和配置类代替web.xml和springmvc.xml文件
编辑WebInit类
package com.atguigu.init;
import com.atguigu.config.SpringConfig;
import com.atguigu.config.SpringMVCConfig;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.Filter;
/*该类主要代替web.xml配置文件 */
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {
//设置一个配置类,代替Spring的配置文件
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
//设置一个配置类 代替SpringMVC的配置文件
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMVCConfig.class};
}
//设置SpringMVC中的前端控制器dispatcherServlet的url路径
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
//设置编码过滤器
@Override
protected Filter[] getServletFilters() {
//创建编码过滤器
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("utf-8");
//设置请求和响应的编码
filter.setForceEncoding(true);
return new Filter[]{filter};
}
}
编辑SpringMVCConfig.xml文件
package com.atguigu.config;
import com.atguigu.interceptor.MyInterceptor;
import com.atguigu.interceptor.MyInterceptor2;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ITemplateResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
import java.util.List;
import java.util.Properties;
@Configuration //标识配置类
@ComponentScan("com.atguigu")
@EnableWebMvc //开启mvc注解驱动
public class SpringMVCConfig implements WebMvcConfigurer {
/*1.设置默认servlet处理静态资源 放行静态资源*/
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
//2.配置视图控制器
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
}
//3. 配置文件上传视图解析器 可以将标识方法的返回值当作bean 交给Spring容器管理
@Bean
public CommonsMultipartResolver multipartResolver(){
return new CommonsMultipartResolver();
}
//4.设置拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
MyInterceptor myInterceptor = new MyInterceptor();
MyInterceptor2 myInterceptor2 = new MyInterceptor2();
registry.addInterceptor(myInterceptor).addPathPatterns("/**").excludePathPatterns("/");
registry.addInterceptor(myInterceptor2).addPathPatterns("/**");
}
/*5.配置异常解析器*/
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
SimpleMappingExceptionResolver exceptionResolver =
new SimpleMappingExceptionResolver();
Properties prop = new Properties();
prop.setProperty("java.lang.RuntimeException","eror");
exceptionResolver.setExceptionMappings(prop);
resolvers.add(exceptionResolver);
}
/**
* 6.配置视图解析器
*/
//配置生成模板解析器
@Bean
public ITemplateResolver templateResolver() {
WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
//ServletContextTemplateResolver需要一个ServletContext作为构造参数,可通过WebApplicationContext 的方法获得
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(
webApplicationContext.getServletContext());
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setTemplateMode(TemplateMode.HTML);
return templateResolver;
}
//生成模板引擎并为模板引擎注入模板解析器
@Bean
public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
return templateEngine;
}
//生成视图解析器并未解析器注入模板引擎
@Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setTemplateEngine(templateEngine);
return viewResolver;
}
}
SpringMVC与Ajax交互
Ajax能够实现异步的原理
同步: 必须等待上一个方法执行完成才能开始下一个方法
异步: 调用可以同时执行多个任务,相互独立,互不干扰
关键点在于Ajax中的引擎
Ajax能够实现异步的原理:
用户在发送请求给Ajax引擎之后,继续执行自己的任务.等待Ajax回调用户的函数,用户在执行自己的方法
Ajax入门案例
<script setup>
import axios from "axios"
function getMsg(){
let url = "http://localhost:8080/springmvc/axios/getMsg";
axios({
method:"get",
url,
params:{
id:1001,
name:"tom"
}
}).then(
function(result){
console.log(result)
console.log(result.data)
console.log(result.status)
}
).catch(
function(error){
console.log(error)
}
)
}
getMsg()
</script>
<template>
<div>
<h1>Ajax案例练习</h1>
</div>
</template>
<style scoped>
</style>
最终简化代码
let getMsg4 = async () => {
let url = "http://localhost:8080/springmvc/axios/getMsg";
let params = { id:120,name:"Ike" }
let {data:data,status:status} = await axios.get(url,{params:params})
console.log(result.data)
}
关于对象的操作
javascript中获取对象的函数
let getUser = async () => {
let url = "http://localhost:8080/springmvc/axios/getUser";
let {data:data,status:status} = await axios.get(url,{params:params})
console.log(result.data)
}
AxiosController中对应getUser方法
对象转换
将对象转化为JSON
其中包含Java对象转化为JSON字符串的方法
@GetMapping("/getUser")
public void getUser(HttpServletResponse response) throws IOException {
//要求对象必须有 get/set 方法
User user = new User(12, "erzi", 27, "男");
//目的将user对象 返回给页面 所以需要转化为JSON
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(user);
//服务器返回业务给数据
response.getWriter().write(json);
}
将JSON转化为对象
@GetMapping("/getUser")
public void getUser(HttpServletResponse response) throws IOException {
//要求对象必须有 get/set 方法
User user = new User(12, "erzi", 27, "男");
//目的将user对象 返回给页面 所以需要转化为JSON
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(user);
//将JSON转化为对象
User user2 = mapper.readValue(json, User.class);
System.out.println("user2 = " + user2);
//服务器返回业务给数据
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(json);
}
利用注解@Responsebody
将代码极简
//将对象转化为JSON返回注解
@ResponseBody
@GetMapping("/getUser2")
public User getUser(){
User user = new User(130, "Zz7", 18, "女");
return user;
}
同源策略说明
同源策略是一种约定,它是浏览器最核心也是最基本的安全功能. 同源策略会组织一个域的javascript脚本和另一个域的内容进行交互, 是用于隔离潜在恶意文件的关键安全机制.
如果Ajax的请求路径与服务器的路径 协议://域名:端口 都一样时,属于同域访问,否则属于跨域访问
- http://localhost:80/springmvc/aa/bb
- http://localhost/springmvc/aa/bb
http的默认端口号为80 所以上面属于同域请求
- https://localhost:443/springmvc/aa/bb
- https://localhost/springmvc/aa/bb
https协议默认端口号为443
@CrossOrgihin 注解可以标识类和方法标识可以跨域访问
Mybatis
Mybatis介绍
Mybatis是持久层框架,主要作用简化JDBC操作,是一个半自动化的ORM映射框架
ORM介绍
- Object Relational Mapping 对象关系映射
- 映射说明:
- 需求:将数据库中的数据转化为对象
- 方式一:数据库中的表到对象 自动映射
- 表 -> 对象
- 字段 -> 属性
- 方式二: 将对象自动生成sql
- 新增sql : insert into 表名 (字段名) values (属性值)
- 其他自动化框架典型代表:
- Hibernate: 映射和sql都自动生成 学习额外的 hsql语句