Why can't I get Thymeleaf to work on Script tags - spring

I have a simple Spring Boot application and I am trying to add Thymeleaf. The basic structure of my app is available here.
Basically when I try to render the following in the template...
<h1>[[${key}]]</h1>
It works perfect! However, when I try...
<script src="https://my.api.com/api/js?key=${key}" />
The ${key} is not getting replaced. What am I missing?

If you want Thymeleaf to resolve attributes, you have to prefix them with th:.
<script th:src="|https://my.api.com/api/js?key=${key}|" />
or
<script th:src="#{https://my.api.com/api/js(key=${key})}" />

Related

(WAR) Spring Boot Admin custom view not found

Once deployed as a WAR into Tomcat, my customized SBA dashboard fails at showing a custom view that was first doing fine into a JAR (but it also fails now, btw)
This is where is located the extension's directory into the WAR:
/WEB-INF/classes/META-INF/spring-boot-admin-server-ui/extensions/customz/...
REM: I've also customized the login page and my picture is located at /WEB-INF/classes/META-INF/spring-boot-admin-server-ui/assets/img/ so I guess that the classpath isn't the issue.
Still, I've got an error into the web browser's console, though:
GET http://xx.xx.xx.xx:8080/extensions/customz/css/custom.fb3a4f29.css net::ERR_ABORTED 404
REM: according to my context path, the correct path should probably be that one:
http://xx.xx.xx.xx:8080/myapp/dashboard/extensions/customz/css/custom.fb3a4f29.css
server.servlet.context-path=/myapp
spring.boot.admin.context-path=/dashboard
...
<packaging>war</packaging>
<build>
<finalName>myapp</finalName>
...
</build>
But I couldn't figure out how to change the base path for my views in this case. I should just have to prefix somehow the system with my "customz/dashboard" context path (?)
Does anybody, please, know how to get out of this trap?
NB: Spring Boot 2.2.8, Spring Cloud Hoxton.SR5, SBA 2.2.3, Tomcat 9.0.36
AdminServerUiAutoConfiguration declares resource handlers for the extensions (mapping context-path/extensions/** to the above classpath, as figured out when I tried to visualize custom JS and CSS earlier.
Remember that spring.boot.admin.ui.extension-resource-locations default is classpath:/META-INF/spring-boot-admin-server-ui/extensions/ which seems fine in my case. That confirms that custom views are correctly exposed.
So that leads us to spring-boot-admin-server-ui/src/main/frontend/index.html where all paths appear to be ... absolute!
<th:block th:each="cssExtension : ${cssExtensions}">
<link rel="preload" th:href="'/extensions/' + ${cssExtension.resourcePath}" as="style">
</th:block>
<th:block th:each="jsExtension : ${jsExtensions}">
<link rel="preload" th:href="'/extensions/' + ${jsExtension.resourcePath}" as="script">
</th:block>
<th:block th:each="cssExtension : ${cssExtensions}">
<link th:href="'/extensions/' + ${cssExtension.resourcePath}" rel="stylesheet">
</th:block>
<link rel="shortcut icon" th:href="${uiSettings.favicon}" type="image/png">
<title th:text="${uiSettings.title}">Spring Boot Admin</title>
...
<script lang="javascript" src="sba-settings.js"></script>
<th:block th:each="jsExtension : ${jsExtensions}">
<script lang="javascript" th:src="'/extensions/' + ${jsExtension.resourcePath}"></script>
</th:block>
I guess these are two points where both servlet and admin ui context paths should be added in order for extensions to be held. May be tehe quickest way would be to URls relative in index.html
So I did exactly that... git cloning SBA on tag 2.2.3, doing the changes and Maven installing it, changing my server's parent to SNAPSHOT, then rebuilding the WAR into Tomcat. Et voilĂ .

Spring Boot Security + GWT, static resources access 403 error

I am fighting the css/js access problem in my gwt+spring security simple application. So, i have secutiy controller with the next method:
#GetMapping(value = "/notes")
public ModelAndView index(ModelAndView modelAndView) {
modelAndView.setViewName(VIEW_NOTES);
return modelAndView;
}
By the way, I integrated these technologies according to this article. So, thanks to this controller method (I use RestController) we've got resolved view (simple as ****):
<!DOCTYPE html>
<html lang="en">
<head>
<title>Notes</title>
<link rel="stylesheet" type="text/css" media="all"
href="../static/css/notes-main.css"></link>
</head>
<body>
<!-- This script tag is what actually loads the GWT module. The -->
<!-- 'nocache.js' file (also called a "selection script") is -->
<!-- produced by the GWT compiler in the module output directory -->
<!-- or generated automatically in development mode. -->
<script language="javascript" src="notesgwtapp/notesgwtapp.nocache.js">
</script>
<!-- Include a history iframe to enable full GWT history support -->
<!-- (the id must be exactly as shown) -->
<iframe src="javascript:''" id="__gwt_historyFrame"
style="width:0;height:0;border:0"></iframe>
<div id="notes"></div>
</body>
</html>
Now is the most interesting thing that I have these two errors:
GET http://localhost:8080/static/css/notes-main.css 403
GET http://localhost:8080/notesgwtapp/notesgwtapp.nocache.js 403
I dont have problems with resolving resources for other views, btw.
Please help, how can I handle it? If i miss some important part of code, I will add it. Just ask. Thank you in advance.
By default Sprint Boot permits all access to /js/**, /css/**, /images/**. But you try to access /static/** and /notesgwtapp/** which will result in the 403 error (see here).
There are two solutions:
Make sure that the notesgwtapp.nocache.js and the notes-main.css file end up in one of the above folders or
Override the SecurityConfig of your Spring Boot app and add the /static/** and /notesgwtapp/** folder to the permitted locations.

Thymeleaf th:include doesn't work after update to Spring Boot 1.3

I have an application which works fine with Spring Boot 1.2.6. Now I tried to 1.3.5 and have the problem, that the following statement doesn't work anymore:
<head >
<title th:text="#{app.title} + ' - ' + #{login.title}"></title>
<th:block th:include="main::head"/>
</head>
I can see in the Thymeleaf log that the main.html is found. Furthermore the Thymeleaf-Expressions from the head are evaluated. How ever the html in the browser has no content in head, neither title nor the content from main.html.
As far as I can see the Thymeleaf version hasn't changed.
So what can be the reason?
The version of the Layout dialect has changed. So I added the property <thymeleaf-layout-dialect.version>1.2.9</thymeleaf-layout-dialect.version> to my pom.xml and everything was fine.
I created an issue for that.

Spring Boot + Freemarker master template

I`m trying to build an app with spring boot and freemarker as template engine. The problem I have is, I want to make a "master template" for all my pages to use. I found out that this is achievable in Freemarker with macros. This is how my indexmaster.ftl looks like:
[#macro indexmaster title="defaultTitle"]
<html>
<head> css stuff </head>
<body>
<div id="content">[#nested /]</div>
</body>
</html>
[/#macro]
and in the other pages, I use the macro like this:
[#import "/WEB-INF/ftl/master/indexmaster.ftl" as layout /]
[#layout.indexmaster title="My title"]
...rest of the page
[/#layout.indexmaster]
The problem I`m facing is, the freemarker "code" is interpreted as text when I access the page
click me
What am I doing wrong? Is there any extra spring boot configuration needed?
Use "<>" instead of "[]" for Freemarker tags.
You need to set the tag_syntax configuration setting of FreeMarker to auto_detect or square_bracket. The default is angle_bracket for backward compatibility. Another option is to start the template with [#ftl], which turns on square bracket syntax even if tag_syntax is angle_bracket.

AJAX validation not working with struts2 Jquery plugin

I am writing a web application with struts2 + Jquery plugin.
I am using AJAX form submission with sj:submit tag from jquery plugin.
I am facing an issue while validating the form (AJAX) with "validate= true" tag in sj:submit.
Following is the sj:submit tag:
<sj:submit value="ADDUSERNOW" onBeforeTopics="before" onSuccessTopics="success"
onErrorTopics="errorState" onCompleteTopics="complete" targets="userMgmntDiv" validate="true"/>
My html head section also contains references to two js files required for validation as below.
<script language="JavaScript" src="${pageContext.request.contextPath}/struts/utils.js" type="text/javascript"></script>
<script language="JavaScript" src="${pageContext.request.contextPath}/struts/xhtml/validation.js" type="text/javascript"></script>
Validation xml is given below which is named as ActionClass-validation.xml and is placed in the same package as that of a class on which validation is invoked:
<validators>
<field name="userModel.userName">
<field-validator type="requiredstring">
<message>UserName Is Required</message>
</field-validator>
</field>
</validators>
After form is submitted , no validation is triggered , and execution proceeds and struts2 action class is called.
Is there anything I am missing here ? I have searched a lot but couldn't find any answer .Please help
struts2-core version : 2.3.4
struts2-jquery-plugin :3.3.3
Action configuration looks loke below :
<action class="addUserAction" method="addUser">
<interceptor-ref name="jsonValidationWorkflowStack"/>
<result>addUser.jsp</result>
</action>
In addition to above,I am using spring + struts2 + hibernate for achieving above task.When I tried the example as shown in struts2-jason wiki page : ,I am getting error as : cannot find action with class named AddUserAction(which is a bean in spring-beans.xml)
It seems that error is thrown when validator inteceptor is invoked.
When I comment out the annotations used for validation on the action class - AddUserAction, this error vanishes and page loads successfully.
Following are my questions :
1)How can I use spring alongwith struts2 convention plugin ? This is because , convention plugin uses its own mechanism for mapping urls and action (using annotations or default behaviour).
2)Previuosly , I was expecting struts.xml file can be used for url to action mapping , and annotations can be used for validations. (using convention plugin)But this approach doesn't seem to work.(convention plugin + struts.xml doesn't work)
struts2 ajax validation is a client side validation, which provided natively by dojo, here is the doc for Struts2 Ajax validation. struts2-jquery plugin provides this feature using jsonValidationWorkflowStack, you can use it like this: Example
I've tried. It's work very well. But if your form has an input file for upload, the ajax validation don't work.

Resources