Alternative to ResourceBundleViewResolver - spring

I have a legacy jsp application with views.properties file, from which I use ResourceBundleViewResolver to load all the views. As ResourceBundleViewResolver has been deprecated from Spring 5.3, I have checked the spring documentation and it says "as of 5.3, in favor of Spring's common view resolver variants and/or custom resolver implementations". I would like to know the alternative to use the BundleViewResolver. Apologies in advance, I am very new to dealing with legacy applications.
Edit
Config.java
public class Configuration_place extends WebMvcConfigurerAdapter {
#Bean
public ResourceBundleViewResolver viewResolver(){
ResourceBundleViewResolver tilesViewResolver = new ResourceBundleViewResolver();
tilesViewResolver.setBasename("views");
return tilesViewResolver;
}
#Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer tilesConfigurer = new TilesConfigurer();
tilesConfigurer.setDefinitions("/tiles-def.xml");
return tilesConfigurer;
}
views.properties
index.(class) = org.springframework.web.servlet.view.tiles3.TilesView
index.url = index
login.(class) = org.springframework.web.servlet.view.tiles3.TilesView
login.url = login
tiles-def.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
"http://tiles.apache.org/dtds/tiles-config_3.0.dtd">
<tiles-definitions>
<definition name = "master.page" template = "/views/templates/layout_main.jsp">
<put-attribute name = "title" value = "JSP Application" />
<put-attribute name = "header" value = "/views/templates/header.jsp" />
<put-attribute name = "menu" value = "/views/templates/menubar.jsp" />
<put-attribute name = "error" value = "/views/templates/errorMessage.jsp" />
<put-attribute name = "content" value = "" />
<put-attribute name = "footer" value = "/views/templates/footer.jsp" />
</definition>
<definition name = "index" extends="master.page">
<put-attribute name="content" value="/views/intro.jsp" />
</definition>
<definition name = "login" extends="master.page">
<put-attribute name="content" value="/views/login.jsp" />
</definition>
</tiles-definitions>

Related

utf8 encoding with Spring 4 + Tiles template + Freemarker

I tried to integrate Spring 4 (4.3.0.), tiles 3 (3.0.7) and FreeMarker 2 (2.3.25-incubating), in templates definitions file I have:
<definition name="base-definition" template="/WEB-INF/views/tiles/layouts/layout.ftl" templateType="freemarker">
<put-attribute name="title" value="" />
<put-attribute name="body" value="" />
</definition>
<!-- Home Page -->
<definition name="home" extends="base-definition">
<put-attribute name="title" value="Welcome" />
<put-attribute name="body" value="/WEB-INF/views/jsp/home.jsp" />
</definition>
home.jsp:
<%# page errorPage="error.jsp" contentType="text/html; charset=utf-8"%>
....
layouts.ftl:
<!DOCTYPE html>
<html lang="sk">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
....
<title><#tiles.insertAttribute name="title" /></title>
</head>
<body>
<section id="site-content">
<#tiles.insertAttribute name="body" />
</section>
ľščťžýáíéúä
</body>
</html>
I have CustomTilesContainerFactory (extends BasicTilesContainerFactory) with registerAttributeRenderers function:
#Override
protected void registerAttributeRenderers(final BasicRendererFactory rendererFactory,
final ApplicationContext applicationContext, final TilesContainer container,
final AttributeEvaluatorFactory attributeEvaluatorFactory) {
super.registerAttributeRenderers(rendererFactory, applicationContext, container, attributeEvaluatorFactory);
FreemarkerRenderer freemarkerRenderer = FreemarkerRendererBuilder.createInstance()
.setApplicationContext(applicationContext).setParameter("TemplatePath", "/")
.setParameter("NoCache", "true").setParameter("ContentType", "text/html")
.setParameter("template_update_delay", "0").setParameter("default_encoding", "UTF-8")
.setParameter("number_format", "0.##########")
.setParameter(SharedVariableLoaderFreemarkerServlet.CUSTOM_SHARED_VARIABLE_FACTORIES_INIT_PARAM,
"tiles," + TilesSharedVariableFactory.class.getName())
.build();
rendererFactory.registerRenderer(FREEMARKER_RENDERER_NAME, freemarkerRenderer);
}
I have CustomTilesInitializer (extends DefaultTilesInitializer) with createContainerFactory function:
#Override
protected AbstractTilesContainerFactory createContainerFactory(ApplicationContext context) {
return new CustomTilesContainerFactory();
}
but in web-browsers, HTTP response header is OK:
text/html; charset=utf-8
but when I check properties of web page (mouse right-click), there is encoding "windows-1252", please, where is a problem, why there is not utf-8 ? And of course, there is problem with specials characters, in layouts.ftl there is "ľščťžýáíéúä" but in web-bowser is ?????ýáíéúä.
thanks!
solution:
#RequestMapping(value = { "/index" }, method = RequestMethod.GET)
public String homePage(ModelMap model, HttpServletResponse response) {
response.setContentType("text/html;charset=UTF-8");
return "home";
}
but, it is not very nice solution :-( neccessary to set content type in ALL request mapping functions ? :-(

Migrate Apache Tiles definition to JavaConfig

I'm currently migrating my Spring project to JavaConfig. Now there is still the tiles.xml which contains the tiles definition.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN" "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>
<!-- Layouts -->
<definition name = "template.base" template = "/WEB-INF/views/layout/template.jsp" />
<!-- Example Controller -->
<definition name = "test" extends = "template.base" />
</tiles-definitions>
Is it possible to translate that XML configuration file to the new JavaConfig standard?

Spring MVC controller using #RequestParam with Apache tile 2

I am have the following configuration for my Spring MVC + Apache tile 2 project.
The Tile configuration
<definition name="test1" extends="mymain">
<put-attribute name="main">
<definition template="/WEB-INF/views/tiles/template/generictemplate.jsp">
<put-attribute name="headerstyle" value="./resources/css/header.css" type="string" />
<put-attribute name="genericcontent" value="/WEB-INF/views/tiles/test.jsp" />
</definition>
</put-attribute>
</definition>
<definition name="test2" extends="mymain">
<put-attribute name="main">
<definition template="/WEB-INF/views/tiles/template/generictemplate.jsp">
<put-attribute name="headerstyle" value="./resources/css/header.css" type="string" />
<put-attribute name="genericcontent" value="/WEB-INF/views/tiles/test.jsp" />
</definition>
</put-attribute>
</definition>
The controller
#RequestMapping(value="/test1", method=RequestMethod.GET)
public String test1(#RequestParam(value="id", required=true) String id){
return "test1";
}
#RequestMapping(value="/test2", method=RequestMethod.GET)
public String test2(){
return "test2";
}
The view generictemplate.jsp
<%# include file="include.jsp" %>
<tiles:importAttribute name="headerstyle" />
<link href="${headerstyle}" rel="stylesheet" type="text/css" />
<div role="main" class="main clearfix">
<section class="generic">
<div class="post">
<tiles:insertAttribute name="genericcontent"/>
</div>
</section>
<!-- end main -->
</div>
My problem is
When i am calling test2 (without parameter), the header.css can be read. But when test1 is called, I am getting 404 Not Found for header.css. I noticed that view is trying to access the css with path of http://localhost:8080/myproject/test1/resources/css/header.css instead of http://localhost:8080/myproject/resources/css/header.css when test1 is calling.
So why the #RequestParam makes this difference?
Thank.
This is because the css is being loaded relative to the current URL.
For test1 you have a param which adds a slash after test1. Where as test2 doesn't have the param, so its relative to the parent directory.
You could try using absolute paths for the css.

Tiles 2 Access Variable in Template

I am using the Spring MVC framework with Apache Tiles 2. I want to be able to have multiple controllers all use the same view (different logic, some basic presentation). I can do that easily. What I want now is to have different Tiles definitions for each controller, all using the same JSP file, but each passing different template variables (page header, short description, etc). This is my Tiles template definition file:
<tiles-definitions>
<!-- Default Main Template -->
<definition name=".mainTemplate" template="/WEB-INF/templates/main.jsp">
<put-attribute name="shortTitle" value="Company ABC" type="string" />
<put-attribute name="body" value="/WEB-INF/templates/blank.jsp" />
</definition>
<!-- Overriding Templates -->
<definition name="index" extends=".mainTemplate">
<put-attribute name="title" value="Company Alpha Bravo Charlie" type="string" />
<put-attribute name="body" value="/WEB-INF/views/index.jsp" />
</definition>
<definition name="index2" extends=".mainTemplate">
<put-attribute name="title" value="Company Other Page" type="string" />
<put-attribute name="body" value="/WEB-INF/views/index.jsp" />
</definition>
</tiles-definitions>
I then try to have this /WEB-INF/views/index.jsp:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<h1>
Hello world, it's <tiles:getAsString name="title" />!
</h1>
When I load this into Tomcat and bring up the page, I get a long stack trace of exceptions. The top of the pile says org.apache.tiles.impl.CannotRenderException: ServletException including path '/WEB-INF/templates/main.jsp'.} with root cause org.apache.tiles.template.NoSuchAttributeException: Attribute 'title' not found. Anybody know what's going on?
I then try to have this /WEB-INF/views/index.jsp:
How do you try this? In your controller you would specify the name of the Tiles view, not one of the multiple JSP Tiles will use in order to render the page:
#RequestMapping("index2")
public String index2() {
// ...
return "index2";
}

UrlBasedViewResolver and Apache Tiles2 in Spring 3

I've got the following exception while trying to open the URL http://localhost:8080/app/clientes/agregar:
javax.servlet.ServletException: Could not resolve view with name 'clientes/agregar' in servlet with name 'Spring MVC Dispatcher Servlet'
My mvc-config.xml is the following:
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
</bean>
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions" value="/WEB-INF/tiles/tiles.xml" />
</bean>
My simple tiles.xml:
<definition name="mainTemplate" template="/WEB-INF/template/template.jsp">
<put-attribute name="titulo" value="Simple Tiles 2 Example" type="string" />
<put-attribute name="header" value="/WEB-INF/template/header.jsp" />
<put-attribute name="footer" value="/WEB-INF/template/footer.jsp" />
</definition>
<definition name="*" extends="mainTemplate">
<put-attribute name="content" value="/WEB-INF/views/{1}.jsp" />
</definition>
When I try to open locations under /app it works fine, like /app/welcome or /app/clientes, but this error appears when trying to open /app/clientes/something. I guess it has something to do with the URL Resolver, but I can't find what...
My ClientesController class, annotated with #Controller has a method like the following:
#RequestMapping(method = RequestMethod.GET, value = "agregar")
public void agregar() { ... }
My JSP view files are located under /WEB-INF/views like:
/WEB-INF/views
-- /clientes
---- agregar.jsp
-- welcome.jsp
-- clientes.jsp
Thanks!
Added the following in my tiles.xml and works fine:
<definition name="*/*" extends="mainTemplate">
<put-attribute name="content" value="/WEB-INF/views/{1}/{2}.jsp" />
</definition>
Any better (more flexible) solution?
<definition name="/**" extends="page">
<put-attribute name="content" value="/WEB-INF/jsp/{1}.jsp"/>
</definition>
If you'll get StackOverFlow you should do like this (type="template"):
<put-attribute name="some_name" value="some_page.jsp" type="template"/>
I haven't tested it, but as the documentation says here: tiles wildcards
one asterisk (*) for a single placeholder;
two asterisks (**) to say "in every directory under the specified one";
So try with two asterisks
<definition name="**" extends="mainTemplate">
<put-attribute name="content" value="/WEB-INF/views/{1}.jsp" />
</definition>

Resources