当前位置: 首页 > 知识库问答 >
问题:

如何强制Spring Boot将正确的HTTP状态代码设置为错误响应?

欧阳安晏
2023-03-14
package com.pany.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

}
package com.pany.app;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/**").anonymous();
    }

}
package com.pany.app;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.HttpClientErrorException;

@RestController
public class MyController {

    @GetMapping(path = "/", produces = { "application/json" })
    public void home() {
        throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "This is my custom 400 Bad Request message");
    }

}
{
  "timestamp": "2020-09-14T07:24:22.061+0000",
  "status": 500,
  "error": "Internal Server Error",
  "message": "400 This is my custom 400 Bad Request message",
  "path": "/"
}

我还用Spring Boot2.3.3.Release测试了这一点...现在它甚至不再像以前那样工作了!!

{
  "timestamp": "2020-09-14T07:34:23.154+00:00",
  "status": 500,
  "error": "Internal Server Error",
  "message": "",
  "path": "/"
}

所有这些都是通过诸如ErrorControllerAbstracTerrorControllerBasicErrorController等类/接口来处理的(都在ErrorMVCautoConfiguration中设置)。显然,有一个重定向到URL/error的操作,将原始请求/和/或响应包装到其他内容中,例如,我可以将请求调试为符合以下内容:SecurityContextHolderAwareRequestWrapper[FirewalledRequest[org.apache.catalina.core.ApplicationHttpRequest@3751Bea4]]

我发现,我得到的JSON是通过一个名为DefaulTerrorAttributes的bean生成的,该bean从键“javax.servlet.error.status_code”下的请求中提取HTTP状态代码。

我在上面看到:https://github.com/spring-projects/spring-boot/issues/4694#issuecomment-163597864(2015年12月):

问题实际上是在BasicErrorController中,并且是特定于HTML响应的。错误使用由ErrorPageFilter设置的javax.servlet.error.status_code属性设置响应状态,但BasicErrorController.ErrorHTML不这样做。这将导致文本/HTML错误响应的状态为200 OK。

事实上,在我的例子中,从来没有调用errorpagefilter

{
  "timestamp": "2020-09-14T07:24:22.061+0000",
  "status": 400,
  "error": "Bad Request",
  "message": "This is my custom 400 Bad Request message",
  "path": "/"
}

多谢了。

共有1个答案

西门品
2023-03-14

@controlleradvice的一个简单替代方案是具有如下所示的自定义异常

@Slf4j
@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException{

  public NotFoundException(String message) {
    super(message);
    log.warn(message);
  }

}

使用带有@responsestatus注释的所需Http代码。

并在需要时抛出此异常

throw new NotFoundException("Your message for not found goes here");
 类似资料:
  • 在我使用的JavaSpring应用程序中,从一个叫做的第三方,我们在JSON中获得错误响应,其中包含200个响应代码。 e. g. 如何将转换为400整数表示形式。Apacheinte似乎没有提供任何这样做的接口。

  • 问题内容: 我有一个API调用,我需要对其进行一些检查并可能返回各种状态代码。我不需要自定义视图或任何东西,我只需要返回正确的代码。如果用户未通过适当的凭据,则需要返回401状态。如果他们尚未发送受支持的请求格式,则需要返回400状态。 因为它是一个API,所以我真正想做的就是设置响应状态并以一条简单的愚蠢消息退出,该消息说明请求失败的原因(可能使用)。刚好足以完成工作,但我还无法使其正常工作。我

  • 我们在前端使用OpenWeb js库,它们需要.NET中间层在发生某些类型的错误时向它们发送特定的HTTP头状态代码。我试图做到这一点: 它有点半途而废。看截图:http状态码 http://zerogravpro.com/temp/pic.png 请注意,我在响应标头中实现了状态码400,但我确实需要请求标头中的400。相反,我得到了“200 OK”。我如何实现这一点? 我用于进行调用的 URL

  • 问题内容: 在处理特定网站时,有时会收到状态码为403的http响应。在这种情况下,我想重新执行该请求(因为在我的特定情况下,该服务器实际上超载时会抛出403)。我曾尝试将a 和a 一起使用,但是它没有按我希望的方式工作;我希望在中引发异常会触发,但事实并非如此。如何获得所需的功能? 这是说明我的情况的示例代码: 问题答案: 尝试使用自定义

  • 我的服务使用WebApi。它有一个带有GET方法的控制器。当我从客户端调用它并返回未授权的状态代码时,我在HttpResponseMessage中没有得到未授权,而是没有找到。 这是我从客户端调用它的方式: < code >响应的内容: 我在 GetTest() 处放置了一个断点,它在那里停止,所以它到达了控制器方法。 为什么我在客户端中收到“未找到”,而不是“未经授权”?

  • 问题内容: 调用JAX-WS端点时,如何获取HTTP响应代码? 在下面的示例代码中,在调用Web服务时可能会引发Exception,例如或。 在这种情况下,如何从HTTP响应中获取HTTP状态代码? 问题答案: 完成@Praveen答案后,您必须将变成原始值,然后从上下文中获取值。 如果您在托管的Web服务客户端中发生异常,请不要忘记将事务标记为回滚。