mirror of
https://github.com/Estom/notes.git
synced 2026-04-14 10:21:08 +08:00
spring&java rest
This commit is contained in:
@@ -515,7 +515,7 @@ F3选中文件/文件夹/代码行,添加/取消书签
|
||||
* 缩进 tap
|
||||
* 推缩进 shift tap
|
||||
|
||||
### 浏览操作
|
||||
### Navigate浏览操作
|
||||
> 用于阅读代码,实现快速的跳转和导航。
|
||||
> edit中的find是基于文本内容的搜索。
|
||||
> navigate中的浏览功能是基于java语义的分析。例如可以检索class、method这种需要语义翻译的东西。
|
||||
|
||||
@@ -13,10 +13,11 @@ public @interface 注解名称{
|
||||
```
|
||||
|
||||
### 分类
|
||||
根据其定义者的角色可以分为以下三种:
|
||||
1. 标准注解:JDK内置的注解
|
||||
2. 自定义注解:用户自定义的注解
|
||||
3. 第三方框架提供的注解
|
||||
根据其定义者的角色可以分为以下四种种:
|
||||
1. 元注解:修饰注解的注解
|
||||
2. 标准注解:JDK内置的注解
|
||||
3. 框架注解:第三方框架提供的注解
|
||||
4. 自定义注解:用户自定义的注解
|
||||
|
||||
|
||||
> 还可以根据其出现的位置分为类、方法、变量和形参的注解。也可以其作用范围分为标准注解、元注解、自定义注解。
|
||||
@@ -299,14 +300,104 @@ public class Demo {
|
||||
一种信息性注解类型,用于指示接口类型声明旨在成为 Java 语言规范定义的功能接口。从概念上讲,函数式接口只有一个抽象方法。由于默认方法有一个实现,它们不是抽象的。如果接口声明了一个覆盖java.lang.Object的公共方法之一的抽象方法,这也不会计入接口的抽象方法计数,因为接口的任何实现都将具有来自java.lang.Object或其他地方的实现(接口的实现是类,所有类的父类都是Object)。
|
||||
请注意,函数式接口的实例可以使用 lambda 表达式、方法引用或构造函数引用来创建。
|
||||
如果使用此注解类型对类型进行注解,则编译器需要生成错误消息,除非:
|
||||
该类型是接口类型,而不是注解类型、枚举或类。
|
||||
带注解的类型满足功能接口的要求。
|
||||
* 该类型是接口类型,而不是注解类型、枚举或类。
|
||||
* 带注解的类型满足功能接口的要求。
|
||||
|
||||
但是,无论接口声明中是否存在FunctionalInterface注释,编译器都会将满足功能接口定义的任何接口视为功能接口。
|
||||
|
||||
|
||||
|
||||
在学习Lambda表达式时,我们了解过函数式接口(接口中只有个一个抽象方法可以存在多个默认方法或多个static方法)。
|
||||
|
||||
@FunctionalInterface作用就是用来指定某一个接口必须是函数式接口的,所以@FunctionalInterface只能修饰接口。
|
||||
|
||||
|
||||
## 4 Spring框架下一个注解的实现
|
||||
> 定义注解、使用注解、实现注解。和定义接口、使用接口、实现接口。与OpenApi中定义服务、使用服务、实现服务。具有相同的含义。
|
||||
|
||||
|
||||
### 登录校验——定义注解
|
||||
模拟是否需要进行登录校验;如果方法中加上了@LoginRequired注解表示方法需要登录校验,如果没加则不需要。定义一个
|
||||
```java
|
||||
@LoginRequired注解
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public@interface LoginRequired {
|
||||
|
||||
}
|
||||
```
|
||||
### 登录校验——使用注解
|
||||
|
||||
定义两个简单接口,其中一个添加@LoginRequired注解表示需要登录校验
|
||||
```java
|
||||
@RestController
|
||||
public class UserController {
|
||||
@GetMapping("/login1")
|
||||
public TransDTO login1(){
|
||||
return new TransDTO<>().withMessage("访问login1成功").withCode(HttpStatus.OK.value());
|
||||
}
|
||||
|
||||
@LoginRequired
|
||||
@GetMapping("/login2")
|
||||
public TransDTO login2(){
|
||||
return new TransDTO<>().withMessage("访问login2成功").withCode(HttpStatus.OK.value());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 登录校验——实现注解
|
||||
|
||||
自定义拦截器。通过拦截器和反射,实现注解的处理逻辑。
|
||||
```java
|
||||
@Configuration
|
||||
public class MyInterceptor implements HandlerInterceptor {
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
System.out.println("访问了过滤器!");
|
||||
HandlerMethod handlerMethod = (HandlerMethod) handler;
|
||||
LoginRequired annotation = handlerMethod.getMethod().getAnnotation(LoginRequired.class);
|
||||
if(annotation != null){
|
||||
//全局异常处理会进行处理
|
||||
throw new BusinessException("访问失败,您没有权限访问!");
|
||||
}
|
||||
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 {
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
配置拦截路径
|
||||
```java
|
||||
@Configuration
|
||||
public class InterceptorTrainConfigurer implements WebMvcConfigurer {
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
全局异常处理
|
||||
```java
|
||||
@RestControllerAdvice
|
||||
public class MyExceptionAdvice {
|
||||
@ExceptionHandler(Exception.class)
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public TransDTO handleException(HttpServletRequest request,Exception e){
|
||||
e.printStackTrace();
|
||||
return new TransDTO().withCode(500).withSuccess(false).withMessage(e.getMessage());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
自定义注解的场景有很多,比如登录、权限拦截、日志、以及各种框架。java注解对于性能有较大的影响,但可用于软件的架构设计,实现动态加载,对于分解复杂业务有帮助。
|
||||
|
||||
### Spring框架下的另一个实现
|
||||
|
||||
|
||||
236
Java基础教程/Java语言基础/18 Rest接口.md
Normal file
236
Java基础教程/Java语言基础/18 Rest接口.md
Normal file
@@ -0,0 +1,236 @@
|
||||
## 1 概述
|
||||
|
||||
### 基本概念
|
||||
|
||||
java.ws.rs是jax-rs规范中定义的包名。jax-rs全称Java API for RESTful Services。jax-rs规范目前版本是2.0规范文档
|
||||
|
||||
jax-rs中定义了
|
||||
* 一组启动方式 (以jee作为http容器 还是配合servlet作为http容器)
|
||||
* 一组注解@GET, @POST, @DELETE, @PUT, @Consumes … 通过 POJO Resource类 提供Rest服务
|
||||
|
||||
### 实现框架
|
||||
|
||||
* Apache CXF开源的Web服务框架
|
||||
* Jersey 由Sun提供的JAX-RS的参考实现
|
||||
* RESTEasy JBoss的实现
|
||||
* Restlet 由Jerome Louvel和Dave Pawson开发 是最早的REST框架 先于JAX-RS出现
|
||||
* Apache Wink 一个Apache软件基金会孵化器中的项目 其服务模块实现JAX-RS规范
|
||||
|
||||
## 2 注解
|
||||
### @Path
|
||||
注解位置 类注解 方法注解
|
||||
|
||||
标注class时 表明该类是个资源类 凡是资源类必须使用该注解
|
||||
|
||||
标注method时 表示具体的请求资源的路径
|
||||
|
||||
### @GET @POST @PUT @DELETE
|
||||
|
||||
注解位置 方法注解
|
||||
|
||||
指明接收HTTP请求的方式属于get,post,put,delete中的哪一种 具体指定请求方式 是由客户端发起请求时指定
|
||||
|
||||
### @Consumes
|
||||
注解位置 方法注解
|
||||
|
||||
指定HTTP请求的MIME类型 默认是*/* 表示任意的MIME类型 该注解支持多个值设定 可以使用MediaType来指定MIME类型
|
||||
```
|
||||
MediaType的类型大致有
|
||||
|
||||
application/xml
|
||||
application/atom+xml
|
||||
application/json
|
||||
application/svg+xml
|
||||
application/x-www-form-urlencoded
|
||||
application/octet-stream
|
||||
multipart/form-data
|
||||
text/plain
|
||||
text/xml
|
||||
text/html
|
||||
```
|
||||
```java
|
||||
@Path("{username"})
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
public User getUser(@PathParam("username") String userName) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### @Produces
|
||||
|
||||
注解位置 方法注解
|
||||
|
||||
指定HTTP响应的MIME类型 默认是*/* 表示任意的MIME类型 同Consumes使用MediaType来指定MIME类型
|
||||
```
|
||||
@Path("{username"})
|
||||
@Consumes({MediaType.APPLICATION_JSON})
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public User getUser(@PathParam("username") String userName) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### @PathParam
|
||||
|
||||
注解位置 参数注解
|
||||
|
||||
配合@Path进行使用 可以获取URI中指定规则的参数
|
||||
|
||||
```
|
||||
@GET
|
||||
@Path("{username"})
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public User getUser(@PathParam("username") String userName) {
|
||||
...
|
||||
}
|
||||
// 浏览器请求http://ip:port/user/lilei时 userName值为lilei
|
||||
```
|
||||
|
||||
### @QueryParam
|
||||
|
||||
注解位置 参数注解
|
||||
|
||||
用于获取GET请求中的查询参数 实际上是url拼接在?后面的参数
|
||||
```
|
||||
@GET
|
||||
@Path("/user")
|
||||
@Produces("text/plain")
|
||||
public User getUser(@QueryParam("name") String name,
|
||||
@QueryParam("age") int age) {
|
||||
...
|
||||
}
|
||||
|
||||
// 浏览器请求http://ip:port/user?name=lilei&age=18时 name值为lilei age值为18 如需要为参数设置默认值 可以使用@DefaultValue
|
||||
```
|
||||
### @FormParam
|
||||
|
||||
注解位置 参数注解
|
||||
|
||||
用于获取POST请求且以form(MIME类型为application/x-www-form-urlencoded)方式提交的表单的参数
|
||||
```
|
||||
@POST
|
||||
@Consumes("application/x-www-form-urlencoded")
|
||||
public void post(@FormParam("name") String name) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### @FormDataParam
|
||||
注解位置 参数注解
|
||||
|
||||
用于获取POST请求且以form(MIME类型为multipart/form-data)方式提交的表单的参数 通常是在上传文件的时候
|
||||
|
||||
### @HeaderParam
|
||||
|
||||
注解位置 参数注解
|
||||
|
||||
用于获取HTTP请求头中的参数值
|
||||
```
|
||||
@GET
|
||||
@Path("/user/get")
|
||||
public Response getUser(@HeaderParam("user-agent") String userAgent) {
|
||||
...
|
||||
}
|
||||
// 这里获取user-agent的值
|
||||
```
|
||||
### @CookieParam
|
||||
|
||||
注解位置 参数注解
|
||||
|
||||
用于获取HTTP请求cookie中的参数值
|
||||
```
|
||||
@GET
|
||||
public String callService(@CookieParam("sessionid") String sessionid) {
|
||||
...
|
||||
}
|
||||
```
|
||||
### @MatrixParam
|
||||
注解位置 参数注解
|
||||
|
||||
可以用来绑定包含多个property (属性)=value(值) 方法参数表达式 用于获取请求URL参数中的键值对 必须使用’;'作为键值对分隔符
|
||||
```
|
||||
@Path("/books")
|
||||
public class BookService {
|
||||
@GET
|
||||
@Path("{year}")
|
||||
public Response getBooks(@PathParam("year") String year,
|
||||
@MatrixParam("author") String author,
|
||||
@MatrixParam("country") String country) {
|
||||
...
|
||||
}
|
||||
}
|
||||
// 请求1 "/books/2012/" 解析结果为 年份 2012 作者 null 国家 null
|
||||
// 请求2 "/books/2012;author=andih" 解析结果为 年份 2012 作者 andih 国家 null
|
||||
```
|
||||
|
||||
> 注意MatrixParam与QueryParam的区别
|
||||
> QueryParam请求url的格式为 url?key1=value1&key2=value2&…
|
||||
> MatrixParam请求url的格式为 url;key1=value1;key2=value2;…
|
||||
|
||||
### @DefaultValue
|
||||
|
||||
配合前面的参数注解等使用 用来设置默认值 如果请求指定的参数中没有值 通过该注解给定默认值
|
||||
|
||||
注解位置 参数注解
|
||||
```
|
||||
@POST
|
||||
@Path("/user/add")
|
||||
@Consumes({MediaType.APPLICATION_FORM_URLENCODED})
|
||||
@Produces({MediaType.APPLICATION_JSON})
|
||||
public Response addUser(@FormParam("username") String userName, @DefaultValue("0") @FormParam("age") int age, @DefaultValue("1") @FormParam("sex") int sex){
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
> 注意 DefaultValue指定的值在解析过程中出错时(@DefaultValue(“test”) @QueryParam(“age”) int age) 将返回404错误
|
||||
|
||||
### @BeanParam
|
||||
注解位置 参数注解
|
||||
|
||||
如果传递的较多 使用@FormParam等参数注解一个一个的接收每个参数可能显得太臃肿 可以通过Bean方式接收自定义的Bean 在自定义的Bean中字段使用@FormParam等参数注解 只需定义一个参数接收即可
|
||||
```
|
||||
public class MyBean {
|
||||
@FormParam("myData")
|
||||
private String data;
|
||||
@HeaderParam("myHeader")
|
||||
private String header;
|
||||
@PathParam("id")
|
||||
public void setResourceId(String id) {...}
|
||||
...
|
||||
}
|
||||
|
||||
@Path("myresources")
|
||||
public class MyResources {
|
||||
@POST
|
||||
@Path("{id}")
|
||||
public void post(@BeanParam MyBean myBean) {
|
||||
...
|
||||
}
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### @Context
|
||||
注解位置 属性注解 参数注解
|
||||
|
||||
用来用来解析上下文参数 和Spring中的AutoWired效果类似 通过该注解可以获取ServletConfig ServletContext HttpServletRequest HttpServletResponse和HttpHeaders等信息
|
||||
```
|
||||
@Path("/user")
|
||||
publicclass Resource {
|
||||
@Context
|
||||
HttpServletRequest req;
|
||||
@Context
|
||||
ServletConfig servletConfig;
|
||||
@Context
|
||||
ServletContext servletContext;
|
||||
|
||||
@GET
|
||||
public String get(@Context HttpHeaders hh) {
|
||||
MultivaluedMap<String, String> headerParams = hh.getRequestHeaders();
|
||||
Map<String, Cookie> pathParams = hh.getCookies();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### @Encoded
|
||||
禁止解码 客户端发送的参数是什么样 服务器就原样接收
|
||||
36
Spring/Spring5/07 事件监听模型.md
Normal file
36
Spring/Spring5/07 事件监听模型.md
Normal file
@@ -0,0 +1,36 @@
|
||||
## 1 原理说明
|
||||
|
||||
### 事件驱动模型和观察者模式
|
||||
一下名称具有相同的含义,都是观察着模式在不同场景下的实现。
|
||||
* Spring的事件驱动模型
|
||||
* 设计模式中的观察者模式
|
||||
* jdk中的observable和observer
|
||||
* ui中事件监听机制
|
||||
* 注册中心和消息队列的订阅发布机制
|
||||
|
||||
先是一种对象间的一对多的关系;最简单的如交通信号灯,信号灯是目标(一方),行人注视着信号灯(多方)。当目标发送改变(发布),观察者(订阅者)就可以接收到改变。 观察者如何处理(如行人如何走,是快走/慢走/不走,目标不会管的), 目标无需干涉;所以就松散耦合了它们之间的关系。
|
||||
|
||||
|
||||
### Spring中实现
|
||||

|
||||
|
||||
|
||||
|
||||
### 类图关系
|
||||
* 事件
|
||||
|
||||

|
||||
|
||||
|
||||
* 发布(动作)
|
||||
* ApplicationContext 接口继承了 ApplicationEventPublisher,并在 AbstractApplicationContext 实现了具体代码,实际执行是委托给ApplicationEventMulticaster(可以认为是多播)
|
||||
|
||||

|
||||
|
||||
|
||||
* 监听
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
BIN
Spring/Spring5/image/2022-10-18-12-06-37.png
Normal file
BIN
Spring/Spring5/image/2022-10-18-12-06-37.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 179 KiB |
BIN
Spring/Spring5/image/2022-10-18-12-07-26.png
Normal file
BIN
Spring/Spring5/image/2022-10-18-12-07-26.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 117 KiB |
BIN
Spring/Spring5/image/2022-10-18-12-08-25.png
Normal file
BIN
Spring/Spring5/image/2022-10-18-12-08-25.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
BIN
Spring/Spring5/image/2022-10-18-12-08-47.png
Normal file
BIN
Spring/Spring5/image/2022-10-18-12-08-47.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 63 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 258 KiB |
@@ -9,6 +9,7 @@
|
||||
> * 在socket网络编程、IO编程中(netty、springWebFlux、sofarpc)就是Reactor模式
|
||||
> * 在操作系统中就是IO多路复用的一种策略
|
||||
> * 在UI框架中就是Listener,事件监听机制和响应机制
|
||||
> * 在Spring框架中也有事件监听模型。
|
||||
> * 在web网站开发中,被称为响应式编程。
|
||||
> * 在微服务中就是注册中心的发布订阅过程
|
||||
> * 在消息中间件中就是发布订阅模式。
|
||||
|
||||
Reference in New Issue
Block a user