【问题标题】:Jersey jackson disable filterprovider泽西杰克逊禁用过滤器提供程序
【发布时间】:2015-09-13 18:45:09
【问题描述】:

最近我开始使用 SecurityEntityFilteringFeature。在球衣环境中放置下面的代码。

environment.jersey().register(SecurityEntityFilteringFeature.class);
environment.jersey().register(JacksonFeature.class);

我所有返回自定义对象或映射的资源类都开始抛出异常

com.fasterxml.jackson.databind.JsonMappingException: Can not resolve PropertyFilter with id 'uk.co.froot.demo.openid.resources.PublicOAuthResource$1'; no FilterProvider configured
at com.fasterxml.jackson.databind.ser.std.StdSerializer.findPropertyFilter(StdSerializer.java:285)
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:459)
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:29)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:129)
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:851)
at com.fasterxml.jackson.jaxrs.base.ProviderBase.writeTo(ProviderBase.java:648)
at org.glassfish.jersey.jackson.internal.FilteringJacksonJaxbJsonProvider.writeTo(FilteringJacksonJaxbJsonProvider.java:135)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:106)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:86)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1128)
at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:664)
at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:421)
at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:411)

【问题讨论】:

  • 我也有同样的问题。点击here另一种解决方案。

标签: java filter jersey jackson dropwizard


【解决方案1】:

由于没有适合我的解决方案,我不得不创建自己的过滤器。 其中使用 Java 安全注释。根据我的自定义要求,我必须在请求中为用户设置角色。并且用于过滤器

package com.buzzy.jersey.provider;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.annotation.security.DenyAll;
import javax.annotation.security.RolesAllowed;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;
import javax.ws.rs.ext.Provider;

import org.apache.commons.lang3.ClassUtils;

import uk.co.froot.demo.openid.model.security.Authority;

/**
 * @author Sanjay Patel (sanjaypatel at ibm.com)
 */
@Provider
public class FilterResponseFilter implements ContainerResponseFilter {

@Context
private ResourceInfo resourceInfo;
@Context
private HttpServletRequest request;

@Override
public void filter(ContainerRequestContext requestContext,
        ContainerResponseContext responseContext) throws IOException {
    if(responseContext.getEntity()!=null)
        filterObject(((Authority)request.getAttribute("hasAuthority")),responseContext.getEntity());
}

private void filterObject(Authority auth, Object entity) {
    if(entity instanceof List) {
        for(Object  obj: (List)entity)filterObject(auth,obj);
    }
    else if(entity instanceof Map) {
        for(Object obj : ((Map)entity).values()) filterObject(auth,obj);
    }
    else if(entity instanceof Object[]){
        for(Object  obj: (Object[])entity)filterObject(auth,obj);
    }
    else if(!ClassUtils.isPrimitiveOrWrapper(entity.getClass()) && !(entity instanceof String)){
        try{
            for(Method method:entity.getClass().getMethods()){
                if(method.getName().startsWith("get") && !method.getName().equals("getClass")){
                    String fieldName = method.getName().substring(3);
                    fieldName=fieldName.substring(0, 1).toLowerCase()+fieldName.substring(1, fieldName.length());
                    Field field = entity.getClass().getDeclaredField(fieldName);
                    field.setAccessible(true);
                    if(method.getAnnotation(DenyAll.class)!=null ){
                        field.set(entity, null);
                    }
                    if(method.getAnnotation(RolesAllowed.class)!=null){
                        if(auth!=null && Arrays.asList(method.getAnnotation(RolesAllowed.class).value()).contains(auth.name())){
                            if(!ClassUtils.isPrimitiveOrWrapper(method.getReturnType()) && !(entity instanceof String)){
                                filterObject(auth, field.get(entity));
                            }
                        }
                        else{
                            field.set(entity, null);
                        }
                    }
                }
            }
        }
        catch(Exception e){
            e.printStackTrace();
        }
    }
}
}

并注册它 dropwizard/jersey。

environment.jersey().register(FilterResponseFilter.class);

【讨论】:

  • 谢谢,桑杰!这个过滤器代码对类似的问题帮助很大。
  • 上述方法是手动实现实体过滤,以脏的方式,没有解决“未配置FilterProvider”的问题,也没有解决“禁用过滤器提供程序”的问题。不幸的是,我可以确认,经过大量尝试从 Jersey 2.23 启动并运行 SecurityEntityFilteringFeature(适用于简单情况)。我陷入了各种问题,最终也手动实现了该功能。
  • 太棒了!我也未能让 SecurityEntityFilteringFeature 与 DropWizard 一起使用。这个过滤器就像一个冠军。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-07
  • 2015-10-19
  • 2012-06-07
  • 1970-01-01
  • 1970-01-01
  • 2013-03-02
相关资源
最近更新 更多