Java-Jersey Jackson停用filterprovider

最近,我开始使用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)

解决方法:

由于没有解决方案适合我,因此我必须创建自己的过滤器.
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);
上一篇:java-在Jersey中将int数组作为@QueryParam发送


下一篇:Java-JAX-RS(Jersey 2)安全性,@ PermitAll和@RolesAllowed无法正常工作