Strange behavior observed with Spring 3.1 Controller - spring

I'm using Spring 3.1 and tiles to develop a MVC app.
I have a JSP page (header.jsp) and 2 controllers (HomeController and SignupController).
The header.jsp is like this:
<s:url var="login_url" value="${loginUrl}" />
<s:url var="signup_url" value="${signUpFormUrl}" />
<a class="btn btn-primary" href="${login_url}">Login</a>
<a class="btn btn-default" href="${signup_url}">Signup</a>
The HomeController.java is like this (the /login/form URL is configured to be used by spring security as login page):
#Controller
public class HomeController {
#RequestMapping({"/", "/home"})
public String showHomePage(final Map<String, Object> model) {
return "home";
}
#ModelAttribute("loginUrl")
public String getLoginUrl() {
return "/login/form";
}
......
}
The SignupController.java is like this:
#Controller
public class SignupController {
.....
#RequestMapping(value = "/signup/form")
public String signup(#ModelAttribute SignupForm signupForm) {
return "signup/form";
}
#ModelAttribute("signUpFormUrl")
public String getSignUpFormUrl() {
return "/signup/form";
}
.....
}
What's strange is that like it is presented above I got this result when the page is rendered:
<a class="btn btn-primary" href="/appContext/login/form">Login</a>
<a class="btn btn-default" href="">Signup</a>
So the ended up with empty href value.
BUT when I moved around the signup controller code regarding the signup (the RequestMapping and the ModelAttribute method) to the home controller, it worked as expected:
<a class="btn btn-primary" href="/appContext/login/form">Login</a>
<a class="btn btn-default" href="/appContext/signup/form">Signup</a>
Is it possible to use RequestMapping from different Controller inside a same view?
Can someone has a view on what is going on here?
Thanks in advance. I can supply anything other (config?) needed to understand further the problem.

Related

Spring Web application tymeleaf : POST request directed to wrong address

I have post mapping for URL: "/bank/addnew" My controller looks like:
Upon submission the form is submitted to "http://127.0.0.1:8082/banks/%20/banks" However, I need it to go to "http://127.0.0.1:8082/banks/addnew". Thanks for the Help!
#Controller
public class BankController {
#Autowired private BankService bankService;
#GetMapping("/banks")
public String bankList() {
return "bank/bank_list";
}
#PostMapping(value="/banks/addnew")
public String addNew(Bank bank) {
bankService.save(bank);
return "redirect: /banks";
}
}
And my template:
<form method="POST" action="#" th:action="#{/banks/addnew}" >
<div class="form-group">
<label for="recipient-name" class="col-form-label">Bank Name:</label>
<input type="text" class="form-control" id="recipient-name" name="name">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
The Post Method was actually working okay. I checked it by printing the Model object inside the target controller. However, it was being submitted to the database a NULL value because I didn't initialize getters and setters for my Model. Finally, there was a space in the return string, thus I removed it.
The controller Should have a return statement with no space.
return "redirect:/banks";

How to set the login/logout link visible/invisible with Thymeleaf?

I am a beginner in Spring Framework. I try to make login and logout Thymeleaf pages. Below codes are the Spring Boot login/logout files with Thymeleaf.
First, Login Controllers codes
#Autowired
private HttpSession userSession;
#Autowired
private UserService userService;
#RequestMapping("/users/login")
public String login(LoginForm loginForm) {
return "users/login";
}
#RequestMapping(value="/users/login", method = RequestMethod.POST)
public String loginPage(#Valid LoginForm loginForm, BindingResult bindingResult) {
if(bindingResult.hasErrors()) {
userSession.setAttribute("blogLogin", false);
System.out.println("Wrong Input!!");
return "users/login";
}
if(!userService.authenticate(loginForm.getUsername(), loginForm.getPassword())) {
userSession.setAttribute("blogLogin", false);
System.out.println("login failed!!");
return "users/login";
}
userSession.setAttribute("blogLogin", true);
System.out.println("Login succesfully.");
return "redirect:/";
}
And the layout.html codes using thymeleaf.
<header th:fragment="site-header" th:remove="tag">
<header>
<a href="index.html" th:href="#{/}">
<img src="../public/img/site-logo.png" th:src="#{/img/site-logo.png}" />
</a>
Home
Log in
Log out
Register
Users
Posts
Write Post
<div id="logged-in-info"><span>Hello, <b>(user)</b></span>
<form method="post" th:action="#{/users/logout}">
<input type="submit" value="Log out"/>
</form>
</div>
</header>
</header>
The problem is I have no idea how to make login/logout link toggling codes using th:if statement of thymeleaf. As you know login link and logout link can not be displayed simultaneously.
you can check whether user is authenticated or anonymous like below and can make decisions.
<div sec:authorize="#{isAuthenticated()}">
<a th:href="#{/logout}">Log out</a>
</div>
<div sec:authorize="#{isAnonymous()}">
<a th:href="#{/login}">Log in</a>
</div>

Thymeleaf - Button click to call http delete method

I would like to call the url via http delete method. I tried th:onclick and th:action but not working.
html code:
<button id="delete" name="delete" th:onclick="#{'/foos/{id}'(id=${foo.id})}" th:method="delete">Delete</button>
controller code:
#RequestMapping(value="/foos/{id}", method = RequestMethod.DELETE)
#ResponseBody
public String delete(#PathVariable String id) {
studentService.delete(id);
return "Successfully deleted";
}
I think you will need a form for your transaction. And also this hidden input field.
<form action="#" th:action="#{'/delete/{id}'(id=${foo.id})}" th:method="delete" >
<input type="hidden" name="_method" value="delete" />
<button type="submit" id="submitButton"> </button>
</form>
The th:method="delete" creates the hidden input field automatically for you. If you add it manually as well you will have it twice. Check the source code.
I still got the POST Error message after the recommendations here. I found out Spring ignores those hidden fields by default. The solution is to activate it in your application.properties file:
spring.mvc.hiddenmethod.filter.enabled=true
My working code in my application looks like this:
Form:
<form action="#" th:action="#{'/books/delete/{id}'(id=${book.id})}" th:method="delete" >
<button type="submit" class="btn">
Delete
</button>
</form>
Controller:
#RequestMapping(value="/books/delete/{id}", method = RequestMethod.DELETE)
public String deleteBook(#PathVariable Long id) {
bookService.deleteBook(id);
return "books";
}

Redirect-Spring -MVC - how redirect control to home page?

#RequestMapping(value= "/redirect", method=RequestMethod.GET)
public String redirect()
{
return "redirect:onLogin";
}
how to redirect control back to home page? the above code for retrieving admin home page is not working.
This should work:
#RequestMapping(value= "/redirect", method=RequestMethod.GET)
public String redirect(){
return "redirect:/onLogin";
}
You can also pass parameters on redirect to show Login Failure messages, something like this:
#RequestMapping(value= "/redirect", method=RequestMethod.GET)
public String redirect(){
return "redirect:/onLogin?success=false";
}
And then in your login.jsp
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:if test="${param.success eq false}">
<div class="alert alert-danger alert-dismissible">
<button class="close" aria-hidden="true" type="button" data-dismiss="alert">×</button>
<h4><i class="icon fa fa-ban"></i> Login Failed!</h4>
</div>
</c:if>

Spring Boot newbie - Request method 'POST' not supported

There are a lot of similar questions to this, I have looked at them but still couldn't figure out what my problem is. Would really appreciate help with this.
This is my controller:
#RestController
#RequestMapping(value = "/game")
public class YatzyController {
#Autowired
private Games games;
#RequestMapping(value = "/{DiceDTO}", method = RequestMethod.POST)
public GameState putGameState(#ModelAttribute("DiceDTO") DiceDTO diceDTO) {
return null;
}
And this is my HTML:
<form method="post" enctype='application/json' action="/game">
<button type="button" onclick="rollDice()">Roll dice</button>
<div>
<input type="text" id="dice1" disabled>
<input type="checkbox" id="keepdice1" value="Keep">
</div>
<div>
<input type="text" id="dice2" disabled>
<input type="checkbox" id="keepdice2" value="Keep">
</div>
<input type="submit">
</form>
Configuration class:
#Configuration
public class YatzyConfiguration {
#Bean
public Games games(){
return new Games();
}
}
Posting to /game
You don't need value = "/{DiceDTO}" in #RequestMapping annotation, because Spring considers it as path's part. So Spring actually maps POST request to /game/somenting path in your case.

Resources