I want to assign Object field eg. greeting.method (which can be post or get ) to Form Method attribute using thymeleaf spring boot - spring

Generally the code is -->
Image of code, click here to see the code!
I want that method which is hardcoded as "post" need to come from greeting object eg. (greeting.method)
How can I achieve that any suggestions?

So just to make it clear, you want to read the url action and method from a variable, instead of hardcoding them in thymeleaf
In that case that is actually very simple:
Pass url and method variables to the model by defining the following in your controller
#ModelAttribute("url") public String url() { return "foo/bar"; }
#ModelAttribute("method") public String method() { return "POST"; }
Define the url and method with thymeleaf: <form th:action="${url}" th:method="${method}" ...>

Related

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

An issue in loading a Thymeleaf fragment inside the controller, the fragment name is being returned

Trying to manipulate a Thymeleaf fragment inside a Java Spring Boot Controller.
According to the link, in order to load the content of the Thymeleaf fragment inside the controller, all we need to do is the following
return "fragments/customerSearch :: customersTable";
While in my case, the following script results in only the String: "fragments/customerSearch :: customersTable" returned:
private String getDocumentsByTransaction(Transaction transaction) {
return "fragments/block-document :: popup(transaction)";
}
inside another function:
...
String documents = getDocumentsByTransaction(transaction);
...
Is there anything missing to load the content of the fragment instead of the fragment name as a static string?
return "fragments/customerSearch :: customersTable"; only works if the method is actually a controller method, and you're going through the entire MVC process.
In your example case, it should look like this:
#Controller
public class WhateverController {
#GetMapping("/page")
private String getDocumentsByTransaction() {
return "fragments/block-document :: popup";
}
}
Now if you access /page in your browser, it will return a fragment rather than an entire page. You also can't just call getDocumentsByTransaction() in your java... There is a lot of spring happening in the background. If you really wanted to do something like that, you'd have to make an http request in your java.

Spring modelattribute not recognized anymore after ajax update

i´ve encountered the following issue several times:
I use a Controller to bind a dto to a html form (via thymeleaf). Please note the model named "invoiceDto"
#RequestMapping(value = {"/create"}, method = RequestMethod.GET)
public String create(Locale locale, Model model) throws Exception {
final String login = this.getAuthentication().getCurrentApplicationUser();
if (login == null || login.isEmpty())
throw new Exception(this.getMessageSource().getMessage("label.findError", null, locale));
final Future<Setting> setting = settingService.findFirst();
final Future<ApplicationUserContactProjection> applicationUserContactProjection = applicationUserService.findByLogin(login);
while (!setting.isDone() && !applicationUserContactProjection.isDone()) {
Thread.sleep(100);
}
if (setting.get() == null || applicationUserContactProjection.get() == null)
throw new Exception(this.getMessageSource().getMessage("label.error.findError",
null, locale));
model.addAttribute("invoiceDto", new InvoiceDto(setting.get(), applicationUserContactProjection.get()));
model.addAttribute("message", this.getMessageSource().getMessage("label.navigation.invoiceCreation", null, locale));
return "invoice/create";
}
I have a html form (thymeleaf generated) where i use the above Java pojo dto with the given modelattribute name to fill my Input fields. This is an excerpt of it. The important part is the div with the id of "invoiceLineItems" where thymeleaf replaces its child div with a lineItems Fragment:
<form action="#" th:action="#{/invoice/newinvoice}" th:object="${invoiceDto}" role="form" method="post"
class="form-signin" id="editInvoiceForm"
accept-charset="utf-8">
<div id="invoiceLineItems"><div th:replace="invoice/items :: lineItems"></div></form>
The fragement contains the following stuff - an excerpt of it:
<td>
<input type="text"
th:field="*{items[__${index.index}__].lineItemTotalPrice}"
readonly
class="form-control" disabled
id="lineItemTotalPrice"/>
</td>
Excerpt of the given pojo:
public class InvoiceDto implements Serializable {
private Invoice invoice;
private List<LineItem> items;
I access the list like this:
th:field="*{items[__${index.index}__].lineItemTotalPrice}"
The Problem:
I can add items dynamically via Ajax. I serialize the whole form (for convenience reasons) and call a Controller Method:
#RequestMapping(value = {"/newlineitem"}, method = RequestMethod.POST)
public String newLineItem(#ModelAttribute("invoiceDto") InvoiceDto invoiceDto,
Model model)
throws Exception {
invoiceDto.addItem(new LineItem());
final Future<InvoiceDto> calculatedInvoiceDto = invoiceService.calculateInvoice(invoiceDto);
while (!calculatedInvoiceDto.isDone()) {
Thread.sleep(100);
}
model.addAttribute("invoiceDto", calculatedInvoiceDto.get());
return "invoice/dynamicitems :: lineItems";
}
As you can see, i let thymeleaf render a Special view, because after the Ajax success spring cannot set the modelattributes proper.
In short: After the Ajax Returns the partial view, the following will throw an exception:
th:field="*{items[__${index.index}__].lineItemTotalPrice}"
whereas this works - note the prefixed invoiceDto:
th:field="*{invoiceDto.items[__${index.index}__].lineItemTotalPrice}"
Question:
What´s wrong here?
Why do i have to prefix the name of the modelattribute after the partial Ajax update, whereas in the first run i don´t have to?
Thank you for your help!
EDIT:
For my share it looks like the way that spring "forgets" the originally named form modelattribute "invoiceDto" if the page is partially updated by an ajax call (to another spring controller, modifying invoiceDto) through a partial thymeleaf html.
So after the controller returns the partial thymeleaf view i have to access its fields with prefixed "invoiceDto", as if there would be no invoiceDto attribute.
Thanks again for your help!
UPDATE
As there is no progress on this i have raised a thymeleaf issue:
https://github.com/thymeleaf/thymeleaf/issues/795
Nevertheless i think this is a spring issue, because i have the same results with JSP.
Repository to comprehend this issue
https://mygit.th-deg.de/tlang/thymefail
If I understand your problem correctly, you're trying to use the *{} notation when there is no active object. When the ajax method returns just the "lineItems" fragment, Thymeleaf has no way of knowing that it belongs to a form with a th:object on it.
I guess the best solution is to return the whole form then, in js, extract the lineItems.
Or maybe just get rid of th:object altogether (convenient only when you want to show validation errors imho).

Best Practice of reading text file in spring mvc

What is the best way to read HTML content from a text file and display the content in JSP? I have placed the text file in the resource folder using spring mvc 3. Normally I do this kind of stuff with Apache commons in struts but believe spring must have provided some utility for this.
I am thinking about reading it in a tag file. What utility should i use for that?
Ignoring the question of why you would want to do this. The return value from a Spring MVC controller method is usually used to resolve a view. The resolved view then becomes the response body. However, you can use the #ResponseBody annotation to make the raw return value the response body.
You can do it in the #RequestMapping method. The Key is the return type ModelAndView.
You read your text file and get the html that you need, after this, adding the html to the model and then return the a new ModelAndView Object.
Here's a sample:
#RequestMapping(value = "siteWithResHtml", method = RequestMethod.GET)
public ModelAndView loadSiteWithResHtml(Model model)
{
String resourceHtml;
// do your stuff for reading file and assign it to the String
model.addAttribute("resource_Html", resourceHtml);
return new ModelAndView("yourJSP", "model", model);
}
and in the jsp you can read the value from the model that you forwarded to the jsp, like this:
<div>${model.resource_Html}</div>
please take notice that the names are match.

Handle url pattern that has user name as part of the url

Suppose I have 3 url patterns that needs to be handled by Spring MVC as follows:
1) www.example.com/login (to login page)
2) www.example.com/home (to my home page)
3) www.example.com/john (to user's home page)
I would like to know what is the best practice way of handling the url pattern that has username as part of the url (real world example is facebook fanpage www.faceboo.com/{fanpage-name})
I have come up with my own solution but not sure if this is the clean way or possible to do it.
In my approach, I need to intercept the request before it being passed to Spring MVC's dispatchservlet, then query the database to convert username to userid and change the request URI to the pattern that Spring MVC can recognize like www.example/user/userId=45.
But I am not sure if this is doable since the ServletAPI does not have the setter method
for requestURI(it does have the getter method for requestURI)
Or if you have a better solution please share with me. Thank in advance :-)
Spring MVC should be able to handle this just fine with PathVariables.
One handler for /login, one handler for /home, and one handler for /{userName}. Within the username handler you can do the lookup to get the user. Something like this:
#RequestMapping(value="/login", method=RequestMethod.GET)
public String getLoginPage() {
// Assuming your view resolver will resolve this to your jsp or whatever view
return "login";
}
#RequestMapping(value="/home", method=RequestMethod.GET)
public String getHomePage() {
return "home";
}
#RequestMapping(value="/{userName}", method=RequestMethod.GET)
public ModelAndView getUserPage( #PathVariable() String userName ) {
// do stuff here to look up the user and populate the model
// return the Model and View with the view pointing to your user page
}

Resources