spring,显示带有无效参数的restful Web服务的自定义错误消息(使用spring的自动参数转换)

spring,显示带有无效参数的restful Web服务的自定义错误消息(使用spring的自动参数转换),spring,Spring,我有一个rest Web服务,它需要一个数字: @RequestMapping(value = "/bb/{number}", method = RequestMethod.GET, produces = "plain/text") public void test(@PathVariable final double number, final HttpServletResponse response) 但是,如果客户端传递的是诸如“QQQ”之类的文本而不是数字, 客户端从spring获得

我有一个rest Web服务,它需要一个数字:

@RequestMapping(value = "/bb/{number}", method = RequestMethod.GET, produces = "plain/text")
public void test(@PathVariable final double number, final HttpServletResponse response) 
但是,如果客户端传递的是诸如“QQQ”之类的文本而不是数字, 客户端从spring获得如下错误:

HTTP Status 500 -
The server encountered an internal error () that prevented it from fulfilling this request.
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'double'; nested exception is java.lang.NumberFormatException: For input string: "QQQ"
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894)
...
我需要处理此情况,并显示正确的错误消息,例如:

<MyError>
  <InvalidParameter parameterName="number"/>
  <message>...</message>
</MyError>
那么,如果客户端使用无效号码呼叫,如何显示自定义错误消息,例如

ps:一种解决方案是将“number”参数定义为字符串,并从函数内部进行转换(然后我可以捕获并抛出自定义异常)。在这个问题上,我要求一个解决方案,同时保持弹簧的自动参数转换


ps:此外,spring对客户端的响应是“HTTP 500内部服务器错误”,而不是“HTTP 400错误请求”。这有意义吗

在控制器类中使用BindingResult。它会将无效字段设置为null,现在您可以编写自己的自定义验证类,在其中检查此字段是否为null,然后生成自定义消息,如“需要有效日期”

,而不是检查类型不匹配异常的实例,你可以得到嵌套异常,如果它是
NumberFormatException
处理它,否则就让其他东西来处理它。这也是糟糕的编码(正如我在这里发布的解决方法)。例如,可能存在其他NumberFormatException异常,这些异常与解析和转换webservice请求的参数无关。但是如果你想要一个通用的异常处理程序,这是意料之中的。如果您想要某种方法来处理您的特定异常,请按照您所说的做,使用您自己解析和转换的字符串参数。您希望其余的web服务能够引发多少NFE?同样,我不能假设如果存在NumberFormatException,这与webservice请求的参数有关。这毫无意义。我在spring论坛上添加了一个相关问题:
import org.springframework.beans.TypeMismatchException;
import javax.annotation.*;
import javax.servlet.http.*;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.*;

@Controller
@RequestMapping(value = "/aa")
public class BaseController {

    @RequestMapping(value = "/bb/{number}", method = RequestMethod.GET, produces = "plain/text")
    public void test(@PathVariable final double number, final HttpServletResponse response) throws IOException {
        throw new MyException("whatever");
    }

    @ResponseBody
    @ExceptionHandler
    public MyError handleException(final Exception exception) throws IOException {
        if (exception instanceof TypeMismatchException) {
            response.setStatus(HttpStatus.BAD_REQUEST.value());
            TypeMismatchException e = (TypeMismatchException) exception;
            String msg = "the value for parameter " + e.getPropertyName() + " is invalid: " + e.getValue(); 
            return new MyError(msg);
        }

        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        return MyError("Unknown internal error");
    }
}