我正在使用带有设置类型名称的注释的开放投影。影响是一个递归接口,它将属性影响添加到所有具有影响的对象。 我只复制了相关/清理过的代码以保持清晰。
@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>
类的对象中并让杰克逊解析该地图?