Java Moxy忽略json中的无效字段

Java Moxy忽略json中的无效字段,java,json,jersey,moxy,jersey-2.0,Java,Json,Jersey,Moxy,Jersey 2.0,当我发送此请求时: {"invalidField": "value", "date": "value"} 为我的休息服务: @PUT @Consumes("application/json") public void putJson(Test content) { System.out.println(content.toString()); } 我希望得到一个异常,因为: 我的域模型中没有invalidField 日期格式无效 但实际上我得到的测试对象是空值。我的主要型号是: pu

当我发送此请求时:

{"invalidField": "value", "date": "value"}
为我的休息服务:

@PUT
@Consumes("application/json")
public void putJson(Test content) {
    System.out.println(content.toString());
}
我希望得到一个异常,因为:

  • 我的域模型中没有invalidField
  • 日期格式无效
  • 但实际上我得到的测试对象是空值。我的主要型号是:

    public class Test {
        private String name;
        private Date date; 
        //getters and setters here  
    }
    
    我认为这不是一种有效的行为。我怎样才能解决这个问题

    谢谢你的帮助

    解决方案: 正如Blaise Doughan所说,需要扩展MOXy的MOXyJsonProvider并重写preReadFrom方法来设置自定义javax.xml.bind.ValidationEventHandler。但问题是Jersey的ConfigurableMoxyJsonProvider总是首先被选中,除非您编写的MessageBodyWriter/MessageBodyReader是使用比Object更具体的类型参数化的。要解决此问题,必须禁用MOXy,然后启用CustomMoxyJsonProvider

    例如:

  • 创建您自己的扩展javax.ws.rs.core.feature的功能:

    @Provider
    public class CustomMoxyFeature implements Feature {
        @Override
        public boolean configure(final FeatureContext context) {
            final String disableMoxy = CommonProperties.MOXY_JSON_FEATURE_DISABLE + '.' + context.getConfiguration().getRuntimeType().name().toLowerCase();
            context.property(disableMoxy, true);
           return true;
        }
    }
    
  • 创建您自己的扩展MOXyJsonProvider的提供程序:

    @Provider
    public class CustomMoxyJsonProvider extends MOXyJsonProvider {
        @Override
        protected void preReadFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, Unmarshaller unmarshaller) throws JAXBException {
        unmarshaller.setEventHandler(new ValidationEventHandler() {
            @Override
            public boolean handleEvent(ValidationEvent event) {
                return false;
            }
        });
    }
    
    @Provider
    公共类CustomMoxyJsonProvider扩展了MOXyJsonProvider{
    @凌驾
    受保护的void preReadFrom(类类型、类型genericType、注释[]注释、MediaType MediaType、多值Map httpHeaders、解组器解组器)引发JAXBEException{
    unmarshaller.setEventHandler(新的ValidationEventHandler(){
    @凌驾
    公共布尔handleEvent(ValidationEvent事件){
    返回false;
    }
    });
    }
    
    }

  • 在应用程序配置中添加以下资源:

    package com.vinichenkosa.moxyproblem;
    
    import java.util.Set;
    import javax.ws.rs.core.Application;
    
    @javax.ws.rs.ApplicationPath("webresources")
    public class ApplicationConfig extends Application {
    
        @Override
        public Set<Class<?>> getClasses() {
            Set<Class<?>> resources = new java.util.HashSet<>();
            addRestResourceClasses(resources);
            return resources;
        }
    
        private void addRestResourceClasses(Set<Class<?>> resources) {
            resources.add(com.vinichenkosa.moxyproblem.TestResource.class);
            resources.add(com.vinichenkosa.moxyproblem.custom_provider.CustomMoxyFeature.class);
            resources.add(com.vinichenkosa.moxyproblem.custom_provider.CustomMoxyJsonProvider.class);
        }
    }
    
    package com.vinichenkosa.moxyproblem;
    导入java.util.Set;
    导入javax.ws.rs.core.Application;
    @javax.ws.rs.ApplicationPath(“webresources”)
    公共类应用程序配置扩展应用程序{
    @凌驾
    public Set>resources=new java.util.HashSet();
    添加资源类(资源);
    归还资源;
    }
    
    private void addRestResourceClasses(SetMOXy将报告有关无效属性值的信息,但默认情况下不会在这些属性值上失败。报告是对的实例完成的。您可以覆盖
    解组器上的
    ValidationEventHandler
    集来执行此操作

    @Override
    protected void preReadFrom(Class<Object> type, Type genericType,
            Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, String> httpHeaders,
            Unmarshaller unmarshaller) throws JAXBException {
        unmarshaller.setEventHandler(yourValidationEventHandler);
    }
    
    您可以创建自己的
    MesageBodyReader
    /
    MessageBodyWriter
    ,扩展MOXy的
    MOXyJsonProvider
    ,并覆盖
    preReadFrom
    方法来执行此操作

    @Override
    protected void preReadFrom(Class<Object> type, Type genericType,
            Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, String> httpHeaders,
            Unmarshaller unmarshaller) throws JAXBException {
        unmarshaller.setEventHandler(yourValidationEventHandler);
    }
    
    @覆盖
    受保护的void preReadFrom(类类型、类型genericType、,
    注释[]注释,MediaType MediaType,
    多值MAP HttpHeader,
    解组器(解组器)抛出JAXBEException{
    unmarshaller.setEventHandler(yourValidationEventHandler);
    }
    
    感谢您的回复。我只是想从Jackson迁移到Moxy,因为它现在是Glassfish的默认库。但由于这种行为,只要不可能。对此解决方案不确定,因为您的ValidationEventHandler会为每个错误返回false,但这不是您想要的。您只在特定情况下需要false。T感谢您的回复。我尝试了此解决方案,但没有使用我的自定义MoxyJsonProvider。我使用了此处描述的解决方案,唯一的区别是,我使用了@javax.ws.rs.ApplicationPath注释而不是servlet。如果我使用ContextResolver,如本文所述,它可以工作,但似乎不适合我的目的。我的服务器是Glassfish4.0Blaise对此提出了一个问题。对于json,似乎无法调用eventHandler。在org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl.StartunmapeElement()中在向事件处理程序发出警告之前,会检查媒体类型是否为xml。对于JSON,是否有方法对未映射的内容发出警告?@ManuelQuinones您找到解决方案了吗?