2017-09-13 77 views
3

我面临的问题是我找不到解决方案(或者我正在处理错误的方法)。当我的服务生成某些异常时,显示序列化失败。这导致得到一个包装的异常,这是一个痛苦的呼叫客户端收到一个糟糕的错误,我想我从原始异常丢失有用的信息。Jax-ws异常序列化失败

在下面的示例中它是一个S3存储桶访问问题,但我遇到了一些SQL异常的类似问题。

如果我可以让我的服务直接进行干预,那将会很有用。理想的做法是添加一些自定义的异常序列化代码。

> com.amazonaws.services.simpleworkflow.flow.DataConverterException: 
> Failure serializing 
> "com.sun.xml.internal.ws.fault.ServerSOAPFaultException: Client 
> received SOAP Fault from server: Access Denied (Service: Amazon S3; 
> Status Code: 403; Error Code: AccessDenied; Request ID: AAAAAAAAAAAA) 
> Please see the server log to find more detail regarding exact cause of 
> the failure." of type "class 
> com.sun.xml.internal.ws.fault.ServerSOAPFaultException" when mapping 
> key "null" at 
> com.amazonaws.services.simpleworkflow.flow.JsonDataConverter.throwDataConverterException(JsonDataConverter.java:90) 
> at 
> com.amazonaws.services.simpleworkflow.flow.JsonDataConverter.toData(JsonDataConverter.java:78) 
> at 
> com.amazonaws.services.simpleworkflow.flow.pojo.POJOActivityImplementation.throwActivityFailureException(POJOActivityImplementation.java:102) 
> at 
> com.amazonaws.services.simpleworkflow.flow.pojo.POJOActivityImplementation.execute(POJOActivityImplementation.java:67) 
> at 
> com.amazonaws.services.simpleworkflow.flow.generic.ActivityImplementationBase.execute(ActivityImplementationBase.java:46) 
> at 
> com.amazonaws.services.simpleworkflow.flow.worker.SynchronousActivityTaskPoller.execute(SynchronousActivityTaskPoller.java:196) 
> at 
> com.amazonaws.services.simpleworkflow.flow.worker.ActivityTaskPoller$2.run(ActivityTaskPoller.java:92) 
> at 
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
> at 
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
> at java.lang.Thread.run(Thread.java:748) Caused by: 
> com.fasterxml.jackson.databind.JsonMappingException: Type id handling 
> not implemented for type org.w3c.dom.Node (by serializer of type 
> com.fasterxml.jackson.databind.ext.DOMSerializer) (through reference 
> chain: 
> com.sun.xml.internal.ws.fault.ServerSOAPFaultException["fault"]) at 
> com.fasterxml.jackson.databind.SerializerProvider.mappingException(SerializerProvider.java:1084) 
> at 
> com.fasterxml.jackson.databind.JsonSerializer.serializeWithType(JsonSerializer.java:159) 
> at 
> com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:695) 
> at 
> com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:675) 
> at 
> com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeWithType(BeanSerializerBase.java:566) 
> at 
> com.fasterxml.jackson.databind.ser.impl.TypeWrappedSerializer.serialize(TypeWrappedSerializer.java:32) 
> at 
> com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:130) 
> at 
> com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3559) 
> at 
> com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:2927) 
> at 
> com.amazonaws.services.simpleworkflow.flow.JsonDataConverter.toData(JsonDataConverter.java:72) 
> ... 8 more 

感谢您的任何建议

+0

@Kayaman上的SOAP服务 –

+0

403非常感谢?用JSON?你的问题缺少一些东西。您是否将SOAP映射到JSON? – Namphibian

回答

1

杰克逊试图序列的com.sun.xml.internal.ws.fault.ServerSOAPFaultException一些实例。这个例外是javax.xml.ws.soap.SOAPFaultException的一个子类,其中happens to have a getter for retrieving the SOAPFault。作为SOAPFault是DOM Node,杰克逊决定使用DOMSerializer并且还编码类型信息,以便在反序列化时间它可以找出哪个具体类型fault是一个实例。问题是DOMSerializer不支持 这种类型的信息的东西,所以你得到com.fasterxml.jackson.databind.JsonMappingException

我认为解决此问题的最佳方法是注册一个自定义串行器/解串器对SOAPFault。然后,您可以序列化到String并反序列化通过SOAPFactory.createFault(...) methods之一创建新实例。不要忘记也执行JsonSerializer.serializeWithType(...),以便杰克逊可以正确地进行类型处理。

A(很粗糙)草案将

public class SOAPFaultSerializer extends StdSerializer<SOAPFault> { 

    public SOAPFaultSerializer() { 
     this(null); 
    } 

    public SOAPFaultSerializer(Class<SOAPFault> t) { 
     super(t); 
    } 

    @Override 
    public void serialize(SOAPFault fault, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { 

     jgen.writeStartObject(); 
     // serialize "interesting" SOAPFault information 
     jgen.writeStringField("faultActor", fault.getFaultActor()); 
     jgen.writeStringField("faultCode", fault.getFaultCode()); 
     ... 
     jgen.writeEndObject(); 
    } 

    @Override 
    public void serializeWithType(JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonGenerationException { 
     typeSer.writeTypePrefixForObject(this, jgen, SOAPFault.class); 
     serialize(value, jgen, provider); 
     typeSer.writeTypeSuffixForObject(this, jgen); 
    } 
} 

public class SOAPFaultDeserializer extends StdDeserializer<SOAPFault> { 

    public SOAPFaultDeserializer() { 
     this(null); 
    } 

    public SOAPFaultDeserializer(Class<?> vc) { 
     super(vc); 
    } 

    @Override 
    public SOAPFault deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { 
     JsonNode node = jp.getCodec().readTree(jp); 
     // deserialize "interesting" SOAPFault information 
     String faultActor = node.get("faultActor").asText(); 
     String faultCode = node.get("faultCode").asText(); 
     ... 
     SOAPFactory factory = SOAPFactory.newInstance(); 
     SOAPFault fault = factory.createFault(); 
     // fill in SOAPFault with deserialized fields 
     fault.setFaultActor(faultActor); 
     fault.setFaultCode(faultCode); 
     ... 
     return fault; 
    } 
} 
+0

辉煌,非常感谢让我走上正轨! –

+0

不客气:) – gpeche

+0

请记住,'SOAPFactory.newInstance()'可能会相对昂贵,所以如果您需要高性能,您应该尝试调用此方法一次并重用工厂实例。 – gpeche