注解
注解 | 说明 |
---|---|
xxx | xxx |
@ServletComponentScan | 扫描过滤器 |
@MapperScan | 扫描mapper |
@EnableOpenApi | 配置swagger3后开启swagger3 |
@Controller | 将web请求映射到注解了@RequestMapping的方法上 |
@ResponseBody | 返回json数据 |
@RequestMapping | 配置请求路径和方式等 |
@GetMapping | 配置请求路径等,其他请求类似 |
@RequestBody | 请求参数是Json格式 |
@PathVariable | restful风格使用,配置亲请求参数 |
@Component | 常用于实体类,被boot托管 |
@Value | 声明属性的值,可使用@Value(“${ }”) 从配置文件拿值 |
@ConfigurationProperties | 读取yml引用类型属性数据 |
@Repository | 常用于用于mapper类,被boot托管 |
@WebFilter | 过滤器配置,前提要开启扫描过滤器 |
@Order(1) | 过滤器执行次序,前提要开启扫描过滤器 |
@ResponseBody | 返回json数据 |
restful风格
REST描述了一个架构样式的网络系统,比如 web 应用程序。它首次出现在 2000 年 Roy Fielding 的博士论文中,Roy Fielding是 HTTP 规范的主要编写者之一。在目前主流的三种Web服务交互方案中,REST相比于SOAP(Simple Object Access protocol,简单对象访问协议)以及XML-RPC更加简单明了,无论是对URL的处理还是对Payload的编码,REST都倾向于用更加简单轻量的方法设计和实现。值得注意的是REST并没有一个明确的标准,而更像是一种设计的风格。
RESTFUL特点包括:
1、每一个URI代表1种资源;
2、客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源;
3、通过操作资源的表现形式来操作资源;
4、资源的表现形式是XML或者HTML;
5、客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请求都必须包含理解请求所必需的信息。
写法:/users/{参数1}/{参数2}
经典 | resuful |
---|---|
GET /user/getUser | GET /users |
POST /user/addUser?name=Tom&password=1234 | POST /users/TOM/1234 |
POST /user/updateUser | PUT /users/TOM/1234 |
POST /user/delUser?name=Tom | DELETE /users/TOM |
配置文件
优先级
.properties>.yml>.yaml
idea无法识别.yml和.yaml文件,没有语法提示解决方法
多种数据格式
- int
- double
- string
- 数组
- 对象
- 数组对象
# int
num: 1
# double
money: 2.5
# string
name: Tom
# 数组
items:
- Tom
- Json
# 对象
news:
title: 新闻
time: 2022-1-1
# 数组对象
items2:
- title: 新闻2
time: 2022-2-2
- title: 新闻3
time: 2022-3-3
从配置文件读取值
读取单一类型
写法:@Value(“${属性名.?.?}”),此处yml变量名和变量名无需一样
@Component
@Data
public class News {
// int
@Value("${num}")
private int num1;
// 对象属性
@Value("${news.title}")
private String title;
}
yml文件变量引用
baseDir: baseDir
tempDir: ${baseDir}\tempDir
需要转义字符时需要带引号,如:${baseDir}\tempDir
读取yml全部属性
自动装配Environment对象,通过getProperty(“属性名”)取值
org.springframework.core.env
@Autowired
private Environment environment;
environment.getProperty("属性名")
读取yml引用类型属性数据
@ConfigurationProperties(prefix = “alice”),此处yml变量名和变量名必须一样
yml
alice:
name: Alice
age: 18
likes: [苹果,香蕉]
java
@Component
@Data
@ConfigurationProperties(prefix = "alice")
public class Alice {
private String name;
private int age;
private String[] likes;
}
WebMvcConfigurer
视图:addViewControllers
视图控制
registry.addViewController("/path").setViewName("view_name");
重定向
方式一:
registry.addRedirectViewController("原请求路径","转发路径");
方式二:
@GetMapping("/testRedirect")
private String testRedirect(){
return "redirect:test_redirect";
}
方式三:
response.sendRedirect("/test.jsp");
转发
方式一:
@GetMapping("/testForward")
private String testForward(){
return "forward:test_forward";
}
方式二:
request.getRequestDispatcher("/test.jsp").forword(request,response);
重定向和转发区别:
1、请求次数:重定向是浏览器向服务器发送一个请求并收到响应后再次向一个新地址发出请求,转发是服务器收到请求后为了完成响应跳转到一个新的地址;重定向至少请求两次,转发请求一次;
2、地址栏不同:重定向地址栏会发生变化,转发地址栏不会发生变化;
3、是否共享数据:重定向两次请求不共享数据,转发一次请求共享数据(在request级别使用信息共享,使用重定向必然出错);
4、跳转限制:重定向可以跳转到任意URL,转发只能跳转本站点资源;
5、发生行为不同:重定向是客户端行为,转发是服务器端行为;
静态资源:addResourceHandlers
静态资源配置
方式一:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("path");
WebMvcConfigurer.super.addResourceHandlers(registry);
}
方式二:
yml
拦截器:addInterceptors
registry.addInterceptor(new HomeInterceptor()).addPathPatterns("需要拦截的路径").excludePathPatterns("需要排除的路径");
- 实现HandlerInterceptor接口
public class HomeInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object id = request.getSession().getAttribute("id");
if (id==null){
response.sendRedirect("/test");
return false;
}
return true;
}
/*
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
*/
}
- 配置需要拦截的内容
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new HomeInterceptor()).addPathPatterns("/home");
WebMvcConfigurer.super.addInterceptors(registry);
}
CORS跨域:addCorsMappings
config或注解
方式一:config
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("*")
.allowedOrigins("*")
.allowedHeaders("*");
WebMvcConfigurer.super.addCorsMappings(registry);
}
- addMapping:配置可以被跨域的路径,可以任意配置,可以具体到直接请求路径。
- allowedMethods:允许所有的请求方法访问该跨域资源服务器,如:POST、GET、PUT、DELETE等。
- allowedOrigins:允许所有的请求域名访问我们的跨域资源
- allowedHeaders:允许所有的请求header访问,可以自定义设置任意请求头信息
方式二:注解@CrossOrigin
@CrossOrigin
@PostMapping("/testCors")
@ResponseBody
private String testCors(){
return "CORS";
}
如何自定义请求头验证
拦截器:
将userSercice注入,查询结果与request.getHeader()是否匹配
public class CorsInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String authorization = request.getHeader("Authorization");
if (request.getMethod().equals("OPTIONS")) {
return true;
}
if (authorization==null){
return false;
}
return true;
}
}
预检请求、OPTIONS问题
向请求头添加自定义属性,实现token功能时,出现CORS跨域导致请求失败( has been blocked by CORS policy: … No ‘Access-Control-All)
if (request.getMethod().equals("OPTIONS")) {
return true;
}
过滤器:
Filter生命周期
- 程序启动调用Filter的init()方法(永远只调用一次);
- 程序停止调用Filter的destroy()方法(永远只调用一次);
- doFilter()方法每次的访问请求如果符合拦截条件都会调用(程序第一次运行,会在servlet调用init()方法以后调用;
- 不管第几次,都在调用doGet(),doPost()方法之前)。
注解
- 配置拦截器
@WebFilter(urlPatterns = "/*",displayName = "MyFilter")
@Order(1)
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("MyFilter:init");
}
@Override
public void destroy() {
System.out.println("MyFilter:destroy");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req=(HttpServletRequest) servletRequest;
System.out.println("MyFilter:url:"+req.getRequestURI());
//该方法执行后直接运行至下一个过滤器
filterChain.doFilter(servletRequest, servletResponse);
}
}
- 过滤器扫描
@ServletComponentScan
注解 | 说明 |
---|---|
@WebFilter | urlPatterns = “要过滤的路径”,displayName = “过滤器名” |
@Order(1) | 有多个过滤器时,值小的先执行 |
java配置
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean registFilter(){
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new MyFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.setName("Filter1");
registrationBean.setOrder(1);
return registrationBean;
}
}
使用场景
- 过滤敏感词汇(防止sql注入)
- 设置字符编码
- URL级别的权限访问控制
- 压缩响应信息
异常页面
- templates/error/404.html
- 使用:
response.sendError(404);