3

我有一个需要数字的休息网络服务:

@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>

我怎样才能做到这一点?

这可以通过捕获 org.springframework.beans.TypeMismatchException 异常来实现(如下代码所示),但它存在很多问题。例如,可能存在与解析和转换 Web 服务请求的参数无关的其他 TypeMismatchException 异常。

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");
    }
}

那么,如果客户端使用无效号码(例如http://example.com/aa/bb/QQQ )呼叫,如何显示自定义错误消息?

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

ps:此外,spring 响应客户端的是“HTTP 500 Internal Server Error”,而不是“HTTP 400 Bad Request”。这有意义吗?!

4

1 回答 1

1

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

于 2014-04-14T15:34:12.513 回答