Skip to content

Commit

Permalink
feat(内核): 支持自定义请求处理器
Browse files Browse the repository at this point in the history
  • Loading branch information
qianmoQ committed Jan 19, 2025
1 parent 1b90d14 commit 04e3111
Show file tree
Hide file tree
Showing 9 changed files with 253 additions and 73 deletions.
42 changes: 42 additions & 0 deletions docs/content/getting-started/error.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
title: 自定义错误处理器
---

LightCall 支持自定义错误处理器。

!!! info "提示"

只需要实现 `ErrorHandler` 接口,然后实现 `canHandle` 和 `handle` 方法即可

!!!

```java
package org.devlive.lightcall.example.error;

import okhttp3.Request;
import okhttp3.Response;
import org.devlive.lightcall.error.ErrorHandler;

public class CustomErrorHandler
implements ErrorHandler
{
@Override
public int order() {
return 50; // 优先级高于默认处理器
}

@Override
public boolean canHandle(Request request, Response response, Exception exception) {
// 处理特定的业务异常
return response != null && response.code() == 400;
}

@Override
public Object handle(Request request, Response response, Exception exception, Class<?> returnType) throws Exception {
// 读取错误响应并转换为业务对象
String errorBody = response.body().string();
// 进行自定义处理
return null; // 或者返回默认值
}
}
```
39 changes: 39 additions & 0 deletions docs/content/getting-started/interceptor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: 自定义拦截器
---

LightCall 支持自定义拦截器,可以在请求和响应之前做一些操作

---

!!! info "提示"

只需要实现 `Interceptor` 接口,然后实现 `beforeRequest` 和 `afterResponse` 方法即可

!!!

```java
package org.devlive.lightcall.example.interceptor;

import okhttp3.Request;
import okhttp3.Response;
import org.devlive.lightcall.interceptor.Interceptor;

public class LoggingInterceptor
implements Interceptor
{
@Override
public Request beforeRequest(Request request)
{
System.out.println("Sending request: " + request.url());
return request;
}

@Override
public Response afterResponse(Response response)
{
System.out.println("Received response: " + response.code());
return response;
}
}
```
102 changes: 102 additions & 0 deletions docs/content/getting-started/processor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
title: 自定义请求处理器
---

LightCall 为开发者提供了一个强大的请求处理器机制,可以用于处理和修改请求的数据。可以自定义请求处理器,以便更好地适应不同的业务需求。

!!! info "提示"

只需要实现 `AbstractMethodProcessor` 抽象类,然后实现相应的方法即可。

!!!

我们以 `OptionsProcessor` 为例,实现一个自定义的请求处理器,用于处理 HTTP Options 请求。

### 添加注解

---

```java
package org.devlive.lightcall.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Options
{
String value() default "";
}
```

### 实现处理器

---

```java
package org.devlive.lightcall.processor;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import org.devlive.lightcall.RequestContext;
import org.devlive.lightcall.annotation.Options;
import org.devlive.lightcall.error.ErrorHandler;
import org.devlive.lightcall.interceptor.Interceptor;

import java.util.List;

@Slf4j
public class OptionsProcessor
extends AbstractMethodProcessor<Options>
{
private OptionsProcessor(OkHttpClient client, ObjectMapper objectMapper, List<Interceptor> interceptors, List<ErrorHandler> errorHandlers)
{
super(client, objectMapper, interceptors, errorHandlers);
}

public static OptionsProcessor create(OkHttpClient client, ObjectMapper objectMapper, List<Interceptor> interceptors, List<ErrorHandler> errorHandlers)
{
return new OptionsProcessor(client, objectMapper, interceptors, errorHandlers);
}

@Override
public Class<Options> getAnnotationType()
{
return Options.class;
}

@Override
protected String getPath(Options annotation)
{
return annotation.value();
}

@Override
protected Request buildRequest(HttpUrl url, RequestContext context)
{
if (context.getBody() != null) {
log.warn("Body is not allowed for OPTIONS method");
}

return context.getRequestBuilder()
.url(url)
.method("OPTIONS", null)
.build();
}
}
```

### 注册处理器

```java
LightCallConfig config = LightCallConfig.create("https://jsonplaceholder.typicode.com")
.addProcessor(OptionsProcessor.class);
```
41 changes: 2 additions & 39 deletions docs/content/usage/error.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,43 +25,6 @@ LightCallConfig config = LightCallConfig.create("https://jsonplaceholder.typicod
.addErrorHandler(new DefaultErrorHandler());
```

## 自定义拦截器
默认提供了

---

!!! info "提示"

只需要实现 `ErrorHandler` 接口,然后实现 `canHandle` 和 `handle` 方法即可

!!!

```java
package org.devlive.lightcall.example.error;

import okhttp3.Request;
import okhttp3.Response;
import org.devlive.lightcall.error.ErrorHandler;

public class CustomErrorHandler
implements ErrorHandler
{
@Override
public int order() {
return 50; // 优先级高于默认处理器
}

@Override
public boolean canHandle(Request request, Response response, Exception exception) {
// 处理特定的业务异常
return response != null && response.code() == 400;
}

@Override
public Object handle(Request request, Response response, Exception exception, Class<?> returnType) throws Exception {
// 读取错误响应并转换为业务对象
String errorBody = response.body().string();
// 进行自定义处理
return null; // 或者返回默认值
}
}
```
- DefaultErrorHandler
36 changes: 2 additions & 34 deletions docs/content/usage/interceptor.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,38 +25,6 @@ LightCallConfig config = LightCallConfig.create("https://jsonplaceholder.typicod
.addInterceptor(new LoggingInterceptor());
```

## 自定义拦截器
默认提供了

---

!!! info "提示"

只需要实现 `Interceptor` 接口,然后实现 `beforeRequest` 和 `afterResponse` 方法即可

!!!

```java
package org.devlive.lightcall.example.interceptor;

import okhttp3.Request;
import okhttp3.Response;
import org.devlive.lightcall.interceptor.Interceptor;

public class LoggingInterceptor
implements Interceptor
{
@Override
public Request beforeRequest(Request request)
{
System.out.println("Sending request: " + request.url());
return request;
}

@Override
public Response afterResponse(Response response)
{
System.out.println("Received response: " + response.code());
return response;
}
}
```
- LoggingInterceptor
3 changes: 3 additions & 0 deletions docs/pageforge.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ footer:
nav:
- 开始使用:
- /getting-started/get-started
- /getting-started/interceptor
- /getting-started/error
- /getting-started/processor
- 文档:
- /usage/interceptor
- /usage/error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.devlive.lightcall.error.DefaultErrorHandler;
import org.devlive.lightcall.error.ErrorHandler;
import org.devlive.lightcall.interceptor.Interceptor;
import org.devlive.lightcall.processor.MethodProcessor;

import java.util.ArrayList;
import java.util.Comparator;
Expand All @@ -17,6 +18,7 @@ public class LightCallConfig
private int readTimeout;
private List<Interceptor> interceptors = new ArrayList<>();
private List<ErrorHandler> errorHandlers = new ArrayList<>();
private final List<Class<? extends MethodProcessor<?>>> processorClasses = new ArrayList<>();

private LightCallConfig(String baseUrl)
{
Expand Down Expand Up @@ -64,4 +66,10 @@ public LightCallConfig addErrorHandler(ErrorHandler errorHandler)
this.getErrorHandlers().sort(Comparator.comparingInt(ErrorHandler::order));
return this;
}

public LightCallConfig addProcessor(Class<? extends MethodProcessor<?>> processorClass)
{
this.processorClasses.add(processorClass);
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.devlive.lightcall.processor;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import org.devlive.lightcall.error.ErrorHandler;
import org.devlive.lightcall.interceptor.Interceptor;

import java.lang.reflect.Method;
import java.util.List;

@Slf4j
public class ProcessorFactory
{
public static MethodProcessor<?> createProcessor(
Class<? extends MethodProcessor<?>> processorClass,
OkHttpClient client,
ObjectMapper objectMapper,
List<Interceptor> interceptors,
List<ErrorHandler> errorHandlers)
{
try {
// 查找符合条件的 create 方法
Method createMethod = processorClass.getMethod("create",
OkHttpClient.class,
ObjectMapper.class,
List.class,
List.class);

// 调用静态 create 方法创建处理器实例
return (MethodProcessor<?>) createMethod.invoke(null,
client,
objectMapper,
interceptors,
errorHandlers);
}
catch (Exception e) {
log.error("Failed to create processor instance for class: {}", processorClass.getName(), e);
throw new IllegalArgumentException("Failed to create processor instance", e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.devlive.lightcall.processor.OptionsProcessor;
import org.devlive.lightcall.processor.PatchProcessor;
import org.devlive.lightcall.processor.PostProcessor;
import org.devlive.lightcall.processor.ProcessorFactory;
import org.devlive.lightcall.processor.PutProcessor;

import java.lang.annotation.Annotation;
Expand Down Expand Up @@ -50,6 +51,18 @@ public LightCallProxy(LightCallConfig config)
registerProcessor(DeleteProcessor.create(client, objectMapper, config.getInterceptors(), config.getErrorHandlers()));
registerProcessor(PatchProcessor.create(client, objectMapper, config.getInterceptors(), config.getErrorHandlers()));
registerProcessor(OptionsProcessor.create(client, objectMapper, config.getInterceptors(), config.getErrorHandlers()));

// 注册自定义处理器
for (Class<? extends MethodProcessor<?>> processorClass : config.getProcessorClasses()) {
MethodProcessor<?> processor = ProcessorFactory.createProcessor(
processorClass,
client,
objectMapper,
config.getInterceptors(),
config.getErrorHandlers()
);
registerProcessor(processor);
}
}

public <A extends Annotation> void registerProcessor(MethodProcessor<A> processor)
Expand Down

0 comments on commit 04e3111

Please sign in to comment.