Spring mapping resources for template Thymeleaf - spring

Spring has problem with mapping items like css, js, img. Problem occured after when I clicked link from template index:
#RequestMapping("/")
public String index(Model model) {
return components.init("index",model).getHeader().getFooter().getSidebar().getRecommended().toString();
}
Link inside template the index looks like that: /places/tags(parameters)
#RequestMapping("/places/tags")
public String index(Model model,#RequestParam(required = false, defaultValue = "eats", value="listOfTag") String listOfTag) {
System.out.println(listOfTag);
return components.init("places",model).getHeader().getFooter().getSidebar().getPlaceForSidebar(listOfTag).toString();
}
After I clicked above link the places site looks not good.
Problem is with the mapping.
No mapping found for HTTP request with URI [/places/assets/css/styles.min.css]
I tried to register resources but nothing to change. I thinking that problem is on the site configuration of Thymeleaf.

I found solution: add before link "/" Topic should be close:)

Related

srpingboot routing problem with thymeleaf

I'm sorry I'm not very specific with the problem this is because I don't know exactly how to discribe the issue, I'm new to sringboot. what I basically want to do is to create a link like http://localhost/admin/countries and http://localhost/admin/countries/add
#Controller
public class CountryController {
#GetMapping("/admin/countries")
public String getCountries() {
return "admin/views/country/index";
}
//add new record
#GetMapping("/admin/countries/add")
public String addCountry() {
return "admin/views/country/add";
}
}
The Link loads correctly without problem, the second link loads but the styling of the page didn't load. I'm using thymeleaf templating so the two file shares the same layout. the index file loads correctly while the add file loads without style
I try to re-route the second link and have something like below and it serve the fike correctly with the style
#Controller
public class CountryController {
//add new record
#GetMapping("/admin/add-country")
public String addCountry() {
return "admin/views/country/add";
}
}
Now I'd like to have something like http://localhost/admin/countries/add, http://localhost/admin/countries/view, http://localhost/admin/countries/update rather than http://localhost/admin/add-country, http://localhost/admin/view-country
What is the cause of this problem and how to fix it
my directory structure look like below
thanks for any help

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

views in thymeleaf spring boot templates sub folder

I am using thymeleaf in spring boot, and have several views. I don't want to keep all the views in the same folder which is src/main/resources/templates by default.
Is it possible to move some of the view in src/main/resources/templates/folder1, and I will pass "folder1/viewname" to access that page?
When I tried http://localhost:8080/folder1/layout1 it didn't found my html in src/main/resources/templates/folder1/, but when I move the html in templates main folder src/main/resources/templates/, http://localhost:8080/layout1 worked fine.
My controller class looks like:
#RequestMapping(value = "{pagename}", method = RequestMethod.GET)
public String mf42_layout1(#PathVariable String pagename) {
return pagename;
}
So, I thought if I pass layout1, it will look int the templates, and if I say "a/layout1", it will look in /layout folder
Thanks,
Manish
Basically, your request mapping and the name of your view are decoupled, you just need to pay attention to the syntax.
For instance, with
#RequestMapping(value = "/foobar", method = RequestMethod.GET)
public String mf42_layout1() {
return "layout1";
}
a request to http://localhost:8080/foobar will render the template located in src/main/resources/templates/layout1.html.
It also works if you put your templates on a subfolder, as long as you provide the correct path to the view:
#RequestMapping(value = "/foobar", method = RequestMethod.GET)
public String mf42_layout1() {
return "a/layout1";
}
A request to http://localhost:8080/foobar will render the template located in src/main/resources/templates/a/layout1.html.
You can also parameterized the url endpoint with #PathVariable:
#RequestMapping(value = "/foobar/{layout}", method = RequestMethod.GET)
public String mf42_layout1(#PathVariable(value = "layout") String layout) { // I prefer binding to the variable name explicitely
return "a/" + layout;
}
Now a request to http://localhost:8080/foobar/layout1 will render the template in src/main/resources/templates/a/layout1.html and a request to http://localhost:8080/foobar/layout2 will render what's in src/main/resources/templates/a/layout2.html
But beware the forward slash acts as a separator in URLs, so with your controller:
#RequestMapping(value = "{pagename}", method = RequestMethod.GET)
public String mf42_layout1(#PathVariable String pagename) {
return pagename;
}
My guess is when you hit http://localhost:8080/a/layout1 pagename receives "a" and "layout1" is not caught. So the controller probably tries to render the contents of src/main/resources/templates/a.html
The Spring MVC reference extensively describes how to map requests, you should read it carefully.
I faced similar template not found issue when running the application in a Linux server. I was using the path as "return "/a/layout1". This worked fine in a local windows PC, but I had to remove the starting "/" to make it work in a Linux box(i.e. "return "a/layout1").

How do I expose a navigation property over OData 4 and WebApi 2.2?

I have a navigation property on a model, Site.Locality and although its foreign key is serialized and available to consumers (Site.LocalityName) I'd like the locality itself to be available from:
~/Site('A')/Locality
How is this done in OData v4 over WebApi 2.2?
On your controller for the Site entity, add the following action:
// Implies that the controller has [ODataRoutePrefix("Sites")]
[ODataRoute("({name})/Locality")]
public async Task<Locality> GetLocality([FromODataUri] string name)
{
// Add try-catch or null 404 handling.
var site = await this.Repository.GetAsync(new[] { name });
return site.Locality;
}
Obviously, place your own DAL code in there, this is just an example.
It's very clear to see that this is achieved through nothing more complex than a simple route and action on your controller.
That said, there is some mapping happening under the hood. For example, you couldn't just expose any arbitrary navigation property:
[ODataRoute("({name})/Wangachop")]
public string GetWangachop([FromODataUri] string name)
{
return "Wangaaa!";
}
Would yield:
The path template 'Sites({name})/Wangachop' on the action 'GetWangachop' in controller 'Sites' is not a valid OData path template. Found an unresolved path segment 'Wangachop' in the OData path template 'Sites({name})/Wangachop'.

Spring redirect: prefix issue

I have an application which uses Spring 3. I have a view resolver which builds my views based on a String. So in my controllers I have methods like this one.
#RequestMapping(...)
public String method(){
//Some proccessing
return "tiles:tileName"
}
I need to return a RedirectView to solve the duplicate submission due to updating the page in the browser, so I have thought to use Spring redirect: prefix. The problem is that it only redirects when I user a URL alter the prefix (not with a name a resolver can understand). I wanted to do something like this:
#RequestMapping(...)
public String method(){
//Some proccessing
return "redirect:tiles:tileName"
}
Is there any way to use RedirectView with the String (the resolvable view name) I get from the every controller method?
Thanks
the call prefixed by redirect: is a url, which is sent in a standard browser 302 redirect. you can't redirect to a view, because a view isn't a url. instead you'll need a new servelet mapping to a 'success' view and then redirect to that instead
#RequestMapping("processing.htm")
public String method(){
//Some proccessing
return "redirect:success.htm"
}
#RequestMapping("success.htm")
public String method(){
return "tiles:tileName"
}
this case works fine when you just need to show a 'thank you' page, which requires no specific data from the processing stage. however, if your success page needs to show some information from the processing, there are 2 ways to do it.
1) pass the information in the url as a get post ("redirect:success.htm?message=hi"). this is incredibly hackable, and thus highly unrecommended.
2) the better way is to store information in the http session, using #SessionAttributes and #ModelAttribute

Resources