【问题标题】:405 Request method 'POST' not supported when testing spring application测试spring应用程序时不支持405请求方法'POST'
【发布时间】:2018-06-06 00:09:00
【问题描述】:

我准备并扩展了这个运行良好的existing spring example。您可以简单地使用“用户”和“密码”登录,然后您会被转发到用户/索引。

使用这个控制器

@Controller
public class LoginController {
    @GetMapping("/login")
    public String login() {
        return "login";
    }

    @GetMapping("/login-error")
    public String loginError(Model model) {
        model.addAttribute("loginError", true);
        return "login";
    }
}

但是一旦我运行使用 WebClient 的示例测试,相同的登录就会导致异常:

com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException: 405 Request method 'POST' not supported for http://localhost:8080/login

这很奇怪,因为应用程序本身运行良好。

编辑:这是导致问题的测试方法

@And("^the user clicks the login button$")
public void theUserClicksTheLoginButton() throws IOException {
    page = page.getElementById("login").click();
}

没想到WebClient的click方法是使用POST,而不是真正执行html中的输入字段。

<form th:action="@{/login}" method="post">
    <label for="username">Username</label>:
    <input type="text" id="username" name="username" autofocus="autofocus" /> <br />
    <label for="password">Password</label>:
    <input type="password" id="password" name="password" /> <br />
    <input type="submit" id="login" value="Log in" />
</form>

编辑 2: 好吧,也许我应该澄清一下我的问题。 我知道应该通过 POST 进行登录,而我的 @Controller 只提供 @GetMapping 但这没关系,因为 spring security 正在处理 POST 请求,正如我在登录时在标题中看到的那样:

我的问题是为什么它在运行应用程序时工作正常,以及为什么在使用 WebClient 时它没有相同的行为

【问题讨论】:

  • 你在使用 Spring Security 吗?
  • 是的,我愿意 -> 查看 build.gradle 和 org.springframework.security.samples.config.SecurityConfig 的依赖项
  • Spring Security 提供了一个登录控制器,可以通过覆盖configure(HttpSecurity http) 方法来设置。
  • 这应该是为了测试目的,让应用程序的行为与正常运行应用程序的方式相同?
  • 这在 SecurityConfig.java link987654323@ 中已经完成了

标签: java spring-mvc spring-boot htmlunit spring-mvc-test


【解决方案1】:

我对使用 Cucumber 设置 Spring 不是很熟悉,我不确定在同一设置中混合使用 SpringRunnerCucumber 跑步者。

我已经像这样更新了你的测试设置:

@RunWith(SpringRunner.class)
@WebMvcTest
@ContextConfiguration
@Import(SecurityConfig.class)
public class LoginFeatureStepDefinition {
    private String username;
    private String password;
    private HtmlPage page;

    @Autowired
    private WebClient webDriver;
  1. 我已将@SpringBootTest 替换为@WebMvcTest,因为mockmvc 自动配置将为您处理webclient 设置。如果您想用整个应用程序启动一个实际的服务器并使用 HTTP 客户端对其进行测试,您需要设置 @SpringBootTest in a different way
  2. 在 MockMvc 设置中,安全配置默认不导入,所以需要导入

【讨论】:

    【解决方案2】:

    Web 客户端通过 POST 请求调用服务,导致异常:Request method 'POST' not supported。服务端看起来不错。

    【讨论】:

    • 是的,我也从异常中意识到。问题是如何执行登录,以便真正的用户点击登录。
    • 尝试将映射更改为@Postmapping
    • 那不是我真正想要的。我试图理解为什么如果真正的用户点击它,@Postmapping 是不必要的,而 WebClient 需要它。这种行为对我来说没有意义,我期待同样的行为。
    • &lt;form th:action="@{/login}" method="post"&gt; -> 因为 UI 方法是 POST,所以它永远不会到达 get 映射。您得到的异常是正确和预期的。 GET 应该用于检索数据。我们只能通过 URL 或请求标头发送参数。 POST 用于将数据发送到服务器。提交表格只能在 POST 中完成。用户名和密码不应通过URL 参数发送,而是通过请求正文发送。
    • 是的,我完全同意你的看法,但这不是我的问题。我编辑了我的帖子,希望我的问题更清楚一点。
    猜你喜欢
    • 2014-06-10
    • 2017-07-01
    • 1970-01-01
    • 2020-08-12
    • 2020-07-24
    • 2017-05-03
    • 2016-06-16
    • 1970-01-01
    • 2012-06-24
    相关资源
    最近更新 更多