您可以通过自定义配置的消息转换器以两种方式发送常见错误响应(来自过滤器)
方法一:
在过滤器中,捕获到您的 api 的异常转发请求,以便它根据接受标头确定内容类型并以预期格式发送错误响应。
try
{
filterChain.doFilter(request, response);
}
catch (Exception e)
{
req.getRequestDispatcher("/sendError/"+e.getLocalizedMessage()).forward(req, resp);
}
您的 API 将是
@RequestMapping(value = "/sendError/{errorMessage}", method = { RequestMethod.GET, RequestMethod.POST })
public @ResponseBody MyResponse sendError(@PathVariable String errorMessage)
{
return new MyResponse("UUID-1","500",errorMessage);
}
MyResponse POJO 在哪里
public class MyResponse
{
private String requestId;
private String code;
private String message;
public MyResponse(){}
public MyResponse(String requestId, String code, String message)
{
this.requestId = requestId;
this.code = code;
this.message = message;
}
...
}
Controller 方法上的@ResponseBody 向 Spring 表明该方法的返回值直接序列化为由客户端接收到的 Accept 头决定的 HTTP 响应体。
方法二:
如下配置自定义消息转换器,并将所有转换器添加到静态列表中,以便可以从过滤器中访问
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.pvn.mvctiles")
public class ApplicationConfiguration implements WebMvcConfigurer
{
public static List<HttpMessageConverter<?>> convertersRef = new ArrayList<>();
...
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters)
{
converters.add(createXmlHttpMessageConverter());
converters.add(new MappingJackson2HttpMessageConverter());
convertersRef.addAll(converters);
}
private HttpMessageConverter<Object> createXmlHttpMessageConverter()
{
MarshallingHttpMessageConverter xmlConverter = new MarshallingHttpMessageConverter();
XStreamMarshaller xstreamMarshaller = new XStreamMarshaller();
xmlConverter.setMarshaller(xstreamMarshaller);
xmlConverter.setUnmarshaller(xstreamMarshaller);
return xmlConverter;
}
}
在你的过滤器中
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException
{
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
try
{
filterChain.doFilter(request, response);
}
catch (Exception e)
{
MyResponse myResp = new MyResponse("UUID", "500", e.getLocalizedMessage());
write(req, resp, myResp);
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private void write(HttpServletRequest req, HttpServletResponse resp, MyResponse myResp) throws IOException
{
String accept= req.getHeader("accept");
for (HttpMessageConverter messageConverter : ApplicationConfiguration.convertersRef)
{
if (messageConverter.canWrite(UserDetails.class, MediaType.valueOf(accept)))
{
HttpOutputMessage outputMessage = new ServletServerHttpResponse(resp);
messageConverter.write(myResp, MediaType.valueOf(accept), outputMessage);
}
}
}
两者都可以正常工作,但方法 1 似乎是最简单的。