index.jsp
<!DOCTYPE html>
<html>
<head>
<title> Home Page|Spring MVC </title>
</head>
<body>
<h2>Welcome to spring mvc</h2>
Form
</body>
</html>
Below is my controller code
#RequestMapping("/showForm")
public String showForm() {
return "showForm.jsp";
}
Here is the jsp code I am using to render the showForm.jsp page, the problem is that whenever I am using /showForm it gives 404 and when I use showForm it render the showForm.jsp page.
You just have to return name of the .jsp page from the endpoint and also you have to append context path of the request with URI.
Modify to this :
index.jsp
<!DOCTYPE html>
<html>
<head>
<title> Home Page|Spring MVC </title>
</head>
<body>
<h2>Welcome to spring mvc</h2>
Form
</body>
</html>
Controller :
#RequestMapping("/showForm")
public String showForm() {
return "showForm";
}
It should work.
My thymeleaf form is not picking up the input longUrl. When I run the application on debug, it hits the post request below with "". How can I make it pick up the form input and send it over in the body?
Thymeleaf Form:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="POST" th:action="#{create_short_url_thymeleaf}">
<h1>Hit Enter to Shorten Your Long Url</h1>
<input type="text" th:name="longUrl"/>
</form>
</body>
</html>
Even when I try to manually populate the value, it still doesn't make it into the controller
<input type="text" name="longUrl" value="somelongurl"/>
Controller Code:
#Controller
#RequestMapping("/api/v1")
public class UrlShorteningController {
#GetMapping("/create_short_url")
public String newShortUrl(Model model) {
model.addAttribute("longUrl",
"");
return "some-form";
}
#PostMapping("/create_short_url_thymeleaf")
ResponseEntity<String> newShortUrlFromThymeleaf(#ModelAttribute String longUrl) {
// Running the application on debug, I make it here, but the longUrl is empty.
....
}
try to replace
th:action="#{create_short_url_thymeleaf} with
th:action="#{/create_short_url_thymeleaf}
Ah, I solved it. I needed to swap that #ModelMapper annotation for a #RequestBody and now it works.
I'm working on a new app using Spring 4 and Thymeleaf 3.
My LoginController.java has the following mapping:
#RequestMapping(value = { "/", "/home", "/welcome" }, method = RequestMethod.GET)
public String index(Principal principal) {
//logs debug message
if(logger.isDebugEnabled()){
logger.debug("getWelcome is executed!");
}
return principal != null ? "home/homeSignedIn" : "home/homeNotSignedIn";
}
So, when I access the app, without being logged in the called page is home/homeNotSignedIn.html, which is posted bellow.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="fragments/app">
<head>
<title th:text="#{view.index.title}">Welcome!</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<div layout:fragment="content">
<div class="container2">
<th:block th:if="${message != null}">
<div th:replace="fragments/alert :: alertFragment (type=${#strings.toLowerCase(message.type)}, message=${message.message})"> </div>
</th:block>
<p />
<p />
Sign up
<p />
</div>
</div>
</body>
</html>
This page has a direct reference to a file called app.html which contains the layout for the application, seen bellow.
I'm having basically two problems.
1) Thymeleaf cries about this:
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/cms-stock] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "ServletContext resource [/WEB-INF/templates/home/homeNotSignedIn.html]")] with root cause
java.lang.IllegalArgumentException: layout:decorate/data-layout-decorate must appear in the root element of your template
2) Maybe related to 1), I get no CSS or JS loaded.
I have started this app as Spring-boot and, probably very stupid of me, I could't get it running. Then, adapted a working pom.xml from another app, and got the problem number 2, further described here.
I'm at a loss here. Please advise!
In my Spring Boot application, I'm trying to configure custom error pages, for example for 404, I have added a following Bean to my application configuration:
#Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
return new EmbeddedServletContainerCustomizer() {
#Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/404.html"));
}
};
}
Also, I have created a following simple Thymeleaf template:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>404 Not Found</title>
<meta charset="utf-8" />
</head>
<body>
<h3>404 Not Found</h3>
<h1 th:text="${errorCode}">404</h1>
<p th:utext="${errorMessage}">Error java.lang.NullPointerException</p>
Back to Home Page
</body>
</html>
and added it into /resources/templates/ folder. Right now on the 404 error I can see only white screen.
What am I doing wrong and how to correctly setup my 404 page? Also, is it possible to use templates and not only static pages for custom error pages?
In Spring Boot 1.4.x you can add a custom error page:
If you want to display a custom HTML error page for a given status code, you add a file to an /error folder. Error pages can either be static HTML (i.e. added under any of the static resource folders) or built using templates. The name of the file should be the exact status code or a series mask.
For example, to map 404 to a static HTML file, your folder structure would look like this:
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
You're using Thymeleaf, And Thymeleaf can handle error without a controller.
For a generic error page this Thymeleaf page need to be named as error.html
and should be placed under src/main/resources > templates > error.html
For specific error pages, you need to create files named as the http error code in a folder named error, like: src/main/resources/templates/error/404.html.
new ErrorPage(HttpStatus.NOT_FOUND, "/404.html")
That /404.html represents the URL Path to Redirect, not the template name. Since, you insist to use a template, you should create a controller that handles the /404.html and renders your 404.html resides in src/main/resources/templates:
#Controller
public class NotFoundController {
#RequestMapping("/404.html")
public String render404(Model model) {
// Add model attributes
return "404";
}
}
You could also replace these just view render-er controllers with a View Controller:
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/404.html").setViewName("404");
}
}
Also, is it possible to use templates and not only static pages for
custom error pages ?
Yes, it's possible. But Not Found pages are usually static and using a template instead of Plain Old HTMLs wouldn't make that much of a sense.
There is no need for the EmbeddedServletContainerCustomizer bean. Simply putting the corresponding error page (such as 404.html in case of 404) in the public directory should be enough (as pointed by #brunoid).
Also note that you can also put a generic error.html page that'll get displayed whenever your application encounters an error or exception.
A simple example (in Freemarker) -
<html lang="en">
<head>
</head>
<body>
<div class="container">
<div class="jumbotron alert-danger">
<h1>Oops. Something went wrong</h1>
<h2>${status} ${error}</h2>
</div>
</div>
</body>
</html>
This'll display proper error status and corresponding error message. And since you are using Spring Boot, you can always override the status and error messages that get displayed on your error page.
If you are using Thymeleaf like suggested in the question, you could use a template similar to the one from the previous reply, but appropriate for Thymeleaf rather than Freemarker. I have also added bootstrap for the styling:
<!DOCTYPE html>
<html lang="en"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Error Page</title>
<link href="/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css" rel="stylesheet" media="screen"/>
<script src="/webjars/jquery/3.2.1/jquery.min.js"></script>
<script src="/webjars/bootstrap/3.3.7-1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="jumbotron alert-danger">
<h1>Oops... something went wrong.</h1>
<h2 th:text="${status + ' ' + error}"></h2>
</div>
</div>
</body>
</html>
You should place this code in a file called error.html and place it in your thymeleaf templates directory. There is no need to add an additional controller for it to work.
Check if you have thymeleaf present in the classpath, or add below code and reimport the project.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
We have to add new
#Controller
public class MyErrorController implements ErrorController {
#RequestMapping("/error")
public String handleError(HttpServletRequest request) {
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
if (status != null) {
Integer statusCode = Integer.valueOf(status.toString());
if(statusCode == HttpStatus.NOT_FOUND.value()) {
return "error404";
}
else if(statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
return "error500";
}
}
return "error";
}
#Override
public String getErrorPath() {
return "/error";
}
}
enter image description hereIt's very easy to do in Spring Boot Application.
Spring Boot all most done all thing for us.
1)In Path src/main/resources/templates
make folder which has name 'error'
2)Next create html file in this folder,
save it as '404.html'.
You done evey thing here.
Spring Boot Automatically show this page if it got 404 page not found error.
Note: Before going to this, make sure that you added Thymeleaf repository in your pom. xml
Thymeleaf can handle error without a controller.
create error.html to resources folder.
I am practising thymeleaf template engine for the first time. I have followed the tutorial and so on but I have no idea where I am going wrong.
My controller:
public String mainPage(Model model){
model.addAttribute("data", "Hello Thymeleaf");
return "main";
}
and my html is as follows:
<!DOCTYPE html >
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>th:text="${data}"</h1>
</body>
</html>
When I hit localhost it displays th:text="${data}" instead of Hello Thymeleaf
<h1>"${data}"</h1>
doesn't work either. View resolver config must be correct as it resolves main to main.html. I am using spring4 SpringTemplateEngine and spring4 thymeleaf view resolver.
thanks in advance
You have to use th:text
<h1 th:text="${data}"></h1>
or if you don't want to use the th:text attribute, then you have to use th:inline="text" and make the thymeleaf render the context inside the tag. But make sure you put the variable inside [[ and ]]
<h1 th:inline="text">[[${data}]]</h1>
Thymeleaf isn't Velocity or Freemarker and doesn't replace expressions blindly. You need the expression in an appropriate tag attribute, such as
<h1 data-th-text="${data}" />
remove quotes to "${data}" and just use ${data}. I also agree with #Faraj Farook