Why JSP don't convert into HTML? so, I don't know what to show you
#Bean
public UrlBasedViewResolver urlBasedViewResolver(){
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/WEB-INF/views/**").addResourceLocations("/WEB-INF/views/");
}
One of my JSPs...
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Edit word</title>
</head>
<body>
<form action="edit" method="post">
<input name="id" type="hidden" value="${id}">
<input type="submit">
</form>
</body>
</html>
...
#RequestMapping(value = "/words/edit",method = RequestMethod.GET)
public String editWord(Model model, #RequestParam(required = false) String userID){
model.addAttribute("words",wordService.getAll());
return "/words/edit";
}
Displays as just opened JSP in browser:
I believe that using a UrlBasedViewResolver will only redirect to the file but a JSP need to be parse/compile.
The doc of Spring tell you that there is InternalResourceViewResolver and InternalResourceView that internally forward the jsp file. This will parse the file as you need.
For view technologies such as JSPs that are processed through the
Servlet or JSP engine, this resolution is usually handled through the
combination of InternalResourceViewResolver and InternalResourceView,
which issues an internal forward or include via the Servlet API’s
RequestDispatcher.forward(..) method or RequestDispatcher.include()
method.
Source :
http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/mvc.html#mvc-redirecting
Please return "words/edit" instead of "/words/edit". You have already set resolver.setPrefix("/WEB-INF/views/"); returning ""/words/edit" results in "//words/edit" .
Related
I created a simple application using Spring MVC(annotation based) and I am not able to view the results on JSP page. Below is the code which I have written:
In my AppConfig class:
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
in my controller class
#RequestMapping(value = { "/" }, method = RequestMethod.GET)
public String listNonClosedDeployments(ModelMap model) {
//DB operations to get the data
model.addAttribute("testMsg", "deployments are opened");
return "success";
}
My success JSP is:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<%# page isELIgnored="false" %>
</head>
<body>
${testMsg}
</body>
</html>
My output page is:
${testMsg}
Could you please let me know what am I missing here?
Thanks,
Venkat
it is not displaying the value because JSP's Expression Language is disabled by default. You have to enable it manually.
Add the below line to the top of your jsp page:
<%# page isELIgnored="false" %>
I've my project on github : https://github.com/QuentinVaut/JavaquariumEE
I've follow many tutorial who say different things and I tried to implement the solutions found in tutorials but nothing wrong, I understand why.
Can you tell me what is wrong with my project and explain me ?
One of many tutorials and Github sample :
http://memorynotfound.com/spring-mvc-internationalization-i18n-example/
I had a cursory look over that tutorial. Here is how I would do it:
First Configure it:
Create a Bean in the configuration class that returns the MessageSource
implementation.
#Bean
public MessageSource messageSource() //The bean must be named messageSource.
{
ReloadableResourceBundleMessageSource messageSource =
new ReloadableResourceBundleMessageSource();
messageSource.setCacheSeconds(-1); //cache time in seconds was set to -1. This disables reloading and makes the message source cache messages forever (until the JVM restarts).
messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name());
messageSource.setBasenames(
"/WEB-INF/i18n/messages", "/WEB-INF/i18n/errors"); //the message source is configured with the basenames /WEB-INF/i18n/messages and /WEB-INF/i18n/errors. This means that the message source will look for filenames like /WEB-INF/i18n/messages_en_US.properties, /WEB-INF/i18n/errors_fr_FR.properties
return messageSource;
}
Now create a bean that returns LocaleResolver:
#Bean
public LocaleResolver localeResolver() //The bean must be named localeResolver.
{
return new SessionLocaleResolver();
}
This makes the LocaleResolver available to any code executed by the DispatcherServlet. That means other non-view JSPs do not have access to the LocaleResolver. To take care of this problem, you can create a Filter and set it up like this:
private ServletContext servletContext;
private LocaleResolver = new SessionLocaleResolver();
#Inject MessageSource messageSource;
...
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
{
request.setAttribute(
DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver
);
JstlUtils.exposeLocalizationContext(
(HttpServletRequest)request, this.messageSource
);
Now you need to configure Handler Interceptors:
You override the addInterceptors method of WebMvcConfigurerAdapter in your configuration class to set up LocaleChangeInterceptor (or any other interceptor for that matter.):
#Override
public void addInterceptors(InterceptorRegistry registry)
{
super.addInterceptors(registry);
registry.addInterceptor(new LocaleChangeInterceptor());
}
Now you can simply use an #Injected LocaleResolver on your controller. You simply call setLocale on the resolver to update the current locale.
Edit: More Specific Example:
Say you have a simple controller that has this:
#RequestMapping(value = "/", method = RequestMethod.GET)
public String index(Map<String, Object> model)
{
model.put("date", new Date());
model.put("alerts", 12);
model.put("numCritical", 0);
model.put("numImportant", 11);
model.put("numTrivial", 1);
return "home/index";
}
Then say you have messages_en_US.properties file under /WEB-INF/i18n/. This properties file contains messages localized for US English.
title.alerts=Server Alerts Page
alerts.current.date=Current Date and Time:
number.alerts=There {0,choice,0#are no alerts|1#is one alert|1
alert.details={0,choice,0#No alerts are|1#One alert is|1<{0,number,integer} > \
alerts are} critical. {1,choice,0#No alerts are|1#One alert is|1<{1,number,\
integer} alerts are} important. {2,choice,0#No alerts are|1#One alert \
is|1<{2,number,integer} alerts are} trivial.
Then, say that you have messages_es_MX.properties file under /WEB-INF/i18n/ and this file contains messages localized for
Mexican Spanish.
title.alerts=Server Alertas Página
alerts.current.date=Fecha y hora actual:
number.alerts={0,choice,0#No hay alertas|1#Hay una alerta|1
alert.details={0,choice,0#No hay alertas son críticos|1#Una alerta es \
crítica|1<{0,number,integer} alertas son críticos}. \
{1,choice,0#No hay alertas son importantes|1#Una alerta es importante\
|1<{1,number,integer} alertas son importantes}. \
{2,choice,0#No hay alertas son triviales|1#Una alerta es trivial\
|1<{2,number,integer} alertas son triviales}.
Now, you need to use <spring:message> tag in your JSP to translate between English and Spanish. This is how your jsp page will look like:
<spring:htmlEscape defaultHtmlEscape="true" />
<%--#elvariable id="date" type="java.util.Date"--%>
<%--#elvariable id="alerts" type="int"--%>
<%--#elvariable id="numCritical" type="int"--%>
<%--#elvariable id="numImportant" type="int"--%>
<%--#elvariable id="numTrivial" type="int"--%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%# taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<title><spring:message code="title.alerts" /></title>
</head>
<body>
<h2><spring:message code="title.alerts" /></h2>
<i><fmt:message key="alerts.current.date">
<fmt:param value="${date}" />
</fmt:message></i><br /><br />
<fmt:message key="number.alerts">
<fmt:param value="${alerts}" />
</fmt:message><c:if test="${alerts > 0}">
<spring:message code="alert.details">
<spring:argument value="${numCritical}" />
<spring:argument value="${numImportant}" />
<spring:argument value="${numTrivial}" />
</spring:message>
</c:if>
</body>
</html>
In my application.properties, I added this line :
spring.messages.basename=i18n/messages
spring.messages.cache-seconds=-1
spring.messages.encoding=UTF-8
You can remove the MessageSource bean with this.
Before I use
<spring:message code="javaquarium.welcome" text="default text" />
But I've thymleaf need this line :
<h1 th:text="#{javaquarium.welcome}"></h1>
Now message from messages.properties show correctly.
I have a form like this:
<form method="post" accept-charset="utf-8">
<fieldset>
<legend>Send a Message To Future</legend>
<label for="fullName">Your Name:</label>
<input type="text" name="fullName" id="fullName">
<br/>
<label for="message">Your Message:</label>
<textarea name="message" rows="3" id="message" style="width: 400px"></textarea>
<br/>
<button type="submit" class="btn">Submit</button>
</fieldset>
</form>
which is handled in
#RequestMapping(value = "/", method = RequestMethod.POST)
public String postMessage(Model model, MessageToFuture messageToFuture) {
String fullName = messageToFuture.getFullName();
String message = messageToFuture.getMessage();
System.out.println(fullName + " " + message);
if (fullName.length() == 0 || message.length() == 0) {
System.out.println("No no no!");
model.addAttribute("formNotFull", "Please fill in all the fields!");
return "index";
} else {
toFutureRepository.addMessageToFuture(messageToFuture);
return "redirect:/";
}
}
and in web.xml I have:
<page-encoding>UTF-8</page-encoding>
also the header of my jsp has:
<%# page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
And finally my configuration for Spring:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "biz.tugay.forFuture.web")
public class ServletConfigClass extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver =
new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
#Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
When I post the characters such as 'ğ', if the application is deployed to Tomcat, I am seeing weird characters. But if I run jetty, all is fine.
server.xml for Tomcat has:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8" />
What am I missing?
I tried both with Tomcat 7 and 8.
I'm making a web app using Spring 4, the Spring security module and tomcat 8. I'm trying to include some css files and js files in a .jsp file, but it's not working. When I check in the sources tag in Chrome the content of the css seems to be a log in form. I suspect that it may have something to do with spring security.
My css file is included like this in the .jsp
<link href="<c:url value='resources/css/materialize.min.css' />" rel="stylesheet"
type="text/css"></link>
This is the WebConfig file
#Configuration
#ComponentScan(basePackages = "mypackage")
#EnableWebMvc
#EnableTransactionManagement
public class WebAppConfig extends WebMvcConfigurerAdapter {
#Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
#Autowired
#Bean
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory){
HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory);
return transactionManager;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
This is the SecurityConfig file
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/js/**", "/resources/css/**", "/resources/img/**", "/resources/font/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().loginPage("/signin")
.failureUrl("/signin?param.error=bad_credentials")
.and().logout().logoutUrl("/signout")
.and().authorizeRequests()
.antMatchers("/favicon.ico", "/resources/css/**", "/resources/font/**",
"/resources/js/**", "/auth/**", "/signin/**", "/signup/**", "/disconnect/facebook").permitAll()
.antMatchers("/**").authenticated()
.and()
.rememberMe().
and().csrf();
}
}
According to other answers here in stackoverflow it should work with the code that I have but the css only returns this:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:social="http://spring.io/springsocial"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="layout">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<div id="content" >
<form id="signin" action="signup" method="post">
<input type="hidden" name="" value=""/>
<div class="formInfo">
</div>
<fieldset>
<label for="login">Email</label>
<input id="login" name="email" type="text" size="25"></input>
<label for="Nombre">Email</label>
<input id="nombre" name="nombre" type="text" size="25"></input>
<label for="password">Password</label>
<input id="password" name="contrasena" type="password" size="25"></input>
</fieldset>
<button type="submit">Sign In</button>
<p>Or you can signin with a new account.</p>
</form>
</div>
All my css and js files are inside WebContent/resources
I solved the problem, apparently there was an ambiguous routing in one of my controllers, so when I tried to access a url that started with "/resources" it routed it to the controller, and thus returned a .jsp instead of the css/js/image. My original controller binded the url in the #Controller, and left the #RequestMapping without indicating the route.
#Controller("/signup")
public class SignUpController {
#RequestMapping(method=RequestMethod.GET)
public String signUpForm(){
...
}
#RequestMapping(method=RequestMethod.POST)
public String crearUsuario(HttpServletRequest request){
...
}
So I changed the #Controller annotation, and put the url in each #RequestMapping like this:
#Controller
public class SignUpController {
#RequestMapping(value="/signup", method=RequestMethod.GET)
public String signUpForm(){}
#RequestMapping(value="/signup",method=RequestMethod.POST)
public String crearUsuario(HttpServletRequest request){}
}
I have a string variable that I create in a controller class and I want to print it in a jsp page using this
${time}
My code works if I don't use a thymeleaf view resolver, but if I do use one it doesn't work.
Here is my controller class
#Controller
public class HomeController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
String thetime = "the time";
model.addAttribute("time", thetime );
return "home.jsp";
}
And my .jsp page
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>
Hello world!
</h1>
<P> The time on the server is ${time}. </P>
</body>
</html>
My thymeleaf resolver configuration:
#Bean
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
resolver.setOrder(1);
resolver.setCacheable(false);
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver());
engine.setMessageSource(messageSource());
return engine;
}
#Bean
public ThymeleafViewResolver thymeleafViewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
String[] vistas = {"*.html", "*.jsp"};
resolver.setTemplateEngine(templateEngine());
resolver.setOrder(1);
resolver.setViewNames(vistas);
resolver.setCache(false);
return resolver;
}
#Bean
public SpringResourceTemplateResolver thymeleafSpringResource() {
SpringResourceTemplateResolver vista = new SpringResourceTemplateResolver();
vista.setTemplateMode("HTML5");
return vista;
}
Is there a special notation to do this with thymeleaf?
You have set your view resolver to be Thymeleaf but you trying to render JSP thats why it isn't working.
if you want that file converted to Thymeleaf format it needs to look like this (or approx) and the extension has to be .html not .jsp:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Home</title>
</head>
<body>
<h1>
Hello world!
</h1>
<P> The time on the server is <div th:text=#{time}>TIME_PLACEHOLDER</div> </P>
</body>
</html>
Aesir's answer worked, but it wasn't necesary to change my .jsp page to a .html page. I just put this
<div th:text="${time}">TIME_PLACEHOLDER</div>
instead of just ${time}, and it worked without the HTML header that was suggested.