Pass #ModelAttribute to href Spring MVC - spring

I'm attempting to pass a calculated URL from server-side via #ModelAttribute and sometimes the href attribute in html (where I allocate this #ModelAttribute) appears to be empty and need to do multiple ctrl-f5 for finally set the URL.
My controller has something like that:
#Controller
....
String calculatedURL = calculateURL(request, user);
if(StringUtils.isBlank(calculatedURL)){
throw new Exception("Error calculating URL");
}
model.addAttribute("calculatedURL",calculatedURL);
return "myPage";
And in my JSP:
myLink
The problem is that sometimes this href value is "".
I tried to evaluate if calculatedURL is null or blank in my controller and throw exception if is it. This never happens and calculatedURL allways is passed with value.
Thanks in advance and so sorry for my English.
David.

Related

how to access redirectAttributes.addFalshAttributed value in hbs(handlebars) file

#PostMapping("/upload") // //new annotation since 4.3
public String singleFileUpload(#RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) {
if (file.isEmpty()) {
redirectAttributes.addFlashAttribute("message", "Please select a file to upload");
return "redirect:uploadStatus";
}
try {
// Get the file and save it somewhere
byte[] bytes = file.getBytes();
Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());
Files.write(path, bytes);
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded '" + file.getOriginalFilename() + "'");
} catch (IOException e) {
e.printStackTrace();
}
return "redirect:/uploadStatus";
}
how to access message value of above code.
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<h1>Spring Boot - Upload Status</h1>
<h2>{{message}}</h2>
</body>
</html>
The above code can't access message value. how to access in handlebars file.
I want to show string of message variable.
Not any special treatment for flash attribute. It is same like model attribute with redirection.
Change this
<h2>{{message}}</h2>
to
<h2>${message}</h2>
You are missing the $ or # symbol depends on how you want to resolve your expression. Use something like below:
<h2 th:text="${message}"><h2>
Please check the standard expression syntax section standarddialect5minutes
Your handlebars variable reference in your html is actually correct as-is.
If your redirect is routed through the controller (as in, if your GET method for updateStatus is defined in your controller), then you may need to follow what I described in an answer I gave to a similar question here. Basically, when using RedirectAttributes in a PRG situation, all you need to do is:
Include RedirectAttributes as parameter to the POST method signature
Set the attribute you want via addFlashAttribute within the POST method
Include a #ModelAttribute annotated parameter in the GET method signature which references the flash attribute
You did not post your updateStatus GET method code so I cannot see what you are doing in it, but if you are doing anything like trying to set that attribute on the model directly that will inadvertently cause the flash attribute to be overwritten.
If I had to guess, I would say the problem is that you are missing the #ModelAttribute annotated parameter within the GET method signature.
If you are using a mustache, then
{{ message }} <- I thinks it's not a problem.
now try
{{#msg}}
{{msg}}
{{/msg}}
'#' and '/' annotes starting and end point. For me, without it, error occured saying
there's no method for message.

How do I return a template(thymeleaf) in spring boot and resolve it to a particular endpoint

Short: I want to use Thymeleaf template index.html but have the url point to thanks.html.
In depth: I am trying to have a form submission take my user to a page http://localhost:8080/thanks.html. I dont want the action of the form to be thanks.html for a few different reasons but I have greatly simplified the logic below. When all of the validation of the form are passed, I want to pass in a variable to indicate which layout to use. I have that working by using a model variable called contentPage. The problem is that if i have "return "thanks.html";" in the indexSubmit Method I get an error from thymeleaf saying template not found. If I change that to "return "index.html"; everything works but the url is http://localhost:8080/ instead of http://localhost:8080/thanks.html.
#PostMapping("/")
public String indexSubmit(Model model) {
model.asMap().clear();
model.addAttribute("contentPage","layout/thanks.html");
return "thanks.html";
}
#GetMapping("/thanks.html")
public String thanks(Model model) {
model.addAttribute("contentPage","layout/thanks.html");
return "index.html";
}
I fond an answer on my own:
return "redirect:thanks.html";
Thanks,
Brian

Why I can't redirect from a Spring MVC controller method to another controller method?

I am pretty new in Spring MVC and I have some problem trying to redirect to a controller method after that another controller method terminate its execution.
So I have the following situation. Into a controller class I have this method that correctly handle POST request toward the validaProgetti resource:
#RequestMapping(value = "validaProgetti", method=RequestMethod.POST)
public #ResponseBody String validaProgetti(#RequestBody List<Integer> checkedRowList) {
System.out.println("ID progetti da aggiornare: " + checkedRowList);
List<Twp1007Progetto> progettiDaValidare = new ArrayList<Twp1007Progetto>();
for (int i=0; i<checkedRowList.size(); i++) {
System.out.println("ID PROGETTO: " + checkedRowList.get(i));
progettiDaValidare.add(progettoService.getProgetto(checkedRowList.get(i)));
}
progettoService.validaProgetti(progettiDaValidare);
return "redirect:ricercaValidazione";
}
So this method is correctly mapped and when the validaProgetti resource is called it is executed.
At the end of this method I don't return a view name that render a JSP page but I have to redirect to another method (that do something and render a JSP page). So, instead to return a view name, I redirect toward another resource:
return "redirect:ricercaValidazione";
Then in the same controller class I have declared this method that handle request toward this ricercaValidazione resource:
#RequestMapping(value = "ricercaValidazione", method=RequestMethod.POST)
public String ricercaValidazione(#ModelAttribute ConsultazioneFilter consultazioneFilter, Model model, HttpServletRequest request) {
RicercaConsultazioneViewObject filtro = null;
try {
filtro = new ObjectMapper().readValue(request.getParameter("filtro"), RicercaConsultazioneViewObject.class);
filtro.setSelStatoProgetto(3); // Progetti da validare
} catch (IOException e) {
logger.error(e);
}
consultazioneFilter = new ConsultazioneFilter(filtro);
model.addAttribute("consultazioneFilter", consultazioneFilter);
model.addAttribute("listaProgetti", new ListViewObject<Twp1007Progetto>(progettoService.getListaProgettiConsultazione(consultazioneFilter)) );
return "validazione/tabellaRisultati";
}
The problem is that it can't work and after the redirection can't enter into the ricercaValidazione() method.
I think that maybe the problem is that this ricercaValidazione() method handle POST request toward the ricercaValidazione resource and the return "redirect:ricercaValidazione"; maybe generate a GET request.
But I am not sure about it.
Why? What am I missing? How can I solve this issue?
Tnx
the redirect and fordward prefix are for resolving views; you are tring to redirect from one controller to another one. This can be done but redirect works in the following way
A response is sent to the browser with the redirect http status code and and url
The browser loads via GET the request URL
Your Spring controller (and the corresponding ammping method) is invocated if it matches the annotation params
From what you write I'm not sure this is what you really want; as you already noted there is a mismatch between HTTP methods (GET vs POST).
Your second method ricercaValidazione expects a filtro param in order to filter some data, but in the validaProgetti there is nothing similar, so it seems that the two controllers are not directly chainable. If what you want is to display a page after validaProgetti that shows a form and the the user can submit it you must add a method annotated with a method GET and url ricercaValidazione; the new method must return the view containing the form; which points via POST to url of validaProgetti. In this way you can redirect from ricercaValidazione to validaProgetti
Give mapping name of your controller with redirect like
redirect:/controll-mapping_name/ricercaValidazione
have a look on this question
Unable to redirect from one controller to another controller-Spring MVC

Spring Jsps and Jumping to Anchors

I was wondering if there is some way in Spring to specify in the controller that I would like to send the client to a specific anchor within the .jsp page that I am using for my view.
I have a section in my .jsp page, identified by an #errors anchor, that displays any form errors that occur. I would like to be able to send them directly to that anchor whenever I need to send them back to the .jsp after model validation fails.
Inside my controller classes, I handle validation errors like so:
if (result.hasErrors())
{
for (ObjectError error : result.getAllErrors())
{
logger.debug("Validation Error: " + error.getDefaultMessage());
}
ModelAndView mv = new ModelAndView();
mv.setViewName("/secure/formViews/newAdminBookingMenu");
mv.addObject(BindingResult.MODEL_KEY_PREFIX + "booking", result);
return mv;
}
I would like to be able to specify in that code block that when the client gets the rendered newAdminBookingMenu.jsp back that they are sent directly to the #errors anchor tag within that page.
I obviously cannot do this by just adding #errors to the name of the .jsp i wish to render as the InternalResourceViewResolver will interpret the view as /WEB-INF/jsp/jspName#errors.jsp which is clearly incorrect.
I know this can be accomplished with javascript and the onload event but I find that kind of dirty and would really rather find a Spring approach if one exists.
Any ideas?
Cheers.
Perhaps a RedirectView is an option:
modelAndView.setView(new RedirectView("error/page#errors", true));
Reference:
15.5.3.1 RedirectView

passing data in querystring when using tiles

I am using tiles2 and spring in my project. When i am redirecting from spring controller to a jsp(the jsp page is mapped in tiles.xml file) page using query string like:
return "showRes.jsp?subSucc=ok";
it shows me:
javax.servlet.ServletException: Could not resolve view with name 'showRes.jsp?subSucc=ok'
I think this is wrong way to passing data using query string.
Please tell me how can i do this.
Thanks
Shams
The Problem is that return "showRes.jsp?subSucc=ok"; statment should return the name of a jsp and it is NOT a URL.
The normal Spring way to pass values is a jsp is to use a Model Map (of course there are some other ways, but this is the easysest to describe one).
Have a look at the ModelAndView and Model class. Create an instance of it, set the view name and add your parameter, and then return it instead of the String.
Model model = new Model();
model.addAttribute("subSucc","ok");
ModelAndView modelAndView = new ModelAndView("showRes.jsp", model);
//may without ".jsp" postfix - this depends on your configuration
return modelAndView;

Resources