Java ObjectMapper导致StackOverflow无限循环异常n

问题描述 投票:0回答:0

我遇到了无限循环堆栈溢出,我无法确定是什么问题导致了它。这是堆栈跟踪的一部分(因为它一直在重复)

注意删除了一些代码和堆栈跟踪,因为它大于允许的字符。

2023-04-07 10:33:07.446 ERROR 53488 --- [nio-8443-exec-2] c.s.c.c.e.tools.support.ModelMapper      : Infinite recursion (StackOverflowError) (through reference chain: sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl["decl"]->java.lang.reflect.Method["parameters"]->java.lang.reflect.Parameter[0]->java.lang.reflect.Parameter["annotatedType"]->sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl["decl"]->java.lang.reflect.Method["parameters"]->java.lang.reflect.Parameter[0]->java.lang.reflect.Parameter["annotatedType"]->sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl["decl"]->java.lang.reflect.Method["parameters"]->java.lang.reflect.Parameter[0]->java.lang.reflect.Parameter["annotatedType"]-
...
>java.lang.reflect.Method["parameters"]->java.lang.reflect.Parameter[0]->java.lang.reflect.Parameter["annotatedType"])
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:789) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer.serializeContents(ObjectArraySerializer.java:253) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer.serialize(ObjectArraySerializer.java:214) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer.serialize(ObjectArraySerializer.java:23) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:733) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:733) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:733) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer.serializeContents(ObjectArraySerializer.java:253) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer.serialize(ObjectArraySerializer.java:214) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer.serialize(ObjectArraySerializer.java:23) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:733) ~[cst-exodus-tools-1.0.0.jar:na]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774) ~[cst-exodus-tools-1.0.0.jar:na]

这是我创建的抛出此错误的对象映射器包装器类(正式是在执行对象映射器写入时而不是这段代码,但提供以防万一这里出现问题)

@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ModelMapper {


    public static <T> T fromString(String json, Class<T> clazz) {
        return ModelMapper.convertJsonToObjectString(json, clazz);
    }

    public static ObjectMapper getMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new Jdk8Module());
        mapper.registerModule(new JavaTimeModule());
        mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
        mapper.writer(new DefaultPrettyPrinter());
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        mapper.registerModule(new CustomSimpleModule());
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.findAndRegisterModules();
        return mapper;
    }

    public static String toString(Object obj) {
        return ModelMapper.convertObjectToJsonString(obj);
    }

    private static <T> T convertJsonToObjectString(String json, Class<T> clazz) {
        T returnValue = null;
        if (StringUtils.isNoneBlank(json)) {
            try {
                returnValue = ModelMapper.getMapper().readValue(json, clazz);
            } catch (Exception ignored) {
                log.error(ignored.getMessage(), ignored);
            }
        }
        return returnValue;
    }

    private static String convertObjectToJsonString(Object obj) {
        String returnValue = null;
        if (Optional.ofNullable(obj).isPresent()) {
            try {
                returnValue = ModelMapper.getMapper().writeValueAsString(obj);
            } catch (Exception ignored) {
                log.error(ignored.getMessage(), ignored);
            }
        }
        return returnValue;
    }

}

这是有数据时抛出异常的对象:

@SuppressWarnings({ "unused", "UnusedReturnValue" })
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
@With
@EqualsAndHashCode(callSuper = false)
@SuperBuilder
@AllArgsConstructor
@NoArgsConstructor
public class ErrorDetails implements Serializable {

    public static final String RESPONSE_BODY_KEY = "Response_Body";
    public static final String REQUEST_BODY_KEY = "Request_Body";
    public static final String REQUEST_HEADER_KEY = "Request_Header";
    public static final String RESPONSE_HEADER_KEY = "Response_Header";
    public static final String ADDITIONAL_FIELDS_KEY = "Additional Fields";
    public static final String STATUS_KEY = "status";
    public static final ZoneId ZONE_ID = ExodusDateAndTimePatterns.DEFAULT_TIME_ZONE;
    public static final String ERROR_STATUS = "ErrorStatus";
    public static final String ERROR_TIMESTAMP = "ErrorTimestamp";
    public static final String ERROR_MESSAGE = "ErrorMessage";
    public static final String ERROR_DEBUG_MESSAGE = "ErrorDebugMessage";
    public static final String ERROR_TYPE = "ErrorType";
    private static final long serialVersionUID = 3135141341712621098L;
    private boolean doNotLog;
    private boolean secureData;
    private Boolean external;
    private ResultsTraceLevel traceLevel;
    private HttpStatus status;
    private String message;
    private Class clazz;
    private String correlationId;
    private AdditionalProperties additionalProperties;
    private ExceptionDetails exceptionDetails;
    private HeaderType headerType;
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
    private LocalDateTime timeStamp;

    public static ErrorDetails getInstance() {
        ErrorDetails details = new ErrorDetails();
        details.setTimeStamp(LocalDateTime.now());
        details.addStatus(HttpStatus.INTERNAL_SERVER_ERROR);
        details.addTraceLevelData(ResultsTraceLevel.ERROR);
        return details;
    }

    public AdditionalProperties getAdditionalProperties() {
        additionalProperties = Optional.ofNullable(additionalProperties).orElse(AdditionalProperties.getInstance());
        return additionalProperties;
    }

    public Object getAdditionalProperty(String key) {
        additionalProperties = Optional.ofNullable(additionalProperties).orElse(AdditionalProperties.getInstance());
        return additionalProperties.getAdditionalProperty(key);
    }

}

这是抛出异常时对象中数据的示例。

ErrorDetails(doNotLog=false,
 secureData=false,
 external=null,
 traceLevel=null,
 status=400 BAD_REQUEST,
 message=Required request header 'Nuance-Session-ID' for method parameter type String is not present,
 clazz=null,
 correlationId=null,
 additionalProperties=AdditionalProperties(properties={Exception=ExceptionDetails(name=org.springframework.web.bind.MissingRequestHeaderException,
 message=Required request header 'Nuance-Session-ID' for method parameter type String is not present,
 methodName=wrapRequestWithLogging,
 lineNumber=HttpInboundLoggingSpringWebFilter.java:155,
 rootCause=null),
 Headers={Content-Type=application/json,
 accept-encoding=gzip,
 deflate,
 br,
 connection=keep-alive,
 host=localhost:8443,
 postman-token=beccc42e-9c48-4573-840b-20dd65a70913,
 user-agent=PostmanRuntime/7.31.3},
 MissingParameter=method 'getProfiles' parameter 2,
 Request=ServletWebRequest: uri=/MoneyLink/MLGetRequestList;client=0:0:0:0:0:0:0:1,
 Request Parameters=org.apache.catalina.util.ParameterMap@50d193b7}),
 exceptionDetails=ExceptionDetails(name=org.springframework.web.bind.MissingRequestHeaderException,
 message=Required request header 'Nuance-Session-ID' for method parameter type String is not present,
 methodName=wrapRequestWithLogging,
 lineNumber=HttpInboundLoggingSpringWebFilter.java:155,
 rootCause=null),
 header=Header(accept=null,
 authorization=null,
 contentType=application/json,
 nvpSessionId=null,
 nuanceSessionId=null,
 sessionId=null,
 headerType=null,
 additionalProperties=AdditionalProperties(properties={accept-encoding=gzip,
 deflate,
 br,
 connection=keep-alive,
 host=localhost:8443,
 postman-token=beccc42e-9c48-4573-840b-20dd65a70913,
 user-agent=PostmanRuntime/7.31.3})),
 headerType=null,
 timeStamp=null)

请注意,如果对象为空(我只是创建一个实例并尝试转换)它工作正常。

java json spring jackson
© www.soinside.com 2019 - 2024. All rights reserved.