如何設定Custom Injection
場景:
client發送get request,會在header帶一個userId,server會根據userId去資料庫查詢相關user.
例如:1
curl -H 'userId: 89ce5a60-a88f-11e5-a837-0800200c9a66' http://localhost:8080/user
PS:正規的做法是把userId放在uri path中,這邊只是模擬從header抓取資料進行處理,之後可以透過annotation方式將結果放到resource
定義annotation
1
2
3
4(RetentionPolicy.RUNTIME)
({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
public UserParam {
}定義ValueFactoryProvider
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//lombok annotation 4j
public final class UserParamValueFactoryProvider extends AbstractValueFactoryProvider {
public static final class InjectionResolver extends ParamInjectionResolver<UserParam> {
public InjectionResolver() {
super(UserParamValueFactoryProvider.class);
}
}
public UserParamValueFactoryProvider(MultivaluedParameterExtractorProvider mpep, ServiceLocator injector) {
super(mpep, injector, Parameter.Source.UNKNOWN);
}
public AbstractContainerRequestValueFactory<?> createValueFactory(Parameter parameter) {
Class<?> classType = parameter.getRawType();
if (classType == null || (!classType.equals(User.class))) {
log.warn("UserParam annotation was not placed on correct object type; Injection might not work correctly!");
return null;
}
return new AbstractContainerRequestValueFactory<User> (){
private ResourceContext context;
private Repo repo;
public User provide() {
final ContainerRequestContext context = this.context.getResource(ContainerRequestContext.class);
final UUID userId = UUID.fromString(context.getHeaderString("userId"));
return repo.getUser(userId);
}
};
}
}
Repo1
2
3public interface Repo {
User getUser(UUID uuid);
}
RepoFactory1
2
3
4
5
6
7
8
9
10
11public class RepoFactory implements Factory<Repo> {
public Repo provide() {
return new DummyRepo();
}
public void dispose(Repo instance) {
}
}
bind UserParamValueFactoryProvider
bind(UserParamValueFactoryProvider.class).to(ValueFactoryProvider.class).in(Singleton.class); 1
2bind(UserParamValueFactoryProvider.InjectionResolver.class).to(new TypeLiteral<InjectionResolver<UserParam>>() {}).in(Singleton.class);
bindFactory(RepoFactory.class).to(Repo.class).in(Singleton.class);透過annotation取得User
1
2
3
4
5
6
"Return user data", response = User.class) (value =
public Response user(@NotNull @Valid @UserParam User user) {
return Response.ok(user, MediaType.APPLICATION_JSON)
.build();
}
如何設定Swagger API
因為是透過ResourceConfig
去設定JAX-RS,所以只要將以下程式碼加入到ResourceConfig
就完成Swagger API設定1
2
3
4
5
6
7
8
9
10
11
12register(ApiListingResourceJSON.class);
register(SwaggerSerializers.class);
BeanConfig beanConfig = new BeanConfig();
beanConfig.setVersion("1.0.1");
beanConfig.setResourcePackage("rest"); // replace with your packages
beanConfig.setBasePath("http://localhost:8080/jersey-starterkit/");
beanConfig.setDescription("My RESTful resources");
beanConfig.setTitle("My RESTful API");
beanConfig.setFilterClass(ApiAuthorizationFilterImpl.class.getName());
beanConfig.setPrettyPrint(true);
beanConfig.setScan(true);
假如想要用apiKey限制使用者存取swagger.json
,可以繼承SwaggerSpecFilter
,在beanConfig.setFilterClass
設定路徑即可.
呼叫swagger.json:1
curl http://localhost:8080/swagger.json