Java 如何以编程方式替换Spring';s NumberFormatException是否具有用户友好的文本?

Java 如何以编程方式替换Spring';s NumberFormatException是否具有用户友好的文本?,java,spring,replace,message,numberformatexception,Java,Spring,Replace,Message,Numberformatexception,我正在开发一个SpringWeb应用程序,我有一个具有整数属性的实体,用户可以在使用JSP表单创建新实体时填写该属性。此表单调用的控制器方法如下所示: @RequestMapping(value = {"/newNursingUnit"}, method = RequestMethod.POST) public String saveNursingUnit(@Valid NursingUnit nursingUnit, BindingResult result, ModelMap model)

我正在开发一个SpringWeb应用程序,我有一个具有整数属性的实体,用户可以在使用JSP表单创建新实体时填写该属性。此表单调用的控制器方法如下所示:

@RequestMapping(value = {"/newNursingUnit"}, method = RequestMethod.POST)
public String saveNursingUnit(@Valid NursingUnit nursingUnit, BindingResult result, ModelMap model) 
{
    boolean hasCustomErrors = validate(result, nursingUnit);
    if ((hasCustomErrors) || (result.hasErrors()))
    {
        List<Facility> facilities = facilityService.findAll();
        model.addAttribute("facilities", facilities);

        setPermissions(model);

        return "nursingUnitDataAccess";
    }

    nursingUnitService.save(nursingUnit);
    session.setAttribute("successMessage", "Successfully added nursing unit \"" + nursingUnit.getName() + "\"!");
    return "redirect:/nursingUnits/list";
}
我完全理解为什么会发生这种情况,但我一辈子都不知道如何以编程方式将Spring的默认数字格式异常错误消息替换为我自己的错误消息。我知道可以用于这类事情的消息源,但我真的希望直接在代码中实现这一点

编辑

正如所建议的,我在控制器中构建了此方法,但仍然收到Spring的“无法转换属性值…”消息:

@ExceptionHandler({NumberFormatException.class})
private String numberError()
{
   return "The auto-discharge time must be a number!";
}
其他编辑

以下是我的实体类的代码:

@Entity
@Table(name="tblNursingUnit")
public class NursingUnit implements Serializable 
{
private Integer id;
private String name;
private Integer autoDCTime;
private Facility facility;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() 
{
    return id;
}

public void setId(Integer id) 
{
    this.id = id;
}

@Size(min = 1, max = 15, message = "Name must be between 1 and 15 characters long")
@Column(nullable = false, unique = true, length = 15)
public String getName() 
{
    return name;
}

public void setName(String name) 
{
    this.name = name;
}

@NotNull(message = "The auto-discharge time is required!")
@Column(nullable = false)
public Integer getAutoDCTime() 
{
    return autoDCTime;
}

public void setAutoDCTime(Integer autoDCTime) 
{
    this.autoDCTime = autoDCTime;
}

@ManyToOne (fetch=FetchType.EAGER)
@NotNull(message = "The facility is required")
@JoinColumn(name = "id_facility", nullable = false)
public Facility getFacility()
{
    return facility;
}

public void setFacility(Facility facility)
{
    this.facility = facility;
}

@Override
public boolean equals(Object obj) 
{
    if (obj instanceof NursingUnit)
    {
        NursingUnit nursingUnit = (NursingUnit)obj;
        if (Objects.equals(id, nursingUnit.getId()))
        {
            return true;
        }
    }
    return false;
}

@Override
public int hashCode() 
{
    int hash = 3;
    hash = 29 * hash + Objects.hashCode(this.id);
    hash = 29 * hash + Objects.hashCode(this.name);
    hash = 29 * hash + Objects.hashCode(this.autoDCTime);
    hash = 29 * hash + Objects.hashCode(this.facility);
    return hash;
}

@Override
public String toString()
{
    return name + " (" + facility.getCode() + ")";
}
}
又一次编辑

我可以使用类路径上包含以下内容的message.properties文件来实现这一点:

typeMismatch.java.lang.Integer={0} must be a number!
以及配置文件中的以下bean声明:

@Bean
public ResourceBundleMessageSource messageSource() 
{
    ResourceBundleMessageSource resource = new ResourceBundleMessageSource();
    resource.setBasename("message");
    return resource;
}
这给了我正确的错误消息,而不是Spring泛型TypeMismatchException/NumberFormatException,我可以接受它,但我仍然希望尽可能以编程方式完成所有事情,我正在寻找替代方案


谢谢你的帮助

句柄数字格式异常

try {
 boolean hasCustomErrors = validate(result, nursingUnit);
}catch (NumberFormatException nEx){
 // do whatever you want
 // for example : throw custom Exception with the custom message.
}

可以使用以下内容对方法进行注释:

@ExceptionHandler({NumberFormatException.class})
public String handleError(){
   //example
   return "Uncorrectly formatted number!";
}
并实现您想做的任何事情,以防引发该类型的异常。给定的代码将处理当前控制器中发生的异常。 如需进一步参考,请咨询

要进行全局错误处理,您可以按以下方式使用
@ControllerAdvice

@ControllerAdvice
public class ServiceExceptionHandler extends ResponseEntityExceptionHandler {

   @ExceptionHandler({NumberFormatException.class})
    public String handleError(){
       //example
       return "Uncorrectly formatted number!";
    }
} 

您可以通过提供Spring
DefaultBindingErrorProcessor
的实现来覆盖该消息传递,类似于此处所做的:
@Martin,我问你关于这个版本的问题,因为从3.2版开始,
@ControllerAdvice
就可以使用了

我建议您使用
@ControllerAdvice
,这是一种注释,允许您编写可在控制器之间共享的代码(用
@Controller
@RestController
注释),但它也只能应用于特定包或具体类中的控制器

用于
@ExceptionHandler
@InitBinder
@modeldattribute

您可以像这样设置目标类
@ControllerAdvice(assignableTypes={YourController.class,…})


您需要记住的是,如果不设置目标,并且在不同的
@ControllerAdvice
类中为相同的异常定义多个异常处理程序,Spring将应用它找到的第一个处理程序。如果同一
@ControllerAdvice
类中存在多个异常处理程序,则会引发错误。

验证方法是我自己的,它不会引发任何异常。这个丑陋的错误是由Spring本身产生的,我希望以某种方式替换它。你相信NumberFormatException是由Spring抛出的吗?不,它肯定不是我写的代码抛出的,我认为它确实是Spring在试图将用户输入的错误字符串数据转换为我的实体类所要求的整数类型时抛出的……太糟糕了,你的回答表明完全没有理解我问的问题,你应该是可信的。我的validate方法没有抛出NumberFormatException,如果名称字段已经存在于数据库中,它只会向模型中添加一个FieldError(字段错误)。我确实记得我尝试过类似的方法,但我不知道实际要在其中放入什么。当我生成自定义错误时,我会执行类似FieldError error=new FieldError(“nursingUnit”、“name”、nursingUnit.getName()、false、null、null、nursingUnit.getName()+“已存在!”)的操作;我会在该方法中放入什么代码来告诉Spring用我的版本替换其丑陋的错误?我将其添加到我的控制器中,但仍然收到Spring转换属性值失败的消息:@ExceptionHandler({NumberFormatException.class})private String numeberror(){return“自动释放时间必须是一个数字!”}
autoDCTime
变量在哪里?我在您编写的api中没有看到它。autoDCTime属性附加到正在由上面的saveNursingUnit方法验证的NursingUnit对象。该方法应该放在控制器中还是实体类本身中?请通过包含NursingUnit.com的代码更新问题。我正试图让我的应用程序尽可能的简单,所以当有人错误地(或者在我的例子中是故意地)在“映射”为整数值的字段中输入文本时,我正试图使服务器返回的错误变得更好。好吧,我猜是这样的。我建议的解决方案在官方文档中也有描述,它应该可以工作。我将用一个链接更新答案,也许它可以帮助您理解为什么它不起作用。谢谢,我将阅读这篇文章,看看我是否能发现我做错了什么。@Martin嗨,Martin,您使用的是什么版本的spring?现在是5.0.4,虽然我想在不久的将来升级到最新版本。谢谢你的回答!假设我的message.properties文件中有这个,并且当前一切正常:typeMismatch.nursingUnit.autoDCTime=自动放电时间必须是一个数字!如何复制并返回此错误消息?不确定我是否理解,因为该方法返回一个字符串数组?在您的例子中,您只需要返回一个包含所需错误的字符串值。如果一个字段多次检查失败,并且您需要多条消息,则它是一个数组。您可能需要向字段添加注释,以便
@ControllerAdvice
public class ServiceExceptionHandler extends ResponseEntityExceptionHandler {

   @ExceptionHandler({NumberFormatException.class})
    public String handleError(){
       //example
       return "Uncorrectly formatted number!";
    }
} 
@ControllerAdvice(assignableTypes = {YourController.class, YourOtherController.class})
public class YourExceptionHandler{
    //Example with default message
    @ExceptionHandler({NumberFormatException.class})
    private String numberError(){
        return "The auto-discharge time must be a number!";
    }

    //Example with exception handling
    @ExceptionHandler({WhateverException.class})
    private String whateverError(WhateverException exception){
        //do stuff with the exception
        return "Whatever exception message!";
    }

    @ExceptionHandler({ OtherException.class })
    protected String otherException(RuntimeException e, WebRequest request) {
        //do stuff with the exception and the webRequest
        return "Other exception message!";
    }
}