我一直在使用spring boot开发rest api服务。 这是我的休息控制器
@RequestMapping(value = "owner/login", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
@ResponseBody
public ResponseEntity<String> login(@RequestBody Owner owner) throws TimeoutException, SocketTimeoutException, SocketException {
controller.login(owner);
return ResponseEntity.ok("\"error\": 0");
}
这是控制器
public JsonObject login(Owner loginOwner){
Map<String,String> params = new HashMap<String,String>();
params.put("email", loginOwner.getEmail());
params.put("password", loginOwner.getPassword());
if(GMoikaStringUtils.isEmpty(loginOwner.getEmail()) || !GMoikaStringUtils.isValidEmail(loginOwner.getEmail())){
throw new InvalidUserInputException("Wrong email format", CLASS_NAME, "login", params, "owners/owner/login POST");
}
else{
someLogic...
}
}
问题是,使用这个结构我应该在每个方法中创建带有参数的地图。如何避免在每个方法中创建地图并将所有参数放入此地图?我需要&#34; MAP&#34;如果发生异常,则显示日志中的参数。 也许春季靴子可以做到,但我无法在官方文档中找到我的案例。提前致谢
答案 0 :(得分:0)
如果您只想在抛出InvalidUserInputException
后执行此操作,则可以编写异常处理程序:
@ExceptionHandler(InvalidUserInputException.class)
@ResponseBody
public ValidationError getError(InvalidUserInputException ex) {
// ...
}
由于InvalidUserInputException
是自定义例外,您可以添加Object
类型的字段,您可以在其中传递请求正文,例如:
throw new InvalidUserInputException("Wrong email format", loginOwner);
现在,您可以使用toString()
对象的Owner
方法进行记录。如果您想以JSON样式获取它,可以使用Apache commons及其ToStringBuilder
:
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.JSON_STYLE)
.append("email", email)
.append("password", password)
.toString();
}
或者,如果您不想依赖于使用toString()
方法并且只想返回普通请求体,您还可以将HttpServletRequest
作为参数添加到异常处理程序中。 / p>
在你这样做之前,你必须把它包起来,因为请求体只能被读取一次,为了解决这个问题,你应该在读取后“缓存”请求体。为此,您可以使用Spring ContentCachingRequestWrapper
。
要包装它,您应该编写自己的Filter
。你可以通过像Spring这样的OncePerRequestFilter
扩展它来实现这个目的:
ContentCachingRequestWrapper wrapper = (ContentCachingRequestWrapper) request;
wrapper.getContentAsByteArray();
@Component
public class RequestWrapperFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
filterChain.doFilter(new ContentCachingRequestWrapper(httpServletRequest), httpServletResponse);
}
}
现在,您可以通过调用getContentAsByteArray()
方法在异常处理程序中获取请求正文。要将请求体作为String,您可以使用Apache Commons中的IOUtils
:
ContentCachingRequestWrapper wrapper = (ContentCachingRequestWrapper) request;
logger.warn("Input validation failed, request body: {}", IOUtils.toString(wrapper.getContentAsByteArray(), wrapper.getCharacterEncoding()));
这会将整个请求正文记录为字符串。但要注意记录敏感信息。