Using:
Spring Web 3.0.5
JSTL 1.2.0
Apache Tiles 2.1.4
Resin 3.1.9
template1: imports jsp for url1
main jsp: imports /my/simple/url2
imported jsp: jsp page without imports nor includes
tiles:
logical view for url1: url1.view (extends tempate1)
logical view for url2: url2.view (is a jsp page)
Now here's what's happening:
When accessing /my/simple/url1: goes to a controller and command which then results to
rendering a template (template1), that imports main jsp
Upon seeing import for /my/simple/url2, dispatches a request for this url
This, in turn, goes to another controller using another command and renders another jsp (aka: imported jsp)
After execution of controller for url2, I expect that url2.view will be rendered and appended to main jsp. But instead of this, template1 is again rendered which results to a loop.
Did anyone experience this problem before? I'm not really sure what's happening.
Ok, so I'm not sure that this will work for for earlier versions of Tiles and Spring (currently using Spring 3.1 and Tiles 2.2.2), but here it goes anyway.
I realized that for some reason, when you do an import using the core tag library within a tiles template, and let's say that import in turn calls a Spring MVC controller, it will cause an infinite loop. The way that I got around this was by doing the following:
Add an attribute in the tiles definition of the layout that will reference a jsp containing the code to do the import. Let's say for example:
<definition name="cti.layouts.fooBarLayout" template="/WEB-INF/views/layouts/foo-bar-layout.jsp">
<put-attribute name="body" value="/WEB-INF/views/some-body.jsp"/>
<put-attribute name="foo" value="/WEB-INF/views/my-import.jsp"/>
</definition>
In this example, you want to add the import code inside of my-import.jsp. You can use the core JSTL tag <c:import>
Inside of foo-bar-layout.jsp, add in a tiles:insertAttribute tag wherever you want this imported page to go. Reference the name of the attribute (in this case 'foo'):
<tiles:insertAttribute name="foo"/>
Now you can extend from this layout without worry about an infinite loop. Not sure why this is working as I don't understand what the underlying implementation is doing, but for some reason, tiles does not allow a dynamic import to be used inside of a template page.
Hope this helped.
I had the same problem and resolved by using the absolute URI of the tile. This triggeres a 'clean' request to the server and isn't aware of the current tile rendering.
I used the import because I required a more dynamic url.
So for the sample case:
<c:import url="/path/to/the/import/jsp/or/controller"/>
becomes
<c:import url="http://localhost:8080/mycontext/path/to/the/import/jsp/or/controller" />
Of course you need to update the baseURI to your applicable situation.
This avoided the recursion happening when combining tiles with c:import
Beware: This triggers a new HTTP-request to your server.
Related
I'm trying to understand the following issue. When I type url http://localhost:8076/demoproject_war/test.jsp spring is able to load test.jsp page. Here is the pic of my directory structure.
My question is how spring loads ./test.jsp even though I don't have any mappings in my controller class for ./test.jsp . Does not this request go to controller to check the mappings?
Spring does not load this JSP when you go to that URL. You're navigating directly to the JSP. It is considered a bad practice as you're not controlling the execution in this case. You should put the JSPs inside a webapp/WEB-INF directory. Then, the won't be accessible directly.
I'm migrating a Play! 1.2 web application and moving to Spring Boot + Spring MVC. Some views contain URLs to other endpoints. For example, I display the book title on the page and next to it I want to add the URL to go the book's details page (e.g. localhost/books/{id}).
In Play! 1.2 the controllers are static, and there is also a Router which can create the full URL for a method belonging to another controller (Router.getFullUrl("BookController.bookDetails", args)), but how do I achieve this with Spring MVC?
Best regards,
Cristian.
If you are trying to get the app/deployed name automatically in .jsp files to make the urls, then please make use of context path. An example below :
<c:set var="context" value="${pageContext.request.contextPath}" />
<script src="${context}/themes/js/jquery.js"></script>
From your requirement "admin.myapp.com","admin-test.myapp.com" are server names right? Something like http://admin.myapp.com/book/{bookId},http://admin-test.myapp.com/book/{bookId}. In Spring app, relative path in jsp can be accessed using pageContext.request.contextPath
I also found the UriComponentsBuilder and ServletUriComponentsBuilder. They are similar to the Play! Framework router and provide methods for building URI's, handling parameters and the query etc. We chose to annotate the controllers' methods using constants and then use the same constants with the UriComponentsBuilder to build back the path and create the request query for GET requests.
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).
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.
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.)