How can I get a response in the same View using SpringBoot? - java

I'm making a simple SpringBoot app that returns a word inserted by the user via a form. I managed to get the response in another view (the form is in home.html, the answer in answer.html) but now I want to get the response in the "home" view. I tried to adapt the code from the two-view version, but it doesn't work. Any thoughts? Thanks!
the HTML view:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Add a word</title>
</head>
<body>
<th:form action="/" object="word" method="POST">
<label>Dictionary - Add a word</label>
<br>
<input name="value">
<br>
<button type="submit">Submit</button>
</th:form>
<p th:text="${value}"></p>
</body>
</html>
The controller:
#RestController
public class Controller {
#GetMapping("/")
public ModelAndView home() {
return new ModelAndView("home", "word", new Word());
}
#PostMapping("/")
public ModelAndView home(#ModelAttribute("word") Word w, Model model) {
ModelAndView mAv = new ModelAndView("home", "word", model);
model.addAttribute("value", w.getValue());
return mAv;
}
}

Related

SPRING MVC: returned ModelAndView/parameters precedence

I'm new in Spring, and I'm trying to better undestand the MVC framework.
Considering the following jsp:
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello World!</title>
</head>
<body>
Welcome <%=request.getAttribute("username")%>
</body>
</html>
I see that, in a #Controller class:
#GetMapping("/EntryPoint1")
public String helloView1(Model model) {
model.addAttribute("username", "pippo");
return "HelloWorld";
}
it uses as username value the one inserted in model.
However, if I declare both the Model model parameter and I return a ModelAndView object, that is:
#GetMapping("/EntryPoint2")
public ModelAndView helloView2(Model model) {
model.addAttribute("username", "pluto");
ModelAndView mav = new ModelAndView("HelloWorld");
mav.addObject("username", "paperino");
return mav;
}
I obtain that the value used by the view is the one contained in mav ignoring the value in model. Is there an explanation for this (for example, any kind of precedence between the objects considered by the view)?
see, here in model.addAttribute("username", "pluto");
and in mav.addObject("username", "paperino");
username is same so priorities goes to ModelAndView, However u change the name then u can render them both and access.

How to fix "Exception evaluating SpringEL expression" error after submitting a variable Spring/Thymeleaf

I am using Spring Boot/Thymeleaf to create a form that accepts an email address, redirects to a results page that displays the accepted email and sends it to a third party API (authenticated with Oauth2). I am having trouble with the form portion, I am attempting to use Thymeleaf to accept the input to display it on the result.html page. I am receiving an error when trying to display it on the results page, full error is:
[THYMELEAF][http-nio-8080-exec-4] Exception processing template "result.html": Exception evaluating SpringEL expression: "signup.email" (template: "result.html" - line 10, col 4)
I was attempting to follow the examples provided here:
https://spring.io/guides/gs/handling-form-submission/
I have attempted to modify the controller from #PostMapping and #GetMapping to #RequestMapping and add commenting described in a workaround such as:
<!--/*#thymesVar id="signup" type="com.mainconfig.controller1"*/-->
Here is the signup.html code containing the form:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html>
<head>
<title>My Jmml</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body style="background-color: #2B2B2B">
<br /><br />
<h2 style="text-align:center">Contact Information</h2>
<!-- Input Form -->
<!--/*#thymesVar id="signup" type="com.mainconfig.controller1"*/-->
<form action="#" th:action="#{/signup}" th:object="${signup}" method="post">
<div align="center">
<label>Email Address</label><br /><br />
<!--/*#thymesVar id="email" type="String"*/-->
<input type="text" th:field="*{email}" placeholder="Email" required />
<br />
<br />
<input class="submitbutton" type='submit' value='Submit'/>
<br />
</div>
</form>
</body>
</html>
Results page that should display the email (result.html):
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Thank you for your submission!</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Thank you for your submission!</h1>
<p th:text="'Email: ' + ${signup.email}" />
Submit another message
</body>
</html>
Controller:
#Controller
public class controller1 {
#RequestMapping (value = "/home")
public String home(Model model) {
return "index.html";
}
#RequestMapping(value = "/signup", method= RequestMethod.GET)
public String signupForm(Model model) {
model.addAttribute("signup", new emailInput());
return "signup.html";
}
#RequestMapping(value = "/signup", method= RequestMethod.POST)
public String signupSubmit(#ModelAttribute("email") emailInput email) {
return "result.html";
}
}
Expected output should be the email variable displayed on the results page after it being gathered in the signup form.
If you have a recommendation on how to better do what I am attempting, I am open to suggestions! I am very new to Spring/Thymeleaf but have had experience with Java/Jsp. Thank you for any help, please let me know if you need anything else to help!
Hopefully this will be a starting point for you.
Make sure you place the html files under /resources/templates.
I changed a bit your signup html and result.html as follows, they are still not perfect(avoid using inline styles and use an external stylesheet!):
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<title>My Jmml</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body style="background-color: #2B2B2B">
<br /><br />
<h2 style="text-align:center">Contact Information</h2>
<!-- Input Form -->
<!--/*#thymesVar id="signup" type="com.mainconfig.controller1"*/-->
<form th:action="#{/signup}" th:object="${signup}" method="post">
<div align="center">
<label>Email Address</label><br /><br />
<!--/*#thymesVar id="email" type="String"*/-->
<input type="text" th:field="*{email}" placeholder="Email" />
<br />
<br />
<input class="submitbutton" type="submit" value="Submit"/>
<br />
</div>
</form>
</body>
and the result.html looks like this
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<title>Thank you for your submission!</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Thank you for your submission!</h1>
<p th:text="'Email: ' + ${email}" />
Submit another message
</body>
</html>
I also created a form object, add additional fields here if you want
public class SignUpForm {
//you can put some annotations here if you want for validating the email
//for e.g #NotEmpty or a #Pattern(regexp to validate the email)
private String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
and in the end your Controller. I pass the email from the signup post request to the result.html via a flash attribute:
#Controller
public class Controller1 {
#RequestMapping(value = "/signup", method= RequestMethod.GET)
public String signupForm(#ModelAttribute("signup") SignUpForm form) {
return "/signup";
}
#RequestMapping(value = "/signup", method= RequestMethod.POST)
public String signupSubmit(#ModelAttribute("signup") SignUpForm form, RedirectAttributes redirectAttributes) {
//validate form first -> check bindingResult documentation
//do what you need with your form object
redirectAttributes.addFlashAttribute("email", form.getEmail());
return "redirect:/result";
}
#RequestMapping(value = "/result", method= RequestMethod.GET)
public String result() {
return "/result";
}
}

Not able to bind values from Thymeleaf based UI form to a controller in Spring Boot

My application is not able to bind a form value from an Thymeleaf + HTML based UI to a Spring Boot controller.
I am getting that value as null when I do a System.out.println into the controller.
index.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<p>Get your greeting here</p>
<form action="/publishMessage" method="post">
<table>
<tr>
<th>CHARGE</th>
</tr>
<tr>
<td>
<textarea th:field="*{messageBody}" name="" cols="90" rows="40">
{
"firstname": "Jose",
"lastname": "Long"
}
</textarea>
</td>
</tr>
<tr>
<td><input type="submit" name="btnSubmit" value="Publish CHARGE message"></td>
</tr>
</table>
</form>
</body>
</html>
PublishMessageController.java
#Controller
public class PublishMessageController {
#PostMapping("/publishMessage")
public String publishMessage(Message message, BindingResult bindingResult, Model model) {
System.out.println("into the publishMessage method..........");
String messageBody = message.getMessageBody();
System.out.println("messageBody: " + messageBody);
return "result";
}
}
Message.java
import lombok.*;
#Data
#Getter
#Setter
#NoArgsConstructor
public class Message {
private String messageBody;
}
Output:
into the publishMessage method..........
messageBody: null
Your message never gets put into the model, so you can't use it as variable in your controller.
Spring model attributes
Handling the command object
BTW: The method shouldn't return "result" but the String of the message body.
Put your messageBody to model where you show your form:
#RequestMapping(value = "/showForm", method=RequestMethod.GET)
public String showForm(Model model) {
...
String messageBody = ...
model.addAttribute("messageBody", messageBody);
...
}
To use this in your view, add th:action and th:object to your form:
<form action="#" th:action="#{/publishMessage}" th:object="${messageBody}" method="post">
...
</form>
Now you're able to use it in your controller method via annotation in the parameters:
#PostMapping("/publishMessage")
public String publishMessage(#ModelAttribute(value="messageBody") String messageBody, BindingResult bindingResult, Model model) {
...
return messageBody;
}
You could do this with the whole message instead of the body, of course.
Based on the above input from SHEIX made some changes and it worked.
ShowFormController.java
#Controller
public class ShowFormController {
#RequestMapping(value = "/showForm", method = RequestMethod.GET)
public String showForm(Model model) {
model.addAttribute("message", new Message());
return "show";
}
}
show.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h3>
Go Back
</h3>
<form action="#" th:action="#{/publishMessage}" th:object="${message}" method="post">
<table>
<tr>
<th>CHARGE</th>
</tr>
<tr>
<td>
<textarea th:field="*{messageBody}" name="" cols="90" rows="40" style="background-color: beige">
</textarea>
</td>
</tr>
<tr>
<td><input type="submit" name="btnSubmit" value="Publish CHARGE message"></td>
</tr>
</table>
</form>
</body>
</html>
Message.java
import lombok.*;
#Data
#Getter
#Setter
#NoArgsConstructor
public class Message {
private String messageBody = "{\n" +
"\t\t\t\t\t\t\"name\": \"John\"\n" +
" }";
}
PublishMessageController.java
#PostMapping("/publishMessage")
public String publishMessage(#ModelAttribute(value = "messageBody") String messageBody, BindingResult bindingResult, Model model) {
System.out.println("into the publishMessage method..........");
System.out.println("messageBody: " + messageBody);
return "result";
result.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h3>
Thanks !!!
Go Back
</h3>
</body>
</html>

Spring MVC-Response is not getting from controller using angular

I am implementing simple CRUD Operation using spring restful webservices and angular js.I trying to load all the details when the page is loading.But its not getting any response.
Controller :-
#RestController
public class EmployeeController {
public List<Employee> appList=new ArrayList<Employee>();
#RequestMapping(value="/employee",method=RequestMethod.GET)
public ModelAndView loadEmployee(){
return new ModelAndView("employee", "webemployee", new Employee());
}
#RequestMapping(value="/employees",method = RequestMethod.GET,headers="Accept=application/json")
public List<Employee>loadAllApps() {
Employee app=new Employee();
System.out.println(".........................loadAllApps.............");
app.setAppID("test_id");
app.setAppName("test_name");
appList.add(app);
return appList;
}
#RequestMapping(value="/employees/insert/{appID}/{appDescr}",method = RequestMethod.POST,headers="Accept=application/json")
public List<Employee> addApps(#PathVariable String appID,#PathVariable String appDescr) throws ParseException {
System.out.println("appID"+appID+"appDescr..........."+appDescr);
Employee app=new Employee();
app.setAppID(appID);
app.setAppName(appDescr);
appList.add(app);
return appList;
}
}
Jsp :-
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html ng-app="AppManger">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>WebService Example</title>
<script data-require="angular.js#*" data-semver="1.2.13" src="http://code.angularjs.org/1.2.13/angular.js"></script>
</head>
<div ng-controller="appController">
<div>
<table>
<tr ng-repeat="app in appList">
<td >{{ app.appID }}</td>
<td >{{ app.appName }}</td>
</tr>
</table>
</div>
<script type="text/javascript">
var appModule = angular.module('AppManger', []);
appModule.controller('appController', function ($scope,$http) {
var url="http://localhost:8080/Apps";
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
$http.get(url+'/employee').
success(function(data, status, headers, config) {
alert(status);
$scope.appList = data;
});
});
</script>
</script>
</html>
when i am trying to checking status value in $http.get method.its not showing any alert message.Please let me know what issues here.
You seem to call your /employee endpoint but expecting a list of employees , because you assigning data response to the:
$scope.appList = data;
First, change that to the other endpoint you created (/employees) which returns the list.
What is the servlet-path of your mvc dispatcher servlet? This would be my first point of failure to check for. I see that you call:
var url="http://localhost:8080/Apps";
Does that mean that you deploy your app in context 'Apps' or is that your servlet path? If this is the context name then I assume that mvc is resolved to the 'root' path i.e. '/'. If not, check what is servlet path for the dispatcher and add that to your url (on the client side). This would explain why you get 404.
And also, check that you can call your API directly in the browser to rule out the server-side errors as user Chandermani suggested.

How do you query a database from JSP Form Data?

I am in need of assistance. I am trying to write a basic form that populates a drop-down list and based on what you select, it queries the database. However, I cannot get it to do it, It just receives all the queries. I am at a loss so if you have any helpful advice or helpful links, that'd be great. I really need to learn Spring MVC, and Hibernate combined. thanks!
HomeController Code: (This controller populates the list)
/**
* Handles requests for the application home page.
*/
#Controller
public class SearchController {
#Autowired
FilmBo filmBo;
/**
* Simply selects the home view to render by returning its name.
*/
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, ModelMap model) {
Selection selection = new Selection();
model.addAttribute("selection", selection);
return "search";
}
#ModelAttribute("categoryList")
public List<String> populateList(){
List<String> categoryList = filmBo.searchByCategory("");
return categoryList;
}
}
Here is the MainController that the form upon submit gets sent to:
public class FilmController {
private static final Logger logger = LoggerFactory.getLogger(SearchController.class);
#Autowired
FilmBo filmBo;
#RequestMapping(value = "/films", method = RequestMethod.GET)
public String home(Locale locale, Model model, #RequestParam(value="title",required=false) String title,
#RequestParam(value="category",required=false) String category) {
logger.info("Welcome home! The client locale is {}.", locale);
List<Film> filmList = filmBo.searchByTitle(title);
logger.info("filmList: " + filmList);
model.addAttribute("filmList", filmList);
List<String> filmCategory = filmBo.searchByCategory(category);
logger.info("filmCategory: " + filmCategory);
model.addAttribute("filmCategory",filmCategory);
return "films";
}
}
Here is my jsp page:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# page session="false"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<div class="form">
<form:form action="${pageContext.request.contextPath}/films"
method="GET" commandName="selection">
Film Title<input type="text" name="title">
<br>
Select a Film Category:<br>
<form:select path="selection">
<form:option value="NONE" label="--- Select ---" />
<form:options name="category" items="${categoryList}" />
</form:select>
<button name="submit" type="submit">Submit Name</button>
</form:form>
</div>
</body>
</html>

Categories

Resources