Parsing data Spring MVC - java

Controller:
#Controller
public class WeatherController {
#GetMapping("/weather")
public String weatherForm(Model model){
model.addAttribute("weather",new WeatherServiceImpl());
return "weather";
}
#PostMapping("/weather")
public String weatherSubmit(#ModelAttribute WeatherServiceImpl weather) {
return "result";
}
}
template
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Handling Form Submission</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Form</h1>
<form action="#" th:action="#{/weather}" th:object="${weather}" method="post">
<p>City: <input type="text" th:field="*{city}" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
</body>
</html>
result template
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Handling Form Submission</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Result</h1>
<p th:text="'city: ' + ${weather.city}" />
Submit another message
</body>
</html>
So I am trying to get city name from user using a form and parse it to object. It parses to object. But I try to show the city name that I got from /weather it wont go to /result and will show an error message
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Wed Jun 20 20:42:53 EEST 2018
There was an unexpected error (type=Internal Server Error, status=500).
An error happened during template parsing (template: "class path resource [templates/result.html]")

Change post method as this.
#PostMapping("/weather")
public String weatherSubmit( WeatherServiceImpl weather,Model model) {
model.addAttribute("weather",weather);
return "result";
}
Find working code here. https://gitlab.com/supun/spring-boot-app/commit/b322644255e044ca5959460dd7d9f7a048a5f6d3

Please try closing paragraph tag.
<p th:text="'city: ' + ${weather.city}" ></p>

Related

How to correctly access URLs via #GetMapping?

I'm currently working on a Docker-deployed Spring application with an nginx-reverse proxy and want to access a subdomain via #GetMapping & #PostMapping.
What is the correct way to access e.g. the /entity/add subdomain?
Is this a code error or might my server be malconfigured? Is there anything else needed in order to correctly review this problem? I'll gladly add it.
I've looked up the official documentation, guides, other StackOverflow posts etc., but none of them seem to work.
Controller.java:
public class EntityController {
private Repository repository;
#ModelAttribute("entity")
public Entity newEntity() {
return new Entity();
}
// Overview.
#GetMapping("/entity")
public String index(Model model) {
final Iterable<Entity> all = repository.findAll();
model.addAttribute("all", all);
return "index";
}
// New entity.
#GetMapping("/entity/add")
public String loadAddPage(Model model) {
model.addAttribute("entity", new Entity());
return "add";
}
#PostMapping("/entity/add")
public String submitEntity(#Valid #ModelAttribute Entity entity, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "add";
}
repository.save(entity);
return "redirect:/index";
}
index.html:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Overview</title>
<meta charset="UTF-8" />
</head>
<body>
<div class="container">
<h2>Entities</h2>
<form action="/entity/add" method="get">
<input type="submit" value="New Entity"/>
</form>
<div class="content" th:each="entity: ${all}">
<h2 th:text="${entity.name}">Name</h2>
<form th:href="#{/entity/details?id={entityId}(entityId=${entity.id})}">
<input type="submit" value="Edit"/>
</form>
<!--<button><a th:href="#{/entity/update?entityId={entityId}(entityId=${entity.id})}"></a></button>-->
</div>
</div>
</body>
</html>
add.hmtl:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<title>New entity</title>
<meta http-equiv="Content-Type" content="text/html" charset="UTF-8" />
</head>
<body>
<div class="container">
<form action="/entity/add" method="post" th:object="${entity}">
<table>
<tr>
<td><label for="name">Name</label></td>
<td><input id="name" type="text" th:text="Name" th:field="*{name}" /></td>
</tr>
</table>
</form>
</div>
</body>
</html>
I expect that a click on the /entity/add-form in index.html correctly links me to entity/add, but it just displays a 404 error. Same with other tested subdomains.
Edit 01: Title updated. (access subdomains -> access URLs)
I understand your question as you need to submit the form to this action url "/entity/add" with method POST. Consider using the Thymeleaf view templates for rendering the server side actions. Check with the following
Change the HTML action attribute to th:action attribute.
Provide the Submit action button to submit the form.
Check this url for more information: https://spring.io/guides/gs/handling-form-submission/
Disclaimer: This is my comment for your question. As I don't have the reputation, I am posting as answer.
I suppose you are using thymeleaf for templating.
Add following in application.properties file:
spring.application.name: my-app-context-path
In Controller :
#GetMapping({"/", "/index"})
public String defaultPage(final Model model, final Locale locale) throws MyException {
addGameInfo(model);
return "index";
}
#GetMapping({"/match/{gameId}"}){
--------
------
}
In view:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
....
....
<h1 class="text-primary">Featured Games</h1><a class="btn btn-flat btn-primary" th:href="#{/match/2944107874}">Game Info 2944107874</a>
....
.....
</html>
You should checkout Thymeleaf Standard URL Syntax
So your url will be resolved to
1.http://localhost:2223/my-app-context-path/
2.http://localhost:2223/my-app-context-path/match/2944107874
It depends on your context path, if you are not providing one, you can access mappings directly.

Model attribute is not available as request attribute in JSP page

I am trying to create a sample registration page with Spring MVC and JSP pages.
While opening the url on tomcat server, I am getting following error
root cause
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'register' available as request attribute
org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:144)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:168)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(
I have a JSP register.jsp
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Registration</title>
</head>
<body>
<form:form action="/register/process" method="POST" modelAttribute="register">
<table style="text-align: center;">
<tr>
<td><form:label path="fname">First Name</form:label></td>
<td><form:input path="fname" name="fname"
id="fname" /></td>
</tr>
<tr>
<td><form:label path="lname">Last Name</form:label></td>
<td><form:input path="lname" name="lname" id="lname" />
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" value="CREATE AN ACCOUNT"/>
</td>
</tr>
</table>
</form:form>
</body>
</html>
I have a controller class UserController.java
package vnfhub.supplier.controller;
#Controller
public class UserController {
#RequestMapping(value = "/register", method = RequestMethod.GET)
public String getRegisterForm(Model model) {
model.addAttribute("register", new Register());
return "register";
}
#RequestMapping(value = "/register/process", method = RequestMethod.POST)
public String processRegistration(#ModelAttribute("register") Register register, BindingResult result) {
return "success";
}
}
and a success.jsp page
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Success Form</title>
</head>
<body>
<font color="green"><h1>Hello</h1></font>
<h1>You have successfully registered</h1>
<font color="green"><h1>Welcome to Spring world !</h1></font>
</body>
</html>
I have tried many solution on stackoverflow.... but none of them worked.
I find your code okay so far as you given here. I mimic the situation with your code but unfortuantely found No Exception.
Things that you might have doing wrong is you are running some old build code in your tomcat. try to clean build and re-deploy in your container.
NB: one friendly suggestion. You are doing one thing wrong that is having action of your form to /register/process that will send the request to the container root (e.g. localhost:8080/register/process). And you will get 404 for that. You are not probably want that. register/process should be your URL and this will POST the request relative to your application-context. If your application context is something localhost:8080/test, this will send the request to localhost:8080/test/register/process

Render fragment contents with Thymeleaf

I'm tryting to have email templates rendered using Thymeleaf and I would like to have the subject and the body in the same file, but rendered separately. I do not want to use spring view, just plain SpringTemplateEngine.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<!--/*#thymesVar id="user" type="com.myapp.user.User"*/-->
<!--/*#thymesVar id="invitationId" type="java.util.UUID"*/-->
<head>
<title th:fragment="subject">Hello <span th:text="${user.name}"/></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<p>
Hello <span th:text="${user.name}"></span>,<br>
you've been invited to join MyApp.
</p>
<p>
Click on the following link to confirm your email and setup a password:<br>
<a th:href="#{https://myapp.com/accept-invitation(id=${invitationId})}">Accept invitation</a>
</p>
<p>
Best regards,<br/>
<em>The MyApp team</em>
</p>
</body>
</html>
There are several problems with this
First, I'm unable to get Thymeleaf render only contents of <title>
String subject = templateEngine.process(
templateFile,
ImmutableSet.of("subject"),
new Context(Locale.ENGLISH, contextVariables)
);
it renders literary only Hello - it looks like the opening <title> tag is always removed and the fragment is trimmer right after the first tag.
And when I render the whole template, it returns
<!DOCTYPE html>
<html>
<head>
Hello <span>pepa</span></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<p>
Hello <span>pepa</span>,<br>
...
Using the following in the <title> makes the output a bit nicer
<span th:text="${user.name}" th:remove="tag"></span>
but the opening tag is still missing.
When I would theoretically succeed in rendering the title correctly, I'd still have it wrapped in an HTML tag - which obviously cannot be used as an email subject. Is there a way to render only contents of the fragment?
I would really like to have both the email subject and body in the same template for cases, when for example I want to do some iteration in the title to generate it from a list - I do not want to do any string concatenations, I wanna have it in the template.
Any suggestions please?
If you want to include only the content of your fragment, assuming that your fragment is called your_fragment.html and is placed under /resources/templates/fragments you can do:
<head>
<title th:replace="fragments/your_fragment::your_fragment"/></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
And your_fragment.html:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head></head>
<body>
<div th:fragment="your_fragment" th:remove="tag">
Hello <span th:text="${user.name}" th:remove="tag"></span>
</div>
</body>
</html>
This will render:
<head>
Hello username
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>

jsp bean's Scope Request doesn't work

I have a problem with JSP Bean's scope - Request. I have a page Index.jsp with jsp bean 'message', its scope is Request and a page result.jsp. When I send request to result.jsp from Index.jsp. My bean 'message' should keep its value but it doesn't now.
I tried with scope Session and my bean worked well. I search all questions about this problem but no answer can meet my question.
Here is my code:
file Index.jsp
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<%
String name = request.getParameter("name") == null ? "" :
request.getParameter("name");
int age = ( request.getParameter("age") == null ||
request.getParameter("age") == "") ? 0 :
Integer.parseInt(request.getParameter("age"));
%>
<h1>Nice to meet you</h1>
<form method="post" action="View/result.jsp">
<jsp:useBean id="message" class="com.java.Message" scope="request"/>
<jsp:setProperty name="message" property="message" value="Hello world!"/>
<label>Name: </label> <br>
<input type="text" name="name" placeholder = "Phan Dinh The"/> <br>
<label>Age: </label> <br>
<input type="number" name="age" placeholder = "25"/> <br>
<input type="checkbox" name="title"/> Senior <br>
<input type="radio" name="language" value="c#"/> C# <br>
<input type="radio" name="language" value="java"/> Java <br>
<br><br>
<jsp:include page="View/date.jsp" flush="true"/>
<input type="submit" value="submit"/>
<br><br>
</form>
<br><br>
</body>
</html>
file result.jsp
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="com.java.Message"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<jsp:useBean id="message" class="com.java.Message" scope="request"/>
<jsp:getProperty name="message" property="message"/>
</body>
</html>
my class Message
package com.java;
public class Message {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String content) {
this.message = content;
}
}
I use Tomcat 8.0.23, Jsp version 2.3, Servlet API 3.1
When you use
<jsp:setProperty name="message" property="message" value="Hello world!"/>
in the index.jsp file, that property is scoped to the request of the index.jsp page. once the index jsp page returns to the client, that request is done. When you submit the form, a new request is created, and that is used for the result page generation. Thus when you are in the result.jsp code, there is no request scoped parameter named 'message'.
You could always put the message in an
<input type="hidden" name="message">Hello World</input>
field of the form, and retrieve it in the results.jsp that way.

Can't get parameter from the page via servlet

It should be simple, but i have a problem,
This is my *.jsp file
<html>
<head>
<title>Edit DataBase data</title>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>New Page 1</title>
</head>
<body>
<hr size="2"/>
<h2>id in DB = ?</h2>
<p>id:<input type="text" name="id" size="20" value="sdfs"></p>
<p>
<form action="/web/save" method="POST">
<input class="button" type="submit" value="submit" />
</form>
</p>
</form>
</body>
</html>
servlet looks like this
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String id = request.getParameter("id")
System.out.println("ID=" + id);
}
but in output ID=null
servlet was loaded by the button click on the server
You need to put the input tag in between the form tags.
For the code you put here
<form action="" method="POST">
is correct.
Check, you might have put
<form action="" method="GET">

Categories