Getting 404 error calling another JSP from link - spring

I have a menu in my web page, and I have added a new link is not working. I am getting this error message.
HTTP Status 404 – Not Found
Type Status Report
Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
Here is the HTML code for the link.
<td><img src="images/menu/35-year-reunion.jpg" alt="Memories" /></td>
I do have a Spring controller method, and this is it. My web page is named reunion2021.jsp.
#RequestMapping(value = "/35yearreunion")
public String thirtyfiveYearReunion(Model model) {
return "reunion2021";
}

Try adding the request method to your controller's method , either this way :
#RequestMapping(value = "/35yearreunion",method = RequestMethod.GET)
public String thirtyfiveYearReunion(Model model) {
return "reunion2021";
}
or this way :
#GetMapping(value = "/35yearreunion")
public String thirtyfiveYearReunion(Model model) {
return "reunion2021";
}

Related

Problems implementing an easy REST service - Spring MVC

I have a Springboot application (a videoclub application). I do not think it is necessary to show you all the code as it would be very verbose. But it works fine.
A class Film, and FilmRepository with some methods, a controller, database JPA, and the HTML files. Everything works fine. I am not looking for a code solution, but more for a "conceptual" solution, just to know if I am implementing properly the REST service.
I want to add now a really easy REST service (adding a class "MyRestController") that will search for a film just by adding the name of it in the URL.
So apart from my Controller, I want to add this RestController just to do this simple thing: If I add the name of a film in the URL, it will search for it with the normal MVC methods.
But adding what I think is the solution gives me this error:
There was an unexpected error (type=Not Found, status=404).
No message available
So when going through the HTML content to the page to search for the film, and adding to that /buscar the film name (which I have in the db) /buscar/Interstellar, it shows the before error.
#CrossOrigin
#RestController
public class MyRestController {
#Autowired
private FilmRepository filmRepo;
#RequestMapping(value = "/buscar", method = RequestMethod.GET)
public ResponseEntity<List<Film>> getFilms(#RequestParam String Title) {
List<Film> pelis = (List<Film>) filmRepo.findByTitle(Title);
HttpStatus status = HttpStatus.OK;
ResponseEntity<List<Film>> response = new ResponseEntity<>(pelis, status);
return response;
}
}
Getting this error makes me think the page knows it has to do something, but might be having trouble getting it (due to strings, iterable things, lists, or that sort of problem, JSON maybe). But I do not know if the "theory" behind the rest service is alright in MyRestController.
Film repository:
public interface FilmRepository extends CrudRepository<Film, Long>{
Iterable<Film> findByTitle(String Title);
}
(The MVC method in the normal controller)
#RequestMapping("/buscar")
public ModelAndView processSearch(#RequestParam(value = "title", required = false) String title) {
if (title == null || title == "") {
Iterable<Film> films = filmRepo.findAll();
return new ModelAndView("buscar").addObject("films", films);
}
Iterable<Film> films = filmRepo.findByTitle(title);
return new ModelAndView("buscar").addObject("films", films);
}
What you're talking about is a #PathVariable
#RequestMapping(path={"/buscar","/buscar/{title}"})
public ModelAndView processSearch(#PathVariable(value = "title", required=false) String title) {
In the end, the problem was with the #RequestParam, which makes you search in the URL with a query like: /buscar?Title=Interstellar
#RequestMapping(value = "/buscar/{title}", method = RequestMethod.GET)
public ResponseEntity<List<Film>> getFilms(#PathVariable String title) {
List<Film> pelis = (List<Film>) filmRepo.findByTitle(title);
HttpStatus status = HttpStatus.OK;
ResponseEntity<List<Film>> response = new ResponseEntity<>(pelis, status);
return response;
}
With this REST service, you can search by URL like "/buscar/Interstellar".
The result is going to give you JSON content with all the information of the Object Film.

Spring MVC: #valid validation failed: going back to same page

so,
I have Spring MVC, #Valid annotation.
On my home page I have search box, and some other stuf printed on the page which is read from database when we visit that page,
Now, when someone hits search button without putting anything the text box, .hasErrors() is true and return "index" which is same page.
the issue is that when I get back to the same page only the search box and search button and error message is there but everything else (the stuff read from database) is no more visible.
its probably because its not being served by same controller method, but what do I do to keep the page same?
Method populating the initial view:
#RequestMapping(value = "/" , method = RequestMethod.GET)
public String indexPage(Model model, HttpServletRequest request){
List<Ad> ads = adDao.getAll();
model.addAttribute(ads);
// this below is added for data binding.
model.addAttribute("adSearchForm",new AdSearchForm());
return "index";
}
Method when someone tries to search
#RequestMapping(value = "/search", method = RequestMethod.POST)
public String searchAds(Model model,#Valid #ModelAttribute("adSearchForm") AdSearchForm adSearchForm,
BindingResult result,
HttpServletRequest request
){
if(result.hasErrors()){
return "index";
}
List<Ad> ads = adDao.searchAds(adSearchForm.getSearchTerm());
model.addAttribute("searchresults",ads);
return "searchResults";
}
so when /search request is served, the data read by first method above is not visible on index page.
It just works this way. When i have more than 2/3 elements which i need to add to model and there is some form with binding result i usually create private method like this:
private void initModel(Model model)
{
model.addAttribute("attr1", //getAttrFromDb
model.addAttribute("attr2", //getAttrFromDb
//more attributes...
}
And use it in GET and POST methods..

Avoid Spring MVC form resubmission when refreshing the page

I am using spring MVC to save the data into database. Problem is it's resubmitting the JSP page when I am refreshing the page.
Below is my code snippet
<c:url var="addNumbers" value="/addNumbers" ></c:url>
<form:form action="${addNumbers}" commandName="AddNumber" id="form1">
</<form:form>
#RequestMapping(value = "/addNumbers", method = RequestMethod.POST)
public String addCategory(#ModelAttribute("addnum") AddNumber num){
this.numSrevice.AddNumbers(num);
return "number";
}
You have to implement Post/Redirect/Get.
Once the POST method is completed instead of returning a view name send a redirect request using "redirect:<pageurl>".
#RequestMapping(value = "/addNumbers", method = RequestMethod.POST)
public String addCategory(#ModelAttribute("addnum") AddNumber num){
this.numSrevice.AddNumbers(num);
return "redirect:/number";
}
And and have a method with method = RequestMethod.GET there return the view name.
#RequestMapping(value = "/number", method = RequestMethod.GET)
public String category(){
return "number";
}
So the post method will give a redirect response to the browser then the browser will fetch the redirect url using get method since resubmission is avoided
Note: I'm assuming that you don't have any #RequestMapping at controller level. If so append that mapping before /numbers in redirect:/numbers
You can return a RedirectView from the handler method, initialized with the URL:
#RequestMapping(value = "/addNumbers", method = RequestMethod.POST)
public View addCategory(#ModelAttribute("addnum") AddNumber num,
HttpServletRequest request){
this.numSrevice.AddNumbers(num);
String contextPath = request.getContextPath();
return new RedirectView(contextPath + "/number");
}
My answer shows how to do this, including validation error messages.
Another option is to use Spring Web Flow, which can do this automatically for you.

How to use send.redirect() while working with Spring MVC

I was trying to redirect to a dynamic page from Interceptors and Handler Mapping program. I have already defined a controller which handles and redirects (/hello.htm) through model (I have only this controller in my program). Until this point it is working fine. Apart from this, I registered a handler which will redirect to a page once it satisfies some condition.
public class WorkingHoursInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("In Working Hours Interceptor-pre");
Calendar c=Calendar.getInstance();
if(c.get(Calendar.HOUR_OF_DAY)<10||c.get(Calendar.HOUR_OF_DAY)>20){
response.sendRedirect("/WEB-INF/jsp/failure.jsp");
return false;
}
return true;
..............
..............
}
But once it comes to response.sendRedirect, it is showing resource not found even though the mentioned page is present. I tried to redirect to "WEB-INF/jsp/hello.jsp" as well but keeps showing the same error. If the condition in the interceptor is not satisfied, the program works fine.
Below is shown the only controller present in the program.
#Controller
public class MyController {
#RequestMapping("/hello.htm")
public ModelAndView sayGreeting(){
String msg="Hi, Welcome to Spring MVC 3.2";
return new ModelAndView("WEB-INF/jsp/hello.jsp","message",msg);
}
}
(The controller for handling hello.html works fine if I change the interceptor condition)
Instead of redirecting, if I just print a message in the console, the program works fine. But once it comes to redirect it shows the error. Do I need to specify a separate controller to handle this request? Will this redirection request go to the dispatcher-servlet?
You need to add redirect: prefix in the view name, the code for redirect will look like:
#RequestMapping(value = "/redirect", method = RequestMethod.GET)
public String redirect() {
return "redirect:finalPage";
}
OR
#RequestMapping(value = "/redirect", method = RequestMethod.GET)
public ModelAndView redirect() {
return new ModelAndView("redirect:finalPage");
}
You may get a detail description from here:
enter link description here

Spring MVC form:errors not showing up

Apologies if this question has been asked before. I'm hoping that someone can step in and help me figure out why my form validation errors aren't showing up.
I'm using Spring 3.0.3 and Hibernate, and I'm using jsr-303 validation to validate my form inputs. I have a Spring controller that handles GETting a page that contains a form that is created with the help of Spring's form taglib. In this form a user is able to change their name and have it saved to the database. If any of the input is empty then the page with the form should be displayed again with error messages. The same controller handles the page's submission. It seems that the controller is functioning properly in most respects, but when there is an error in the user submitted form, no errors are showing up on the page.
Here is what form looks like:
<form:form commandName="changeNameCommand">
<form:errors path="*" cssClass="errorBox" />
<table width="100%" border="0" cellspacing="5" cellpadding="5" align="left">
<tr>
<td><b>First Name:</b></td>
<td><form:input path="firstName" value="${user.firstName}" /></td>
</tr>
<tr>
<td><b>Last Name:</b></td>
<td> <form:input path="lastName" value="${user.lastName}" /></td>
</tr>
</table>
</form:form>
Note that there is a user object in the view that is used to populate the form with the user's current first and last name. This is working properly.
The controller looks something like this:
#Controller
#RequestMapping(value = "/account/settings/change-name")
#SessionAttributes("changeNameCommand")
public class ChangeNameController {
#ModelAttribute("changeNameCommand")
public ChangeNameCommand getCommand() {
return new ChangeNameCommand();
}
#RequestMapping(method = RequestMethod.GET)
public ModelAndView getChangeNamePage(HttpServletRequest req) {
ModelAndView mav = new ModelAndView("Account.ChangeName");
mav.addObject("page_title", "Change Name");
return mav;
}
#RequestMapping(method = RequestMethod.POST)
public String doChangeName(
#ModelAttribute("changeNameCommand")
#Valid ChangeNameCommand command,
BindingResult result, SessionStatus status) {
if (result.hasErrors()) {
return "redirect:/account/settings/change-name";
}
// Code here to persist updated user first and last name to database...
status.setComplete();
return "redirect:/home";
}
}
I'm using Tiles 2.1.2 to compose pages and Urlrewrite 3.1.0 to help form friendly urls.
The ChangeNameCommand class looks something like this:
import org.hibernate.validator.constraints.NotEmpty;
public class ChangeNameCommand {
#NotEmpty(message = "You must provide a first name.")
private String firstName;
#NotEmpty(message = "You must provide a last name.")
private String lastName;
#NotEmpty(message = "Your password is required to make changes.")
private String currentPassword;
// Getters and setters here...
}
When debugging, I see that when there is not input for either the first or last name the BindingResult instance does contain errors. My concern is the redirect when there is an error. I've seen other questions here that just return the view name instead of using the redirect: prefix. I tried that but (I think) because of the way I'm using Urlrewrite and the way my servlet mapping is set up Spring returns an error. I've tried returning
/account/settings/change-name
/web/account/settings/change-name
/mywebsite/web/account/settings/change-name
but to no avail. FWIW, here is my servlet-mapping:
<servlet-mapping>
<servlet-name>mywebsite</servlet-name>
<url-pattern>/web/*</url-pattern>
</servlet-mapping>
Any help much appreciated!
using redirect makes all request attributes (including errors and the whole model) disappear. So, don't use redirect, or use the session to temporarily store the data, or use conversations. Or figure out how to use something like a flash-scope (I'm about to in a while)
Another thing - using UrlRewriteFilter with spring-mvc is uncalled for. You have full control over your beatuful REST-like URLs with spring-mvc only.
Here is how I solved my problem. To start off with, I didn't want to drop my use of UrlRewriteFilter and Tiles. However, the problem with this was that, in the case of errors, I couldn't just return the path, as indicated in the controllers RequestMapping annotation. Below is my solution, with the redirect removed in the case of errors, in doChangeName().
#Controller
#RequestMapping(value = "/account/settings/change-name")
#SessionAttributes("changeNameCommand")
public class ChangeNameController {
#ModelAttribute("changeNameCommand")
public ChangeNameCommand getCommand() {
return new ChangeNameCommand();
}
#RequestMapping(method = RequestMethod.GET)
public ModelAndView getChangeNamePage() {
ModelAndView mav = new ModelAndView("Account.ChangeName");
mav.addObject("page_title", "Change Name");
return mav;
}
#RequestMapping(method = RequestMethod.POST)
public ModelAndView doChangeName(#ModelAttribute("changeNameCommand") #Valid ChangeNameCommand command,
BindingResult result, SessionStatus status) {
if (result.hasErrors
ModelAndView mav = new ModelAndView("Account.ChangeName");
mav.addObject("page_title", "Change Name");
return mav;
}
// Code here to persist updated user first and last name to database...
status.setComplete();
RedirectView view = new RedirectView("/home");
return new ModelAndView(view);
}
}
Thanks to everyone who helped me out on this!

Resources