[英]Custom response on bad request using spring RestController
我有以下控制器。 我正在使用Spring创建Restful API。
@RestController
public class UserController extends RestControlValidator {
@RequestMapping(value = "/user/", method = RequestMethod.POST, headers = "Accept=application/json", consumes = "application/json", produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody List newUser(@RequestBody @Valid UserInput input,BindingResult result)
{Some code}
}
UserInput
类如下所示:
public class UserInput{
@NotEmpty
private String emailId;
@NotEmpty
private String fName;
private String lName;
private int sex;
//getters and setters
现在,当我尝试使用数据{"sex":"Male"}
访问/user/
时,得到以下响应:
我希望这样的请求的响应是:
{"errors":{"sex":"The value must be an integer"}}
有什么方法可以在Spring中自定义BAD REQUEST
响应?
考虑到当前情况,最理想的解决方案是更改HandlerMethodArgumentResolve的行为,因为@RequestBody构造的json转换为pojo失败,因为我们没有机会检查错误的数据,并且此检查可以很好地在自定义消息转换器中完成
答:首先,我们需要创建LanguageMessageConverter,如下所示
public class LanguageMessageConverter extends
AbstractHttpMessageConverter<Language> {
private Gson gson = new Gson();
public LanguageMessageConverter() {
super(new MediaType("application", "json", Charset.forName("UTF-8")));
}
@Override
protected boolean supports(Class<?> clazz) {
return Language.class.equals(clazz);
}
Map<String, String> mp = new HashMap<>();
@Override
protected Language readInternal(Class<? extends Language> clazz,
HttpInputMessage httpInputMessage) throws IOException,
HttpMessageNotReadableException {
Map langmp = gson.fromJson(
convertStreamToString(httpInputMessage.getBody()), Map.class);
for (Field field : clazz.getDeclaredFields()) {
if (!langmp.get(field.getName()).getClass().getCanonicalName().equals(field.getType().getCanonicalName())) {
if (field.getType().getCanonicalName().equals("java.lang.Integer")||field.getType().getCanonicalName().toString().equals("int")) {
langmp.put(field.getName(), "0");
} else if (field.getType().equals("java.lang.String")) {
//TODO COde needs to be improved here because this check is not efficient
langmp.put(field.getName(), "wrong");
}
}
}
Language lang = gson.fromJson(gson.toJson(langmp), clazz);
return lang;
}
langmp
(可以使用更好的JSON解析器) B.其次,我们需要在调度程序xml中注册自定义MessageConverter,即LanguageMessageConverter
<mvc:annotation-driven >
<mvc:message-converters register-defaults="true">
<bean class="com.comp.org.controller.LanguageMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
register-defaults="true"
非常重要,因为我们要添加Custom MessageConverter,但是我们还需要其他现有的转换器与我们添加的转换器一起工作 C.考虑到相关的pojo填充有必要的详细信息,它将在自定义转换器中到达我们的控制器后处理,现在我们将添加手动验证,例如。 如果int变量为0,则应返回必要的错误json
根据您的请求,即使json包含错误的数据,自定义消息转换器也应对其进行处理,因此在控制器中,我们可以验证上述条件。 该代码肯定可以进一步改进。 请让我知道此解决方案是否满足您的要求或代码的任何部分需要进一步阐述,并希望能解决您的问题。
我有同样的问题,而不是我这样解决的:
创建一个名为Error的对象,就像这样(不要忘记实现Serializable ...):
private String fieldName; private String errorCode; private String defaultMessage; public Error() { } public Error(String fieldName, String errorCode, String defaultMessage) { this.fieldName = fieldName; this.errorCode = errorCode; this.defaultMessage = defaultMessage; } /* getters, setters */
在@RestController
方法中,您必须调用inputValidator.validate()
方法(如果您没有为UserInput
创建对象验证器,那么我们实际上不是在说相同的语言...)
// validating the userInput userInputValidator.validate(userInput, bindingResult); if (bindingResult.hasErrors()) { List<Error> errors = new ArrayList<>(bindingResult.getErrorCount()); for (FieldError fieldWithError : bindingResult.getFieldErrors()) { errors.add(new Error(fieldWithError.getField(), fieldWithError.getCode(), fieldWithError.getDefaultMessage())); } return errors; } // in case of success: return null;
最后,您必须将JSON对象转换为客户端。 您将拥有两种对象:
3.1。 null(根据您使用的语言undefined
)
3.2。 像这样的JSON对象:
[ { "fieldName": "name", "errorCode": "user.input.name.in.blank", "defaultMessage": "Insert a valid name!" }, { "fieldName": "firstPhone", "errorCode": "user.input.first.phone.blank", "defaultMessage": "Insert a valid first phone!" } ]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.