从Spring Boot Filter发送RESTFUL API JSON响应

发布于 2025-02-11 23:05:15 字数 1477 浏览 0 评论 0原文

我正在使用以下过滤器检查API请求中是否存在特定的HTTP标头。

@Component
@RequiredArgsConstructor
public class HeaderValidationFilter extends OncePerRequestFilter {
private final ObjectMapper objectMapper;

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        
String headerValue = request.getHeader("RANDOM_HEADER");

if(Objects.isNull(headerValue)) {
    ResponseEntity<Object> responseToSend = ResponseGen.create("FAILED", "Missing Authentication Header", new Object())));

    response.setHeader("Content-Type", "application/json");
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    response.getOutputStream().write(responseToSend);
    return;
}

    filterChain.doFilter(request, response);
}

它将响应返回为JSON,但添加的对象键,例如标题statuscode等,我提供的有效载荷放置在body中。由于我在项目上定义了标准错误响应,因此我无法返回响应。 (请参阅以下响应)

{
"headers": {},
"body": {
    "status": "FAILURE",
    "message": "Missing Authentication Header",
    "data": {}
},
"statusCode": "UNAUTHORIZED",
"statusCodeValue": 401
}

我希望响应仅以这种格式:

{
    "status": "FAILED",
    "message": "Missing Authentication Header",
    "data": {}
}

我尝试使用@controllerAdvice fleffers @controllerAdvice @controllerAdvice >由于它是在dispatcherservlet之前执行的,

有人可以帮助我吗?

I am using following filter for checking if a specific HTTP Header is present on api request.

@Component
@RequiredArgsConstructor
public class HeaderValidationFilter extends OncePerRequestFilter {
private final ObjectMapper objectMapper;

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        
String headerValue = request.getHeader("RANDOM_HEADER");

if(Objects.isNull(headerValue)) {
    ResponseEntity<Object> responseToSend = ResponseGen.create("FAILED", "Missing Authentication Header", new Object())));

    response.setHeader("Content-Type", "application/json");
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    response.getOutputStream().write(responseToSend);
    return;
}

    filterChain.doFilter(request, response);
}

It returns response as JSON but with added object keys like headers,statusCodeetc and the payload I provided is placed inside body. As I have a standard error response defined on the Project, I cannot return the response at it is. (See the following response)

{
"headers": {},
"body": {
    "status": "FAILURE",
    "message": "Missing Authentication Header",
    "data": {}
},
"statusCode": "UNAUTHORIZED",
"statusCodeValue": 401
}

I want the response to be only in this format:

{
    "status": "FAILED",
    "message": "Missing Authentication Header",
    "data": {}
}

I have tried returning using generic exception handler with @ControllerAdvice but it doesn't capture exception from Filters as it is executed before DispatcherServlet

Can someone help me out?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绝不放开 2025-02-18 23:05:15

您看到的JSON

{
"headers": {...},
"body": {...},
"statusCode": ...,
"statusCodeValue": ...
}

是您在过滤器中作为响应写入的序列化响应性

ResponseEntity<Object> responseToSend = ResponseGen.create("FAILED", "Missing Authentication Header", new Object())));

显然,如果您需要另一种格式的响应,则必须使用序列化的对象作为回应。例如

@Data
@AllArgsConstructor
class StandardError {
    private String status;
    private String message;
    private Object data;
}

....

@Override
protected void doFilterInternal(HttpServletRequest request, 
                                HttpServletResponse response, 
                                FilterChain filterChain) throws ServletException, IOException {
    ...
    if (Objects.isNull(headerValue)) {
        StandardError responseToSend = new StandardError("FAILED", "Missing Authentication Header", new Object());

        response.setHeader("Content-Type", "application/json");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.getOutputStream().write(responseToSend);
        return;
    }
    ...

The JSON you see

{
"headers": {...},
"body": {...},
"statusCode": ...,
"statusCodeValue": ...
}

is the serialized ResponseEntity that you write as a response in your filter:

ResponseEntity<Object> responseToSend = ResponseGen.create("FAILED", "Missing Authentication Header", new Object())));

Obviously, if you need a response in another format you'll have to use an object that is serialized to the desired format as a response. E.g.

@Data
@AllArgsConstructor
class StandardError {
    private String status;
    private String message;
    private Object data;
}

....

@Override
protected void doFilterInternal(HttpServletRequest request, 
                                HttpServletResponse response, 
                                FilterChain filterChain) throws ServletException, IOException {
    ...
    if (Objects.isNull(headerValue)) {
        StandardError responseToSend = new StandardError("FAILED", "Missing Authentication Header", new Object());

        response.setHeader("Content-Type", "application/json");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.getOutputStream().write(responseToSend);
        return;
    }
    ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文