Я подготовил и расширил этот существующий пример весны, который работает нормально. Вы можете просто войти в систему с помощью «пользователя» и «пароля», и после этого вы будете перенаправлены к пользователю / индексу.
Используя этот контроллер
@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();
}
Я не ожидал, что метод click WebClient использует 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>
Обновлено еще раз:
Хорошо, может быть, мне нужно немного пояснить свой вопрос.
Я знаю, что вход в систему должен выполняться через POST, и мой @Controller предоставляет только @GetMapping, но это нормально, потому что Spring Security обрабатывает запросы POST, как я могу видеть в заголовке при входе в систему:
Мой вопрос - почему он работает нормально при запуске приложения и почему у него нет такого же поведения при использовании WebClient.
Да, я знаю -> см. Зависимости от build.gradle и org.springframework.security.samples.config.SecurityConfig
Spring Security предоставляет контроллер входа в систему, который можно настроить, переопределив метод configure(HttpSecurity http).
И это нужно сделать в целях тестирования, чтобы приложение вело себя так же, как обычное приложение?
В любом случае этого не происходит в SecurityConfig.java ссылка на сайт




Веб-клиент вызывает службу через запрос POST, который вызывает исключение: Request method 'POST' not supported. Сторона службы выглядит хорошо.
Да, это я тоже понял из исключения. Вопрос в том, как выполнить логин, чтобы он работал так, как если бы реальный пользователь нажимал на логин.
Попробуйте сменить сопоставление на @Postmapping
Это не совсем то, что я ищу. Я пытаюсь понять, почему @Postmapping не нужен, если реальный пользователь нажимает на него, а WebClient он нужен. Для меня такое поведение не имеет смысла, я ожидаю того же поведения.
<form th:action = "@{/login}" method = "post"> -> Он никогда не достигнет отображения получения, поскольку метод пользовательского интерфейса - POST. Полученное вами исключение является правильным и ожидаемым. GET следует использовать для получения данных. Мы можем отправлять параметры только через URL или заголовки запроса. POST используется для отправки данных на сервер. Отправка форм должна производиться только в режиме POST. имя пользователя и пароль следует отправлять не через параметры URL, а через тело запроса.
Да, я полностью согласен с вами, но это не мой вопрос. Я отредактировал свой пост, чтобы, надеюсь, прояснить мою проблему.
Я не очень знаком с настройкой Spring с Cucumber, и я не уверен, что смешиваю как SpringRunner, так и Cucumber runner в одной настройке.
Я обновил вашу тестовую установку следующим образом:
@RunWith(SpringRunner.class)
@WebMvcTest
@ContextConfiguration
@Import(SecurityConfig.class)
public class LoginFeatureStepDefinition {
private String username;
private String password;
private HtmlPage page;
@Autowired
private WebClient webDriver;
@SpringBootTest на @WebMvcTest, так как автоконфигурация mockmvc позаботится о настройке веб-клиента за вас. Если вы хотите запустить реальный сервер со всем приложением и протестировать его с помощью HTTP-клиента, вам необходимо настроить @SpringBootTestпо-другому.
Вы используете Spring Security?