Spring openprojects + jackson:即使@Value抛出异常,也可以编写JsonType注释

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

项目

我正在使用带有设置类型名称的注释的开放投影。影响是一个递归接口,它将属性影响添加到所有具有影响的对象。 我只复制了相关/清理过的代码以保持清晰。

    @GetMapping("/{id}/impacts")
    public ImpactOverview getImpacts(@PathVariable("id") String id) {
        return repository.findImpactByLabel(id, Impacts.class);
    }
public interface Impacts extends Field,ImpactOverview {
    // repo variable is simple spring data repository with a id and projection class params.
    @JsonIgnore
    @Value("#{@repo.findTable(target.label, T(com.company.view.projections.field.impacts.Table))}")
    Table getTable();

    default Collection<? extends ImpactOverview> impacts() {
        //combine is just making a big collection of collection fields & singular fields
        return combine(getTable(), ...);
    }

}
public interface Table extends com.company.view.projections.table.Table,ImpactOverview {}
@JsonTypeName(AssetType.FIELD_TYPENAME)
public interface Field {}
@JsonTypeName(AssetType.TABLE_TYPENAME)
public interface Table {}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
public interface ImpactOverview {
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
    default Collection<? extends ImpactOverview> impacts() {
        return null;
    }
}

基本上,这非常有效,并产生嵌套影响概述 json 结构,如下所示:

{
    "type": "field",
    ...
    "impacts: [
        {
            "type": "table",
            ...
        },
        {
            "type": "...",
            ...
            impacts: [...]
        }
    ]
}

可读如下:如果该字段发生变化,我们就会对该表、该...(例如代码库、文件...)产生影响。如果我们影响例如。代码库,因为字段发生变化,该变化可能会影响该程序。影响的递归嵌套循环取决于业务制定的预定义结构。

我们还编写了一个扩展 ResponseEntityExcepionHandler 的 ControllerAdvice。

@ControllerAdvice
@Slf4j
@RequiredArgsConstructor
public class ControllerExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    protected ResponseEntity<Object> handleExceptionInternal(final Exception ex,
                                                             final Object body,
                                                             final HttpHeaders headers,
                                                             final HttpStatusCode statusCode,
                                                             final WebRequest request) {
        return toCompanyException(ex);
    }

    @ResponseBody
    ResponseEntity<Object> toCompanyException(@NonNull Exception e) {
        return ResponseEntity.status(Status.of(e)).body(Body.of(e));
    }
}

问题

如果此

repo.findTable
调用失败,
HttpMessageNotWritable
会抛出
AbstractJackson2HttpMessageConverter
异常,我们将收到如下所示的 json 结构:

{
    "type": "FIELD"
}{
    "exception": "http-message-not-writable",
    "message": "exception"
}

发生这种情况是因为

BeanSerializerBase::serializeWithType
方法执行了
writeTypePrefix
,其中写入了
"type": "field"
。 只有这样,异常才会发生在
serializeFields
调用中。

此时字段类型已经写入。 我该如何克服这个问题?我们只希望返回异常对象。 如果我预先调用所有 getImpacts,所有方法都将被调用/测试,但我将执行所有查询两次?当然接口的代理中会有缓存。或者我应该将它存储在一些

Map<String, Object>
类的对象中并让杰克逊解析该地图?

jackson spring-data spring-data-neo4j spring-projections
1个回答
0
投票

发现这是由这个问题我在spring框架中打开

引起的

暂时可以通过删除

extends ResponseEntityExceptionHandler
来绕过。

© www.soinside.com 2019 - 2024. All rights reserved.