Display Spring MVC model attributes in thymeleaf template - spring

I am developing a full Spring application with Spring MVC and Thymeleaf in view layer. In the past I've worked with JSPs and Spring MVC in view layer, but those are now dinosaurs I guess.
So my problem is that with JSPs I could very easily display model attributes in view by adding value in model.addAttribute in controller and displaying the same in JSP anywhere with placeholder evaluating to springex ${value}. So if I want to place a title in page I can write <title>${appName}<title>. This is one of the places where I can put any springex.
I am having hard time to figure out how to do this with Thymeleaf as it uses attribute based parsers. So anywhere on page if thymeleaf prefix is not included it won't process spring expression. It's very hard to work with limited set of tag libraries. I've heard of custom attributes for thymeleaf but I guess there should be a better way to do this.

You can use the th:text attribute, e.g.
<html ... xmlns:th="http://www.thymeleaf.org">
...
<title th:text="${appName}">mocking text</title>
...
</html>
The content of the tag ("mocking text" in this case) gets replaced by the result of the expression in the th:text attribute.
Of course you need to have the appropriate JAR files on CLASSPATH and have the Thymeleaf view resolver properly configured, as described in the Thymeleaf+Spring guide.
For additional information about how template processing works with Thymeleaf in general you can refer to the Thymeleaf guide.

Related

Invoke and load Spring MVC controller request method from Thymeleaf

I am using Spring Boot 1.5.4 (Spring MVC) and Thymeleaf 3.0.6 (Layout Dialect 2.2.2)
Assume that I am rendering the model from a Spring MVC Controller method with a Thymeleaf template (template A), which outputs HTML A.
Is it possible, from within template A, to call/invoke another Spring MVC controller method (which then will render the model with a different thymeleaf template) outputting HTML B, and load the rendered results into HTML A?
Something like what the struts2 action tag does with the executeResult=true Param.
https://www.tutorialspoint.com/struts_2/struts_action_tag.htm
I've looked into thymeleaf include and replace, but they only seem to work with loading the html fragment not an entire Spring MVC Request
You can try to make an AJAX request to the Spring MVC controller method which will return the template B.
Then, once you have the response you can set the response as an existing html element in your DOM, something like:
$.get("your_end_point", function(data, status){
document.getElementById("your_template_B_Container_DIV_ID").appendChild(data);
});
This is only a guess, also keep on mind that if you create a template with body, head... this will probably not work, try to use a template with no body or head tags. For example you can try with a template made only with div tags ans see if you can render it.

Is it a good design to use a spring's MVC tag ( let's say form:input tag) within a custom myCustomTag.tag file implementation?

I am developing a myCustomTag.tag file to implement my custom tag in spring MVC supported project. I know that the developer using the myCustomTag would use the myCustomTag within the spring provided tag. For E.g. :
<form:form action="..." commandName="...>
<myprefix:mycustomTag ............ />
</form:form>
Is it a good design to use a spring's MVC tag ( let's say form:input tag) within a custom myCustomTag.tag file implementation ?
Absolutely, I don't see a reason why you would not want to use spring tags within a custom tag.
For example, for a large form, you might want to separate sections into their own tags and spring tags are perfectly ok to be used there (ie, if it is syntactically allowed).

Cannot access struts action data from nested JSP

I am working for first time with Struts 2 + Spring + Hibernate architecture. I took this project as reference for building it and it works. I can list DB tables in my index.jsp using struts tags, but this does not work from nested JSP loaded into DIV containers inside index.jsp.
index.jsp has a <div class="art-nav"></div> and loads there another jsp using js:
$(".art-nav").load("./menu.jsp");
The same struts tags that work in index.jsp to list DB tables do not work in menu.jsp. I am not sure if the problem is the way I am loading this JSP or if it is necessary to execute some action from Struts 2 before loading menu.jsp...
Basically the JSPs use AJAX and I am adapting them to this architecture and there is where I am facing the problems because of my lack of experience.
Thank you in advance for your help!
You should include the second jsp as follows:
<div class="art-nav">
<%# include file="/WEB-INF/jsp/menu.jsp"%>
</div>
If you load your jsp via javascript the response will not get forwarded to that jsp.
If you really want to load a jsp via javascript you should create a new action (menu.action) that returns a parsed jsp and include it in the existing html. (Though I personally do not really like that technique.)

How to develop JSP/Servlets Web App using MVC pattern?

I'm developing a JSP/Servlet web app (no frameworks). I want to use MVC pattern. I am going to design my project like this:
Controller: a servlet that reads a request, extracts the values,communicates with model objects and gives information to a JSP page.
View: JSP Pages.
Model: Java Classes / Java Beans .. etc.
The problem: Index.jsp is the starting point (default page) in my web site. So, the Index.jsp becomes the controller to parse the request. For example, the following request:
index.jsp?section=article&id=10
is parsed in index.jsp as following :
<div class="midcol">
<!-- Which section? -->
<%String fileName = request.getParameter("section");
if (fileName == null) {
fileName = "WEB-INF/jspf/frontpage.jsp";
} else {
fileName = "WEB-INF/jspf/" + fileName + ".jsp";
}
%>
<jsp:include page='<%= fileName%>' />
</div>
Here, I can't force the servlet to be a controller, because the index.jsp is the controller here since it's the starting point.
Is there any solution to forward the request from index.jsp to the servlet and then go back to index.jsp? Or any solution that achieves the MVC goal - the servlet should be the controller?
I'm thinking of making a FrontPageController servlet as default page instead of index.jsp, but I don't know if it's a perfect idea?
Get rid of index.jsp and just let the controller servlet listen on a specific url-pattern of interest. The controller itself should forward the request to the JSP page of interest using RequestDispatcher.
request.getRequestDispatcher("/WEB-INF/page.jsp").forward(request, response);
Alternatively you can let index.jsp forward or redirect to an URL which is covered by the controller servlet which in turn shows the "default" page (which seems to be frontpage.jsp).
That said, in a correct MVC approach, you should have no scriptlets in JSP files. Whenever you need to write some raw Java code inside a JSP file which can't be replaced reasonably by taglibs (JSTL and so on) or EL, then the particular Java code belongs in any way in a real Java class, like a Servlet, Filter, Javabean, etcetera.
With regard to the homegrown MVC approach, you may find this answer and this article useful as well.

Multiple View resolvers in spring mvc

I want to use multiple view resolvers in my web app based on spring mvc
Can anyone tell me how do I achieve that.
I want to use both JSP and freemarker in my app.
Please suggest some approaches or links or examples..
All help is appreciated.
Adhir
You can add as many view resolvers as you want. You can specify the order in which the view resolvers need to be checked. Spring will take the first view resolver which can successfully resolve the view.
ex:
Since you have JSP and freemarker add the view resolvers for both and give the order property 1 for JSP and 2 for freemarker.
If your view is /freemarker/hello.ftl then the JSP resoplver will fails since it will not be able to find th file /freemarker/hello.ftl, then the freemarker resolver will handle this view. But if the JSP resolver is able to find the file and resolve it then freemaker resolver will not be used to resolve that view
Refer: Chaining ViewResolvers

Resources