My current controller is returning to an HTML page. I want to send some data (a DTO) which can be received at front end, like an ajax response (like it happens in ajax + RestController). But this is not a RestController, it is a normal #controller returning HTML. I don't know even if it is possible to send DTO with html. There isn't much code to look at. I am just looking for feasibility. Do let me know if additional info is required. Thanks
Edit
Here is some code for reference. login.html is the page I am returning to. I want to send some additional info with this return ( in the form of a DTO ).
#Controller
public class LoginUserController {
#RequestMapping(value = {"/loginuser", "/loginuser?error"})
public String login() {
return "/login";
}
}
If you want to return view only i.e jsp in your case . You could put DTO object in modelMap and used inside jsp . Or simply if you want to return JSON only you could use #ResponseBody .
#RequestMapping(value = {"/loginuser", "/loginuser?error"})
public String login(ModelMap model) {
YourDTO dtoObject = // get DTO;
model.put("dtoObject",dtoObject)
return "/login";
}
class YourDTO {
private int id;
private String name;
// getters setters
}
Inside login JSP you can usedtoObject .
Name <c:out value="${dtoObject.name}" ></c:out> // Using JSTL
Or In Html file
<input type="text" id="name" value='${dtoObject.name}'/>
Seems like you're trying to build a spring boot web app, here is the bare minimum what you need to do:
Make sure your maven dependencies have spring-boot-starter-thymeleaf along with spring-boot-starter-webapp in the pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Configure/write your controller like this :
#Controller
public class LoginUserController {
#GetMapping(value = {"/loginuser", "/loginuser?error"})
public String login( Model model) {
model.addAttribute("message", "Aww snaps! something went wrong...");
return "login";
}
}
Ensure you have src/main/resources/templates/login.html which may look like this:
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Login Page</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="${message}" />
</body>
</html>
You can use any other viewing technology of your choice instead of Thymeleaf. Basically the viewing technology parses the HTML template, looks for expressions like
th:text
to reslove the value of
${message}
with the data that you've put in the model in Controller.
Hope this helps!
you can use following code
#Controller
public class LoginUserController {
#GetMapping(value = {"/loginuser", "/loginuser?error"})
public String login( Model model) {
organizationDTO = organizationService.getOrganizationDTO(id);
model.addAttribute("organizationDTO", organizationDTO);
return "/login";
}
}
and use below code in HTML page using JSTL
<div class="row">
<p class="col-md-4">${organizationDTO."your value"}</p>
</div>
eg below
<div class="row">
<label class="col-md-2">Id</label>
<p class="col-md-4">${organizationDTO.id}</p>
<label class="col-md-2">Name</label>
<p class="col-md-4">${organizationDTO.name}</p>
</div>
Related
I've created a project with a Spring Initilizr. I'm trying to parse a string into a "code.html" file and recover it with a #GetMapping. Here's the file:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Code</title>
</head>
<body>
<pre>
<p th:text="${code}">
</pre>
</body>
</html>
And here's the method:
#GetMapping("/code")
public ModelAndView getHTML(HttpServletResponse response) {
response.addHeader("Content-Type", "text/html");
ModelAndView model = new ModelAndView();
model.addObject("code", code.getCode());
model.setViewName("code.html");
return model;
}
(I have a seperate class for the code so code.getCode() just returns a string.)
Unfortunately, http://localhost:8080/code returns an empty screen. What am I doing wrong? Maybe there's an easier way to achieve the task?
i work with springboot and thymeleaft
maybe you need send only the view in the code
like this
#GetMapping("/code")
public ModelAndView getHTML(HttpServletResponse response,Model model) {
model.addAtributte("key", "code");
return new ModelAndView ("templates/code");
}
the model is shipped with the view
in the html try this
<p th:text="${key}">
or you can try the <th:block>
check thymeleaf documentation
I'm trying to handle a form submission with thymeleaf in my spring-boot application, i integrated
this example which worked fine on my app. I'm trying to change it a little bit, but this is what i'm getting as an exception:
org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'recruiter' cannot be found on null
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:213) ~[spring-expression-5.2.3.RELEASE.jar:5.2.3.RELEASE]
...
This is the object i'm trying to handle with thymeleaf
public class FormRec {
private String recruiter;
public String getRecruiter() {
return recruiter;
}
public void setRecruiter(String recruiter) {
this.recruiter = recruiter;
}
}
This is my Controller
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import com.service.minimicroservice.objects.FormRec;
#Controller
public class MyController {
#GetMapping("/form")
public String greetingForm(Model model) {
model.addAttribute("recForm", new FormRec());
return "form";
}
#PostMapping("/form")
public String greetingSubmit(#ModelAttribute FormRec rec) {
return "result";
}
}
result.html
<!DOCTYPE HTML>
<html xmlns:th="https://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="'Recruiter: ' + ${rec.recruiter}" />
Submit another message
</body>
</html>
part of the form.html
<body>
<form action="#" th:action="#{/form}" th:object="${recForm}" method="post">
<div class="form-row m-b-55">
<div class="name">Recruiter<br> Name</div>
<div class="value">
<div class="row row-space">
<div class="col-2">
<div class="input-group-desc">
<input class="input--style-5" type="text" name="first_name" th:field="*{recruiter}">
<label class="label--desc">Full Name</label>
</div>
</div>
...
In order to refer to a FormRec Object i use recForm as th:object in the form.html and rec to refer to it in the result.html.
Note: I pass a value to the th:field="*{recruiter}" input text when i submit the form (is not null)
You have to name the ModelAttribute rec that the data gets bound to. So in your controller method do this (notice the name = "rec"):
public String greetingSubmit(#ModelAttribute(name = "rec") FormRec rec) {
...
}
It should work.
Additional explanation:
I've had a closer look at why that happens and it's because Spring's ModelAttribute annotation by default infers from the name of the type and not the name of the parameter (the example link you provided says it's method parameter name, but it seems to be wrong).
So in this case Spring sends formRec (notice the camelCase, which it expects when the class name is called FormRec) to the result.html and not rec as you would expect.
If my explanation doesn't really make sense, then this is the Spring documentation on ModelAttribute:
The default model attribute name is inferred from the declared attribute type (i.e. the method parameter type or method return type), based on the non-qualified class name: e.g. "orderAddress" for class "mypackage.OrderAddress", or "orderAddressList" for "List".
I am facing this issue while trying to redirect a user from a login page (Spring) to a url that contains special german letters (ä, ö, ü, ß). This is likely not limited to them, but these are important at the moment.
The workflow looks like this:
User goes to a login page with a redirectUrl request param, for example: http://www.example.com/login.do?redirectUrl=http%3A%2F%2Fwww.example.com%2F%25C3%25B6l%2F, where %25C3%25B6l translates to öl
After logging in successfully, the user should be redirected to http://www.example.com/öl/. However, the actual URL is http://www.example.com/�l/, for some strange reason.
Looking at the URL Redirect trace, seems like (Spring?) encodes the ö to %F6 (Unicode?) instead of %C3%B6 (UTF-8).
The spring container (Tomcat) is all set to have UTF-8 encodings.
I have also tried encoding and decoding the URL to and from ISO-8859-1 and UTF-8, but without luck.
What I have also tried and seemed to work was to manually convert the special letters to their UTF-8 encoding (e.g. string.replace("ö", "%C3%B6");" and pass the url in that form. However, this is ugly and I would prefer not to do that.
Any suggestions on how to properly handle this?
Thanks.
Assumed you are in context of a Spring MVC application, redirects can be implemented using RedirectView or simply with the prefix redirect: as return value of a controller method. Catch it as RequestParam during form initialization and keep it in the session as shown in the following example:
Model:
public class LoginForm implements Serializable {
private String username;
private String password;
private String redirectUrl;
// getters and setters omitted
}
View:
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<form:form method="POST" modelAttribute="loginForm" acceptCharset="UTF-8" action="login/doLogin">
<table>
<tr>
<td><form:label path="username">User Name</form:label></td>
<td><form:input path="username"/></td>
</tr>
<tr>
<td><form:label path="password">Password</form:label></td>
<td><form:password path="password"/></td>
</tr>
</table>
<div>
<input type="submit" value="Submit"/>
</div>
</form:form>
</body>
</html>
Controller:
#Controller
#RequestMapping("login")
#SessionAttributes(LoginController.FORM_NAME)
public class LoginController {
static final String FORM_NAME = "loginForm";
private static final String DEFAULT_REDIRECT_URL = "https://google.com";
#ModelAttribute(FORM_NAME)
public LoginForm createForm() {
return new LoginForm();
}
#GetMapping
public String showForm(Model model, #ModelAttribute(FORM_NAME) LoginForm loginForm, #RequestParam(required = false) String redirectUrl) {
loginForm.setRedirectUrl(redirectUrl);
model.addAttribute(FORM_NAME, loginForm);
return "login/login-form";
}
#PostMapping("/doLogin")
public String processFormCredentials(LoginForm loginForm) {
// input validation omitted ...
return "redirect:" + (loginForm.getRedirectUrl() != null ? loginForm.getRedirectUrl() : DEFAULT_REDIRECT_URL);
}
}
Using this code, the redirect with umlauts works fine on Tomcat - http://<url>/login?redirectUrl=http%3A%2F%2Fwww.example.com%2F%25C3%25B6l%2F redirects on form submission to http://www.example.com/öl/.
I am using SpringBoot with Thymeleaf to build a trivial example to help me learn the two technologies.
I am basing my example on THIS GUIDE
The entity is a Greeting which has an Id and a Content.
I create the Greeting just fine, and I can list all the Greetings I've created.
I then wanted to add a delete option against each Greeting in the list page. When clicking delete, I want the object to be deleted and the list page served up again.
Alas, when I load the list page I get this error:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'greeting' available as request attribute
Controller and respository objects
#Controller
public class GreetingController {
#Autowired
GreetingRepo gr;
#RequestMapping(value="/greeting/list", method=RequestMethod.GET)
public String greetingsForm(Model model) {
model.addAttribute("greetings", gr.findAll());
return "greeting/list";
}
#RequestMapping(value="/greeting/delete", method=RequestMethod.POST)
public String deleteGreeting(#ModelAttribute("greeting") Greeting greeting) {
gr.delete(greeting);
return "redirect:/greeting/list";
}
}
#RepositoryRestResource
interface GreetingRepo extends JpaRepository<Greeting, Long> {
}
List.html page:
<!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>
<div th:each="greeting : ${greetings}">
<p th:text="'id: ' + ${greeting.id}" />
<p th:text="'content: ' + ${greeting.content}" />
<form action="#" th:action="#{/greeting/delete}" th:object="${greeting}" method="post">
<input type="hidden" th:field="*{id}"/>
<input type="hidden" th:field="*{content}"/>
<input type="Submit" value="Delete"/>
</form>
</div>
Add another
Show All
</body>
</html>
Would appreciate a push in the right direction here :-)
I think you miss this line .
model.addAttribute("greeting", new Greeting());
#RequestMapping(value="/greeting/list", method=RequestMethod.GET)
public String greetingsForm(Model model) {
model.addAttribute("greeting", new Greeting());
model.addAttribute("greetings", gr.findAll());
return "greeting/list";
}
you dont have to use a form to delete the greeting you can do it very easily with this approach. hide the id of the greeting within the url. so you dont need to use a form and hidden tags. and annotate the controller method with following approach, to accept incoming id of the greeting.
replace the current form with given html code and replace the delete method in the controller as well.
<a th:href="#{/greeting/{id}/delete(id=${greeting.id})}" th:text="delete"></a>
#RequestMapping(value="/greeting/{id}/delete",method=RequestMethod.GET)
public String deleteGreeting(#PathVariable int id) {
gr.delete(id);
return "redirect:/greeting/list";
}
edit:- since you need the object to be present within the controller
you can use findOne method to fetch the object from the given id.check out the following example.
<a th:href="#{/greeting/{id}/edit(id=${greeting.id})}" th:text="edit"></a>
#RequestMapping(value="/greeting/{id}/edit",method=RequestMethod.GET)
public String Edit(#PathVariable int id){
greeting greetingob = gr.findOne(id);
return "edit";
}
hi i have a problem i am learnig how to pass values with PathVariable, i have a form with a input text and a button when you press the buttom it takes you to other page and show the value but it dont work when i press the buttom it takes me to this URL:
http://localhost:8080/appThyme/shoForm1.html?firstname=MyName&submit=
and i get this error HTTP 404 - /appThyme/showForm1.html
but if i put this URL: http://localhost:8080/appThyme/respuesta/Myname it works it shows me my page with my name, how can i make that work with only pressing the buttom, why when i press the buttom it add question marks and equals symbols to my URI
#Controller
public class HomeController {
#RequestMapping(value = "/form1", method = RequestMethod.GET)
public String showFormulario2(Model model) {
logger.info("***PAG formulario***");
return "form1.html";
}
#RequestMapping(value = "/showForm1/{id}", method = RequestMethod.GET)
public String showForm(Model model, #PathVariable("id") String id)
{
String theId= id;
model.addAttribute("TheID", theId);
return "showForm1.html";
}
my form1.html page
<form id="guestForm" th:action="#{/showForm1.html}" method="get">
<div>
<input type="text" name="firstname" id="firstname"></input>
</div>
<div>
<button type="submit" name="submit">Submit</button>
</div>
</form>
my showForm1.html page
enter code here
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>
Hello world!
</h1>
<P> The value is ${nombre} </P>
</body>
</html>
Form submissions are not intended to work with the #PathVariable construct you are using here. #PathVariable is intended for use with REST-style URI's, and that is not what is generated on a form submit.
If you change your controller signature to look like this:
#RequestMapping("/showForm1.html", method = RequestMethod.GET)
public String showForm(Model model, #RequestParam("firstname") String id)
{
String theId= id;
model.addAttribute("TheID", theId);
return "showForm1.html";
}
then the method should be called correctly on form submission.