使用 Dropwizard 的 Jersey 过滤器、拦截器和 MessageBodyReader
Jersey Filters, Intercepter and MessageBodyReader using Dropwizard
我正在探索 dropwizard 项目中的球衣过滤器。尝试探索如何在每个端点的公共位置拦截传入请求,以对请求对象(即路径参数、查询参数或请求主体)执行一些基本检查
我正在尝试以下接口
- 过滤器
- ContainerRequestFilter
- Reader拦截器
- 消息正文Reader
我能够实现 Filter 和 ContainerRequest Filter,并看到这些实现中的代码得到执行。但是我的 ReaderInterceptor 和 MessageBodyReader 没有被执行。
这是我的代码
PersonResource.java
@Path("person")
@Api("Person Resource")
@Log
@MyAnnotation
public class PersonResource {
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Person getPerson(@PathParam("id") String id){
log.info("Requesting Person information...");
return new Person(id,"Person Name");
}
}
过滤器实施
package com.practice.rigz.interceptor;
import lombok.extern.java.Log;
import javax.servlet.*;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
@Provider
@Log
public class RequestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("INIT...");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(servletRequest,servletResponse);
log.info("DO FILTER...");
}
@Override
public void destroy() {
log.info("DESTROY...");
}
}
ContainerRequestFilter 实现
package com.practice.rigz.interceptor;
import com.practice.rigz.annotations.MyAnnotation;
import lombok.extern.java.Log;
import javax.ws.rs.container.*;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.util.List;
@Provider
@Log
@MyAnnotation
public class RequestContainerRequestFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
log.info(String.join("," ,requestContext.getPropertyNames()));
List<String> partnerId = requestContext.getUriInfo().getPathParameters().get("id");
if (partnerId.get(0).equals("1")){
throw new IllegalAccessError();
}
log.info("CONTAINER REQUEST FILTER...");
}
}
Reader 拦截器实现
package com.practice.rigz.interceptor;
import com.practice.rigz.annotations.MyAnnotation;
import lombok.extern.java.Log;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.ReaderInterceptorContext;
import java.io.IOException;
@Log
@MyAnnotation
@Provider
public class RequestReaderInterceptor implements ReaderInterceptor {
@Override
public Object aroundReadFrom(ReaderInterceptorContext readerInterceptorContext) throws IOException, WebApplicationException {
log.info("INTERCEPTOR");
return readerInterceptorContext.proceed();
}
}
MessageBodyReader 实现
package com.practice.rigz.interceptor;
import com.practice.rigz.annotations.MyAnnotation;
import lombok.extern.java.Log;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
@Provider
@Log
@MyAnnotation
public class RequestMessageBodyReader implements MessageBodyReader {
@Override
public boolean isReadable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) {
log.info("IS READABLE...");
return false;
}
@Override
public Object readFrom(Class aClass, Type type, Annotation[] annotations, MediaType mediaType, MultivaluedMap multivaluedMap, InputStream inputStream) throws IOException, WebApplicationException {
log.info("READ FROM ...");
return null;
}
}
在我的 Dropwizard 应用程序 运行 方法中,我注册了以下所有组件
private void registerFilters(Environment environment) {
environment.servlets().addFilter("request-filter", RequestFilter.class)
.addMappingForUrlPatterns(java.util.EnumSet.allOf(javax.servlet.DispatcherType.class), true, "/*");
environment.jersey().register(RequestMessageBodyReader.class);
environment.jersey().register(RequestReaderInterceptor.class);
environment.jersey().register(RequestContainerRequestFilter.class);
}
知道为什么我的 MessageBodyReader 和 ReaderInterceptor 不起作用吗?
我正在使用 OpenJDK11 和 Dropwizard 1.3.16
以下是我的程序在尝试到达终点时的输出
信息 [2019-11-23 16:29:07,016] com.practice.rigz.interceptor.RequestContainerRequestFilter: org.glassfish.jersey.message.internal.TracingLogger
信息 [2019-11-23 16:29:07,019] com.practice.rigz.interceptor.RequestContainerRequestFilter:容器请求过滤器...
INFO [2019-11-23 16:29:07,045] com.practice.rigz.resources.PersonResource: 请求人员信息...
信息 [2019-11-23 16:29:07,119] com.practice.rigz.interceptor.RequestFilter:进行过滤...
0:0:0:0:0:0:0:1 - - [23/Nov/2019:16:29:07 +0000] "GET /person/1111 HTTP/1.1" 200 34 "http://localhost:8080/swagger" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Safari/605.1.15" 242
我找到了问题的原因。我需要的东西很少
- 拦截器适用于 POST 方法。
- MessageBodyReader 也适用于 Post 方法,因为只有 POST 可以有正文。我总是从 isReadableMethod 中 returning 错误。如果我希望我的实现处理特定类型的请求,则此方法应该 return true。将实施更改为以下
package com.practice.rigz.interceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import com.practice.rigz.annotations.MyAnnotation;
import com.practice.rigz.model.Person;
import lombok.extern.java.Log;
import org.hibernate.validator.internal.util.privilegedactions.NewJaxbContext;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Link;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
@Provider
@Log
@MyAnnotation
public class RequestMessageBodyReader implements MessageBodyReader<Person> {
@Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
log.info("IS READABLE...");
return type == Person.class;
}
@Override
public Person readFrom(Class<Person> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {
ObjectMapper mapper = new ObjectMapper();
Person person = mapper.readValue(entityStream, Person.class);
log.info("READ FROM...");
return person;
}
}
我正在探索 dropwizard 项目中的球衣过滤器。尝试探索如何在每个端点的公共位置拦截传入请求,以对请求对象(即路径参数、查询参数或请求主体)执行一些基本检查 我正在尝试以下接口
- 过滤器
- ContainerRequestFilter
- Reader拦截器
- 消息正文Reader
我能够实现 Filter 和 ContainerRequest Filter,并看到这些实现中的代码得到执行。但是我的 ReaderInterceptor 和 MessageBodyReader 没有被执行。
这是我的代码
PersonResource.java
@Path("person")
@Api("Person Resource")
@Log
@MyAnnotation
public class PersonResource {
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Person getPerson(@PathParam("id") String id){
log.info("Requesting Person information...");
return new Person(id,"Person Name");
}
}
过滤器实施
package com.practice.rigz.interceptor;
import lombok.extern.java.Log;
import javax.servlet.*;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
@Provider
@Log
public class RequestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("INIT...");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(servletRequest,servletResponse);
log.info("DO FILTER...");
}
@Override
public void destroy() {
log.info("DESTROY...");
}
}
ContainerRequestFilter 实现
package com.practice.rigz.interceptor;
import com.practice.rigz.annotations.MyAnnotation;
import lombok.extern.java.Log;
import javax.ws.rs.container.*;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.util.List;
@Provider
@Log
@MyAnnotation
public class RequestContainerRequestFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
log.info(String.join("," ,requestContext.getPropertyNames()));
List<String> partnerId = requestContext.getUriInfo().getPathParameters().get("id");
if (partnerId.get(0).equals("1")){
throw new IllegalAccessError();
}
log.info("CONTAINER REQUEST FILTER...");
}
}
Reader 拦截器实现
package com.practice.rigz.interceptor;
import com.practice.rigz.annotations.MyAnnotation;
import lombok.extern.java.Log;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.ReaderInterceptorContext;
import java.io.IOException;
@Log
@MyAnnotation
@Provider
public class RequestReaderInterceptor implements ReaderInterceptor {
@Override
public Object aroundReadFrom(ReaderInterceptorContext readerInterceptorContext) throws IOException, WebApplicationException {
log.info("INTERCEPTOR");
return readerInterceptorContext.proceed();
}
}
MessageBodyReader 实现
package com.practice.rigz.interceptor;
import com.practice.rigz.annotations.MyAnnotation;
import lombok.extern.java.Log;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
@Provider
@Log
@MyAnnotation
public class RequestMessageBodyReader implements MessageBodyReader {
@Override
public boolean isReadable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) {
log.info("IS READABLE...");
return false;
}
@Override
public Object readFrom(Class aClass, Type type, Annotation[] annotations, MediaType mediaType, MultivaluedMap multivaluedMap, InputStream inputStream) throws IOException, WebApplicationException {
log.info("READ FROM ...");
return null;
}
}
在我的 Dropwizard 应用程序 运行 方法中,我注册了以下所有组件
private void registerFilters(Environment environment) {
environment.servlets().addFilter("request-filter", RequestFilter.class)
.addMappingForUrlPatterns(java.util.EnumSet.allOf(javax.servlet.DispatcherType.class), true, "/*");
environment.jersey().register(RequestMessageBodyReader.class);
environment.jersey().register(RequestReaderInterceptor.class);
environment.jersey().register(RequestContainerRequestFilter.class);
}
知道为什么我的 MessageBodyReader 和 ReaderInterceptor 不起作用吗? 我正在使用 OpenJDK11 和 Dropwizard 1.3.16
以下是我的程序在尝试到达终点时的输出
信息 [2019-11-23 16:29:07,016] com.practice.rigz.interceptor.RequestContainerRequestFilter: org.glassfish.jersey.message.internal.TracingLogger 信息 [2019-11-23 16:29:07,019] com.practice.rigz.interceptor.RequestContainerRequestFilter:容器请求过滤器... INFO [2019-11-23 16:29:07,045] com.practice.rigz.resources.PersonResource: 请求人员信息... 信息 [2019-11-23 16:29:07,119] com.practice.rigz.interceptor.RequestFilter:进行过滤... 0:0:0:0:0:0:0:1 - - [23/Nov/2019:16:29:07 +0000] "GET /person/1111 HTTP/1.1" 200 34 "http://localhost:8080/swagger" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Safari/605.1.15" 242
我找到了问题的原因。我需要的东西很少
- 拦截器适用于 POST 方法。
- MessageBodyReader 也适用于 Post 方法,因为只有 POST 可以有正文。我总是从 isReadableMethod 中 returning 错误。如果我希望我的实现处理特定类型的请求,则此方法应该 return true。将实施更改为以下
package com.practice.rigz.interceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import com.practice.rigz.annotations.MyAnnotation;
import com.practice.rigz.model.Person;
import lombok.extern.java.Log;
import org.hibernate.validator.internal.util.privilegedactions.NewJaxbContext;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Link;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
@Provider
@Log
@MyAnnotation
public class RequestMessageBodyReader implements MessageBodyReader<Person> {
@Override
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
log.info("IS READABLE...");
return type == Person.class;
}
@Override
public Person readFrom(Class<Person> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {
ObjectMapper mapper = new ObjectMapper();
Person person = mapper.readValue(entityStream, Person.class);
log.info("READ FROM...");
return person;
}
}