注意:部分代码将使用西班牙语。
嗨,我为我的Sping Boot 应用程序做了一个很好的异常模型,这样我抛出的每个个性化异常都会创建一个个性化的响应(在本例中,它是一个名为ErrorModel
得类),这样我就可以用@ExceptionHandler
捕获@RestControllerAdvice
中得异常,并且只返回该特定异常创建的errorModel
。在个性化异常中创建的每个errorModel
的特殊之处是code
和description
。
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ClienteSinMorasException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
@ResponseBody
public ErrorModel manejoDeClienteSinMoras(ClienteSinMorasException ex) {
return ex.getErrorModel();
}
}
个字符
因此,因为每个异常都是相同的,并且工作方式相同,唯一的区别是code
(codigo
)和description
(descipcion
),所以我创建了这个,它工作得很好:
public abstract class IErrorException extends RuntimeException {
@Getter
private final ErrorModel errorModel;
public abstract String getCodigo();
public abstract String getDescripcion();
public IErrorException() {
super();
this.errorModel = new ErrorModel(this.getCodigo(), this.getDescripcion(), null);
}
public IErrorException(ArrayList<HashMap<String, String>> errores) {
super();
this.errorModel = new ErrorModel(this.getCodigo(), this.getDescripcion(), errores);
}
public IErrorException(String errorKey, String errorValue) {
super();
ArrayList<HashMap<String, String>> errores = new ArrayList<>();
errores.add(new HashMap<>(Map.of(errorKey, errorValue)));
this.errorModel = new ErrorModel(this.getCodigo(), this.getDescripcion(), errores);
}
}
// One of the exceptions
@Getter
public class ClienteSinMorasException extends IErrorException {
private final String codigo = "code";
private final String descripcion = "desc";
public ClienteSinMorasException() {
super();
}
public ClienteSinMorasException(ArrayList<HashMap<String, String>> errores) {
super(errores);
}
public ClienteSinMorasException(String errorKey, String errorValue) {
super(errorKey, errorValue);
}
}
的字符串
这是完美的(除了那些超级,但无论如何),但最近,他们要求我改变它,使code
和description
是从.yml属性读取,这样的值可以在运行时改变,而不需要重新运行应用程序。
我开始明白,这起作用的唯一原因是,当我在抽象类中执行this.getCodigo()
时,explicit primitive
类型的final
字段“有点已经存在(在本例中,返回“code”)。如果不是final
,也不是explicit primitive
类型,则不起作用,它在构造函数执行后加载所有内容,因此我最终创建了一个new ErrorModel(null, null, null)
。另外,super()
必须是构造函数中的第一个元素,因此我无法正确地初始化变量。
// One of the exceptions
@Getter
public class ClienteSinMorasException extends IErrorException {
private final String codigo = Yml.get("cod");
private final String descripcion = Yml.get("desc");
public ClienteSinMorasException() {
super();
}
public ClienteSinMorasException(ArrayList<HashMap<String, String>> errores) {
super(errores);
}
public ClienteSinMorasException(String errorKey, String errorValue) {
super(errorKey, errorValue);
}
}
型
这不管用,老实说,我不知道该怎么办。
2条答案
按热度按时间f5emj3cl1#
字段初始化器直到稍后才运行。然而,这两个字段似乎没有任何功能。你不需要它们。它们最多是作为缓存Yml读取器值的一种有点蹩脚的方式存在。蹩脚的是,每个异常的示例都会重新创建它们,如果缓存是重点,在Yml类本身中这样做会更有效。
因此,完全删除字段。要么它们根本没有任何意义,要么它们的意义是作为缓存(即避免重复锤击磁盘以多次重新读取YML文件)。如果它是缓存-这是它的错误位置,请编辑
Yml
的代码以在那里添加缓存行为。无论哪种方式,对这种异常类型的正确处理都是:字符串
这避免了问题:这里没有字段,所以也没有字段初始化器,所以你不会遇到任何关于初始化序列的问题。
oug3syen2#
所以我是最初发布这个问题的人。上面的答案是我用的.....直到我最近才明白,从我的Angular 来看,这一切都是愚蠢的。这里是我的新答案。
所以,基本上,我是搬起石头砸自己的脚。原因很简单:**我不需要在初始化类时做所有这些!!! 我可以在调用
.getErrorModel()
的时候做,这是我需要的时候,而不是之前。这是一个如此明显的疏忽,似乎我被@Getter
蒙蔽了双眼,尝试使用它,而不是自己编写任何类型的getter。这是新的解决方案。字符串
然后:
型
我认为这是目前为止最好的解决方案,因为它不会不必要地接近边缘。