Failed to load resource 405 - spring-boot

I'm a bit at a loss here.
I have a thymeleaf page and a spring-boot backend that takes in a user object, getting the object to the page is fine, my problem comes in when I'm trying to get it to the back end to do stuff with it.
I keep getting the following
2021-09-15 09:21:07.834 WARN 3624 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
and on the browser
Failed to load resource: the server responded with a status of 405 ()
for my controller I have the following
#Controller("/user")
public class UserController {
#Autowired
private UserService userService;
#Autowired
private ModelMapper modelMapper;
#RequestMapping(value = "/add")
public String addUser(#ModelAttribute("user") final UserDto userDto) {
//do stuff
//userService.save(modelMapper.map(userDto, User.class));
return "/user";
}
}
as for my thymeleaf page
<form th:action="#{/user/add}" th:object="${user}" method="post">
<label for="fullName">Full Name</label>
<input id="fullName" class="form-control form-group" type="text" th:field="*{fullName}">
<label for="email">Email</label>
<input id="email" class="form-control form-group" type="email" th:field="*{email}">
<label for="password">Password</label>
<input id="password" class="form-control form-group" type="password" th:field="*{password}">
<p>
<button class="form-group form-control btn btn-primary" type="submit" value="Submit">Submit</button>
</p>
</form>
What am I missing here?
I did try to mess around the #GetMapping, #PostMapping, #RequestMapping(method = GET), #RequestMapping(method = POST), #RequestMapping(method = {GET, POST})
I also tried <form ... th:method="post"> and <form ... th:method="get">
But none of these seems to work.

You add global /user in #Controller. this annotation is used to implement Web Application not for path and it is better to give global path in application.properties like below code. Inside addUser() method you want to return with page name like return "user" if go to the url then put return "redirect:/user"
Here down is modified code:
application.properties
server.servlet.contextPath=/user/
Controller
#Controller
public class UserController {
#Autowired
private UserService userService;
#Autowired
private ModelMapper modelMapper;
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String addUser(#ModelAttribute("user") final UserDto userDto) {
//do stuff
//userService.save(modelMapper.map(userDto, User.class));
return "pagename"; // enter page name where you wanna go not url
}
}
Template
<form th:action="#{/add}" th:object="${user}" method="post">
<label for="fullName">Full Name</label>
<input id="fullName" class="form-control form-group" type="text" th:field="*{fullName}">
<label for="email">Email</label>
<input id="email" class="form-control form-group" type="email" th:field="*{email}">
<label for="password">Password</label>
<input id="password" class="form-control form-group" type="password" th:field="*{password}">
<p>
<button class="form-group form-control btn btn-primary" type="submit" value="Submit">Submit</button>
</p>
</form>

Related

Thymleaf controller request mapping binging issue

I am new to thymleaf and at first i used simple requestmapping and thymleaf th:action and th:object to bind controller methods. But after adding class level requestmapping i cannot view my html.
below is my controller class code where i redirect to login page.
#Controller
#RequestMapping("/project")
public class MyController {
#RequestMapping(value = {"/"}, method = RequestMethod.GET)
public String login(Model model) {
model.addAttribute("mylogin", new Credentials());
return "login";
}
}
below is my html page.
<form class="user" th:action="#{/project/login}" th:object="${mylogin}" method="POST">
<div class="form-group">
<input type="email" id="user_name" name="username"
class="form-control form-control-user"
placeholder="Enter Email Address..." />
</div>
<div class="form-group">
<input type="password" id="password" name="password"
class="form-control form-control-user"
placeholder="Password" />
</div>
<button class="btn btn-primary btn-user btn-block"
name="Submit" value="Login" type="Submit" th:text="Login"></button>
</form>
after adding #RequestMapping("/project") in class i cannot fetch html. If i remove this #RequestMapping("/project") and change th:action="#{/project/login}" to th:action="#{/login}" my code works.
What can be the problem for such issue?
Change This Request mapping this way /login with class level requestmapping and try again:
#RequestMapping(value = {"/login"}, method = RequestMethod.GET)
public String login(Model model) {
model.addAttribute("mylogin", new Credentials());
return "login";
}
OR
#GetMapping("/login")
public String login(Model model) {
model.addAttribute("mylogin", new Credentials());
return "login";
}

form th:action not working using thymeleaf and spring

i am new in spring and thymeleaf, i am trying to submit a form, insert to database, but whe i am using form submission with submission it simply redirects to page and don't invoke to controller
i don't know why,
please, help
here is my Controller
#Controller
public class AdminController {
#Autowired
private CategoryServiceImpl categoryService;
#GetMapping("/adminPage")
public String index(){
return "adminPage";
}
#GetMapping("/categoryList")
public String showCategory(){
return "categoryList";
}
#GetMapping("form")
public String categoryForm(Model model, Category category){
model.addAttribute("category", category);
// model.addAttribute("add", true);
// categoryService.create(category);
return "admin/categoryForm";
}
#PostMapping("create")
public String addOrgCategory(#Valid Category orgCategory) {
categoryService.create(orgCategory);
return "redirect:/categoryList";
}
my html form is here
<form action="#" th:action="#{/create}" th:object="${category}" method="POST">
<div class="form-group">
<label for="name" class="text-dark font-bold">Category name</label>
<input id="name" type="text" class="form-control" th:value="${category} ? ${category.name} : ' '" th:field="*{name}">
</div>
<div class="form-group">
</div>
<button
type="submit" class="btn btn-success" data-toggle="tooltip"
data-placement="top" title="Tooltip on top">Create
</button>
</form>

SpringMVC UserDetailsService login

I have this class:
#Service
public class AppUserDetailsService implements UserDetailsService {
#Autowired
private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
Optional<User> optionalUser = userRepository.findByEmailAndStatus(email, UserStatusEnum.ACTIVE);
User user = optionalUser.orElseThrow(() -> new UsernameNotFoundException("Usuário e/ou senha incorretos"));
return new UserSystem(user, getPermissoes(user));
}
private Collection<? extends GrantedAuthority> getPermissoes(User user) {
Set<SimpleGrantedAuthority> authorities = new HashSet<>();
user.getPermitionList().forEach(p -> authorities.add(new SimpleGrantedAuthority(p.getCode().getDescription().toUpperCase())));
return authorities;
}
}
My html form:
<form name="login" method="POST" th:action="#{/login}">
<div class="form-group">
<input type="email" class="form-control input-lg" id="email" placeholder="Email" name="email"
required="required"/>
</div>
<div class="form-group">
<input type="password" class="form-control input-lg" id="password" placeholder="Senha" name="password"
required="required"/>
</div>
<div class="btn-group btn-group-justified" role="group">
<div class="btn-group" role="group">
<button type="button" class="btn btn-danger" onclick="showUserForm()">Cadastar</button>
</div>
<div class="btn-group" role="group">
<button type="submit" class="btn btn-default">Entrar</button>
</div>
</div>
<button type="button" class="btn btn-link wimoo-link">Esqueceu sua senha?</button>
</form>
My login Bean:
#GetMapping("/login")
public ModelAndView login(#AuthenticationPrincipal User user) {
ModelAndView mv = new ModelAndView("login");
mv.addObject(new User());
if (user != null) {
mv = new ModelAndView("masterdata/home");
return mv;
}
return mv;
}
The problem is, the User in my method 'public ModelAndView login(#AuthenticationPrincipal User user)' is always null. The method loadUserByUsername is ok, but in my bean the user is always null.
You are missing a few things. You are not binding your form details to your user in the login method. In order to do the binding do this:
On your form you have:
<div class="form-group">
<input type="email" class="form-control input-lg" id="email" placeholder="Email" name="email" required="required"/>
</div>
if you want to bind this email from your form to the email field on your User object, then if on the User class you have:
public class User{
private String myEmailAddress;
}
then on your input tag, you should add a name attribute that equals to myEmailAddress in order to bind that value from your form to your User object on your login method.
<div class="form-group">
<input type="email" name="myEmailAddress" class="form-control input-lg" id="email" placeholder="Email" required="required"/>
</div>
All you need to do now is to add the #ModelAttribute annotation to your login method in order to actually do this binding. Like this:
#GetMapping("/login")
public ModelAndView login(#AuthenticationPrincipal #ModelAttribute User user) {
ModelAndView mv = new ModelAndView("login");
mv.addObject(new User());
if (user != null) {
mv = new ModelAndView("masterdata/home");
return mv;
}
return mv;
}

Occasional null pointer exception on jsp form (java Spring Boot)

I saw some NullPointerExceptions in the log. All the exceptions are from two users. The spring controller is supposed to received the form object that the user uploaded. However it is null.
This is the jsp code of the form:
<form method="POST" action="/events/${id}/tickets/checkout" id="checkout-info-form">
<label> Recipient Name <input id="recipient" type="text" name="recipient"></label>
<label class="address-row checkout-hidable"> Address Line 1 <input id="address1" type="text" name="addressLine1"> </label>
<label class="checkout-hidable"> Address Line 2 (optional) <input id="address2" type="text" name="addressLine2"> </label>
<label class="city-row checkout-hidable"> City <input type="text" id="city" name="city" placeholder="e.g. New York"> </label>
<label class="state-row checkout-hidable"> State <input type="text" id="state" name="state" placeholder="e.g. NY"> </label>
<label class="zip-row checkout-hidable"> Zip Code <input type="text" id="zip" name="zip" placeholder="e.g. 12345"> </label>
<label class="shipping-row">Shipping Method:</label>
<label class="shipping-method">
<input type="radio" name="shipping" value="usps_5days" id="shipping1">
<span>USPS 3-5 days shipping</span> $5.99
</label>
<label class="shipping-method">
<input type="radio" name="shipping" value="usps_1days" id="shipping2">
<span>USPS overnight shipping</span> $19.99
</label>
<c:set var="index" value="${0}"/>
<c:forEach items="${tickets}" var="ticket">
<input type="hidden" name="tickets[${index}]" value="${ticket.id}">
<c:set var="index" value="${index + 1}"/>
</c:forEach>
<c:remove var="index"/>
<input id="checkout-info-form-submit-button" class="btn-blue-large" type="submit" name="submitbutton" value="Next step">
</form>
This is the model object that I use to receive the form:
public class CheckoutInfo implements Serializable {
private static final long serialVersionUID = 2585075011792338943L;
private String recipient;
private String addressLine1;
private String addressLine2;
private String city;
private String state;
private String zip;
private String shipping;
private String[] tickets;
public CheckoutInfo() {
}
}
The controller:
#RequestMapping(value="/events/{eventId}/tickets/checkout", method=RequestMethod.POST)
public ModelAndView purchaseTickets(
#PathVariable("eventId") long id,
CheckoutInfo checkoutInfo,
RedirectAttributes redir,
#AuthenticationPrincipal User user) {
......
}
The null pointer exception occurs because checkoutInfo is null. I don't know why this could happen. I never seen this happen. And this only come from a few of our users. I am using spring boot v1.2.3.RELEASE
I appreciate it if anyone could help.

Cannot submit a form on SpringMVC

I am fairly new to SpringMVC and have a form that can not submit to the back-end. I created the form as following and when I submit it error 404 will be returned. I changed action to /MyProject/contact but did not work.
<form class="form-horizontal" role="form" method="post"
action="/contact">
<div class="form-group">
<div class="col-md-12">
<label class="sr-only" for="exampleInputName2">Name
</label> <input type="text" class="form-control" id="name"
name="name" placeholder="Your name" value="">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<label class="sr-only" for="exampleInputName2">Email
Address</label> <input type="email" class="form-control" id="email"
name="email" placeholder="Your email" value="">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<label class="sr-only" for="exampleInputName2">Phone
Number</label> <input type="number" class="form-control" id="phone"
name="phone" placeholder="Phone number" value="">
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<label class="sr-only" for="exampleInputName2">Enquiry</label>
<textarea class="form-control" rows="4" name="message"
placeholder="Please enter your enquiry"></textarea>
</div>
</div>
<div class="form-group">
<div class="col-md-2 " style="float: right;">
<input id="submit" name="submit" type="submit" value="Send"
class="btn btn-primary">
</div>
</div>
<div class="form-group">
<div class="col-sm-10 col-sm-offset-2">
<! Will be used to display an alert to the user>
</div>
</div>
</form>
Controller
#Controller
public class ContactController {
#RequestMapping(value="/contact", method=RequestMethod.POST)
public String processForm(Contact contact, Model model){
System.err.println("Contact Name is:" + contact.getName());
return null;
}
}
Error
HTTP Status 404 - /contact
type Status report
message /contact
description The requested resource is not available.
Its beacuse spring does not know how to pass the param Contact contact to your controller method. You need to do couple of things to make it work. Change your form to like below.
<form class="form-horizontal" role="form" method="post" modelAttribute="contact" action="/contact">
Your controller to take contact as model attribute.
#Controller
public class ContactController {
#RequestMapping(value="/contact", method=RequestMethod.POST)
public String processForm(#ModelAttribute Contact contact, Model model){
System.err.println("Contact Name is:" + contact.getName());
return null;
}
}
For a better understanding of what a model attribute does, there are plenty of samples and explanation online. Hope this helps.
I could solve the problem by help of minion's answer, following this tutorial and adding following link
#RequestMapping(value = "/contact", method = RequestMethod.GET)
public ModelAndView contactForm() {
System.err.println("here in GET");
return new ModelAndView("contact", "command", new Contact());
}

Resources