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.
Related
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.
Hi Guys!
I have been implementing service in Spring Boot which
allows users to send anonymouse questionaries to server.
I have already implemented most of the backend like adding users etc. and right now I have been struggling with one action which take answers from user and sends into server (save in database).
Object containing answers (filledSurvey) is being sent as empty. In this same logic in logging users fields from form are corectly send forward.
This endpoint displays questionary:
#RequestMapping(path = {"/try", "/try/{id}"})
public String tryCompletingSurvey(Model model, #PathVariable("id") Long id) {
Connection connection = connectionService.getConnection(id);
FilledSurvey filledSurvey = connection.getSurvey().getTemplate();
for (FilledQuestion filledQuestion : filledSurvey.getFilledQuestions()) {
filledQuestion.getFilledAnswers().get(0).setCheck(true);
}
model.addAttribute("filledSurvey", filledSurvey);
return "completing/completing";
}
This is thymeleaf html:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Completing survey</title>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css">
</head>
<body>
<center>
<form action="#" th:action="#{/user/surveys/finish}" th:object="${filledSurvey}" method="post">
<!-- <div th:each="question, questionStat : ${survey.getFilledQuestions()}" >-->
<!-- <p th:text="${question.getQuestion()}"></p>-->
<!-- <div th:each="answer, answerStat: ${question.getFilledAnswers()}" >-->
<!-- <input type="radio"-->
<!-- th:name="question+${questionStat.index}"-->
<!-- th:field="*{}"-->
<!-- th:value="${true}">-->
<!-- <label th:text="${answer.answer}">-->
<!-- </label>-->
<!-- </div>-->
<!-- </div>-->
<h2>Survey name: </h2>
<h3 th:text="${filledSurvey.getSurveyName()}"></h3>
<h2>Number of questions: </h2>
<h3 th:text="${filledSurvey.filledQuestions.size()}"></h3>
<div class="col-md-6">
<input type="submit" style="align-content: center" class="btn btn-primary" value=" Send ">
</div>
</form>
</center>
</body>
</html>
And this is endpoint which stores empty object from thymeleaf:
#RequestMapping(path = "/finish", method = RequestMethod.POST)
public String getHash(FilledSurvey filledSurvey) {
StringBuilder sb = new StringBuilder();
for (FilledQuestion question : filledSurvey.getFilledQuestions()) {
for (FilledAnswer answer : question.getFilledAnswers()) {
if (answer.isCheck()) sb.append(answer.getAnswer());
}
}
LocalDateTime date = LocalDateTime.now();
sb.append(date);
String hash = sb.toString();
hash = Base64.getEncoder().encodeToString(sb.toString().getBytes());
filledSurvey.setHash(hash);
surveyMagazinService.addSurveyToMagazin(filledSurvey);
return "completing/finish";
}
I changed code to automaticly mark answers for now.
This the picture of the object in the next endpoint:
filledSurvey object
I am aware that this is common question but i have been looking for the answer for a while now and couldn't figure it out. I have no errors in the console as well. I would appreciate any help or feedback.
If I understood correctly, I see following issue:
You are using a form to submit the survey data and use the th:object="${filledSurvey}" to bind the data. But there is actually not data send back to the controller, when the form is submitted, because there are no input fields defined that have the th:field attribute applied.
The request that will be send to the server on a submit, will contain form encoded data of all fields that you assign a th:field attribute to. The controller will map the form encoded data to a FilledSurvey object using java bean convention in the getHash method.
EDIT: can you try adding the #ModelAttribute annotation:
#RequestMapping(path = "/finish", method = RequestMethod.POST)
public String getHash(#ModelAttribute FilledSurvey filledSurvey) {
...
Try adding an input field like this inside your form:
<input type="hidden" th:field="*{surveyId}" >
This should give you at least an FilledSurvey object with the id set on your "/finish" endpoint. You can then use the id to fetch the survey like its done in the first code snippet.
The way you are using the th:field within your list of questions will not work, because spring cannot map this kind of structure. See https://spring.io/guides/gs/handling-form-submission/ to understand how form submission works with spring mvc.
I hope this helps a bit, best regards ;)
I am trying to get a list of objects that are sent to the server from the html form as parameters for my list, then I will loop through those entries and then return them through the springboot th:each. But it doesn't seem to be working at all. On load the form appears but when I enter a value in it, then it returns an error page and the URL however turns:
http://localhost:8080/#%7B/%7D?%24%7Bcontent%7D=hello
this output in eclipse says:
Expression "content" is not valid: only variable expressions ${...} or selection expressions *{...} are allowed in Spring field bindings
Note: content here is the value property in my form.
My controller looks like this:
#Controller
public HelloList() {
this.addUs = new ArrayList <>();
}
#RequestMapping("/")
public String getlist(#RequestParam (required = false) String content, Model model) {
if (content != null && !content.trim().isEmpty()) {
this.addUs.add(content);
}
model.addAttribute("list",addUs);
return "index";
}
the index.html looks like this
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Insert title here</title>
</head>
<body>
<div>
<ul>
<li th:each="amHere: ${addUs}">
<span th:text="${amHere}">hello! world</span>
</li>
</ul>
<form action="#{/}" method="GET">
<input type="text" name="content"/>
<input type="submit" value="Submit"/>
</form>
</div>
</body>
</html>
This might be a duplicate but it seems like most of the solutions I came across are not helping. So any help is mostly appreciated. Thank you in advance.
Turns out I was missing the initialization of my list in the constructor. I initialized the list by adding a value to it first in the constructor like this.
this.addUs.add("Hello World");
Because the #RequestMapping is mapped to the home path in my case index.html, any request gets sent there automatically.
working example
action = "#{/}" should be th:action="#{/}". That's the reason you're seeing the weird url (because it's url encoding #{/}). Thymeleaf only evaluates expressions that start with th:.
I'm not sure about the other error. It looks like the html you've pasted doesn't match up with the error you are getting.
If you urldecode http://localhost:8080/#%7B/%7D?%24%7Bcontent%7D=hello, you get http://localhost:8080/#{/}?${content}=hello, which doesn't line up with your form.
I'm trying to write a simple web app in JSP that allows user to choose 2 numbers in the range 1-100 from 2 drop-down lists and then print out those numbers. However, I keep receiving the error message:
Below is my code:
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Game Table</title>
</head>
<body>
<form method="post">
#rows:
<select name="row">
<%
for(int i=1;i<=100;i++){
out.println("<option value="+"\""+i+"\""+">"+i+"</option>");
}
%>
</select>
#columns:
<select name="column">
<%
for(int i=1;i<=100;i++){
out.println("<option value="+"\""+i+"\""+">"+i+"</option>");
}
%>
</form>
<%
String row=request.getParameter("row");
String column=request.getParameter("column");
if(row!=null && column!=null){
out.println(row+" "+column);
}
%>
</body>
Thank you so much
well, problem is in navigation not in your code. For not showing dropdown menu so use proper url mapping to run your jsp like http://localhost:8080/yourwebprojectname/game.jsp game.jsp is assumption of your following above code page name.
Your code have many error like missing of action="" like
<form method="post" action="book.jsp">
</Select> tag above the form
Main problem is you dont have any button or use of ajax to show the output that you trying to display via Scriptlet
for simple solution add a button inside your form
<input type="submit" value="show" name="show"/>
add code something like this inside your Scriptlet
if("show".equals(request.getParameter("show"))){
if(row!=null && column!=null){
out.println(row+" "+column);
}
}
I am not completely sure, but it might be returning 404 (not found) because you are not submitting this data correctly. See, there is no "action" atribute indicating where it should go (e.g. "save.jsp").
Hope it helps! :)
I am trying to create a registration JSP page which when submit is clicked I would like it to pass the information entered to an addUser method in a java class
This is my JSP Page:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
<title>Registration</title>
</head>
<body>
<center>
<h2>Signup Details</h2>
<form action="RegisterUser.java" method="post">
<br/>Username:<input type="text" name="username">
<br/>Password:<input type="password" name="password">
<br/>Email:<input type="text" name="email">
<%= String name = request.getParameter("username");
String pass = request.getParameter("password");
String email = request.getParameter("email");
User u = new User();
u.setName(name);
u.setPassword(pass);
u.setEmail(email);%>
<br/><input type="submit" value="Submit" action="RegisterUser.addUser(u)">
</form>
</center>
</body>
</html>
When Submit is clicked I want to add the details to a database using the following method
public class RegisterUser {
private static final String PERSISTENCE_UNIT_NAME = "User";
private static EntityManagerFactory factory;
private User user;
public void addUser(User user){
factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = factory.createEntityManager();
// Create new user
em.getTransaction().begin();
em.persist(user);
em.getTransaction().commit();
em.close();
You have to create a Servlet that processes your form and calls the addUser() method.
You can't invoke a Java method directly from JavaScript.
Here's a good tutorial on the subject.
http://www.tutorialspoint.com/servlets/servlets-form-data.htm
You generally pass request data to Servlet which acts as controller and depending on request it delegates logical calls to services class
Check out the complete flow with example and nice explanation on servlet wiki page
You need to work with a Servlet that will work as Controller in your Model. The View, the JSP in your case, should be able to communicate with your Model using a Servlet.
For a good separation between the Model, Controller and the View you can use Spring MVC. Here is a good example that you can follow as start point: http://www.mkyong.com/spring-mvc/spring-mvc-hello-world-example.
Did you try closing down eclipse and opening it again? If not try restarting eclipse. It works for me every time.