SPRING MVC: How can I render ModelAndView into a string - spring

Inside Controller I need to get a rendered string and do some actions with it. This string has to be rendered out of a view. Is there a simple way of doing it?
Clarification:
I have controller
#RequestMapping(value = "/")
#ResponseBody
public String renderString() {
//I NEED TO RENDER SOME CONTENT I SAVED IN A VIEW
//I DONT WANT TO RETURN THIS CONTENT BACK TO THE BROWSER
//INSTEAD I WANT TO LETS SAY SEND CONTENT VIA EMAIL
ModelAndView view = new ModelAndView("email_template", Model);
**//QUESTION IS HERE, HOW DO I GET RENDERED STRING OUT OF VIEW/MODEL?
String emailText = view.render(); ??????????**
...sendEmail(emailText);
return "Email send";
}
Hope is more clear now

As Japs told you, I'm not sure to really understand your question, but I'll go for what I think "out of a view" means.
With Spring you can add the annotation #ResponseBody to your Controller. The String returned by the method will then be the only content of the response.
Example:
#RequestMapping(value = "/")
#ResponseBody
public String renderString() {
return "Rendered String";
}
You will get "Rendered String" at screen.

Related

How to handle two jsp forms pages in Spring MVC controller class

I have two different jsp pages one is login.jsp and form.jsp.i want to build application like ones login success then form page will open. here i am handle two jsp pages but it will show ambiguity problem.
#RequestMapping(value = "/", method = RequestMethod.GET)
public String loginModel(Model model){
model.addAttribute("loginBean",new LoginBean());
return "login";
}
#RequestMapping(value = "/", method = RequestMethod.GET)
public String model(Model model){
//FrontBean fBean=new FrontBean();
model.addAttribute("frontBean",new FrontBean());
return "form";
}
Here is your login page, it is your welcome page also
#RequestMapping(value = "/", method = RequestMethod.GET)
public String loginModel(Model model) {
model.addAttribute("loginBean", new LoginBean());
return "login";
}
then you should not add the same path to another method. change your other method to like this (change the mapping value to the second method)
#RequestMapping(value = "/welcome", method = RequestMethod.GET)
public String model(Model model){
//FrontBean fBean=new FrontBean();
model.addAttribute("frontBean",new FrontBean());
return "form";
}
You also need business logic to check the username and password. thereafter redirect to your welcome page like this. (your login.jsp should send the username and password to /check-user in post method)
#PostMapping("/check-user")
String checkUser(#RequestParam("userName") String userName , #RequestParam("passWord") String passWord){
if(userName.equals("Your username") && passWord.equals("Your password")){
return "redirect:welcome";
}
return "error";
}
Remember this is not a secure way to implement. it is just an example of an easy understanding. you can implement your own things. best of luck

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.

Redirect with GET needs relative path, why?

I am very new to Spring MVC and am seeing a rather trivial behavior I don't understand.
Bellow you can find snippets to my Controller (consider I have feed.jsp and feedList.jsp). What I don't understand is why I need the "../list" in one redirect, when the other works without it
#Controller
#RequestMapping("/feed/*")
public class FeedController {
#RequestMapping(value = "delete/{feedId}", method = RequestMethod.GET)
public String deleteFeed(#PathVariable("feedId") Integer feedId) {
feedService.delete(feedId);
return "redirect:../list";
}
#RequestMapping(value = "save", method = RequestMethod.POST)
public String saveFeed(#ModelAttribute("feed") Feed feed, BindingResult result) {
feedService.create(feed);
return "redirect:list";
}
}
Perhaps the UrlBasedViewResolver is handling view names as relative to the current request mapping url (citation needed).
Anyway, I always use context-relative absolute paths (starting with a slash): redirect:/list. Actually, if your jsp is called "feedList", then your should return redirect:/feedList

Resources