#RequestBody being set but not sure how - spring

So this is a super novice question. Im running this tutorial and in some of the methods like this:
#RequestMapping(value="/string", method=RequestMethod.POST)
public #ResponseBody String readString(#RequestBody String string) {
return "Read string '" + string + "'";
}
where there is a string as a requestbody, the string is foo but i don't know how it is set. Is there some method somewhere that sets a default or what (maybe i'm missing something super obvious). The html looks like this
<form id="readString" class="textForm" action="<c:url value="/messageconverters/string" />" method="post">
<input id="readStringSubmit" type="submit" value="Read a String" />
</form>
Thanks for any help you can provide.

As far as I understand the "#RequestBody String string" variable is being set by Spring when you submit your html form using the using post request method.

Related

Form input type DateTime using Thymeleaf + Spring MVC issue

I am struggling to use a Java LocalDateTime scheduledDateTime in a Thymeleaf form and getting it back to save it in the database. I get the following error message :
Bean property 'campaignExecution' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
It is really due to the datetime field. If I remove it from the html form everything works fine and I see the data from the object created in the controller.
My object contains the following along with the getter and setter returning thetype (LocalDateTime) :
#DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm")
private LocalDateTime scheduledDateTime;
My Controller initialize the value to now()
#RequestMapping({ "/campaign1"})
public String requestCampaign1(Model model) {
CampaignExecution ce = new CampaignExecution();
LocalDateTime localDateTime = LocalDateTime.now();
ce.setScheduledDateTime(localDateTime);
model.addAttribute("campaignExecution", ce);
And this is the form :
<form id="f" name="f" th:action="#{/campaign1}"
th:object="${campaignExecution}" method="post">
<div>
Schedule a date :
<input type="datetime-local" th:field=*{campaignExecution.scheduledDateTime} />
</div>
<hr>
<div>Parameters</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
Much easier than I was thinking. For th:field you cannot use multiple object but only the "form object". I was using the full qualifier : object name.property name.

Thymeleaf dynamic text

I'm using thymeleaf for email templates but text for these templates are from database.
It looks like this:
<html>
<header>
</header>
<body>
Hello <th:block th:text="${dbText}> </th:block>
</body>
</html>
so, property dbText is String from db.
Question: is it possible to somehow store thymeleaf dynamic property in dbText?
I mean, when I fetch dbText it's
"my friend <th:block th:text="${name}"></th:block>"
so when I try to replace name property in thymeleaf it doesn't replace my value instead of name but render this:
"my friend ${name}"
Ideally, you'd want to drop an object into your template via a model, and then access name as a property of that object.
In your controller:
#RequestMapping(value="/your-uri", method = RequestMethod.GET)
public String showName(Model model) {
User someUser = new User("First", "Last");
model.addAttribute("user", someUser);
}
Then in your view:
<p th:text="${user.firstName} + ' ' + ${user.lastName}></p>
This is assuming that your User class has the following:
private String firstName
private String lastName
// getters & setters
This would output:
<p>First Last</p>

Spring mvc: I cant map form action url to controller action

I apologize in advance if this or a similar question has already been asked, but I could not find a suitable answer.
I have a simple form like this in EditUser.jsp (mapped to: .../admin/users/edit/{userId}):
<form action="/admin/users/edit/addRole/${user.userId}" method="POST">
<select name="role">
<c:forEach var="role" items="${roles}">
<option value="${role}">${role}</option>
</c:forEach>
</select>
<button type="submit" value="AddRole">Add Role</button>
</form>
And #RequestMapping like this:
#RequestMapping(value = "/admin/users/edit/addRole/${userId}", method = RequestMethod.POST)
public String addUserRole(
Model model,
#RequestParam("role") String role,
#PathVariable(value="userId") long userId)
{
...
return "redirect:/admin/users/edit/${userId}";
}
The problem is the result of the request: HTTP Status 404 - /admin/users/edit/addRole/7- "The requested resource is not available" (7 is some user id). A cannot map the POST request to the controller action. I already tried with th:action but it redirects me to the previous page .../admin/users.
Any help pointers appreciated .
I think you url is wrong. As long as you do not deploy the application in the servlets container root path, it will not work because the url is missing the applications name. So a correct url would be something like:
<form action="myAppName/admin/users/edit/addRole/${user.userId}" method="POST">
But better would been using <c:url> or <spring:url>-tag this adds the application name to the url (if the given url starts with an /)
<form action="<c:url value="/admin/users/edit/addRole/${user.userId}" />" method="POST">
for some more information have a look at this two answers:
How to use relative paths without including the context root name? (the highes ranked answer of BalusC is for an quite old jsp version (<2.0)) so take the answer with the c:url tag
How to use with an tag?
I finally found the error - $ sign in #RequestMapping annotation. A just removŠµ $ from annotation and from return "...url" and that's all.

Spring MVC return object from JSP

I have a Spring MVC controller that sends a list to the view:
modelAndView.addObject("myList", List<foo>);
On the JSP, I iterate over this list creating a table where each row is a form with a submit button representing one foo instance. How can I get the single instance of foo represented by the row into the next controller? I tried putting it in an input type="hidden" but that didn't work.
A JSP is processed and rendered into HTML, which is just text.
When you submit a form, the browser takes the values of the <input> fields and serializes them in a specific format. With the typical application/x-www-form-urlencoded content type, the following <input> elements
<form action="/some/url" method="POST">
<input name="someField" value"someValue" type="text" />
<input name="someOtherField" value"someOtherValue" type="text" />
<input name="submit" value"submit" type="submit" />
</form>
The serialized format will look something like
someField=someValue&someOtherField=someOtherValue&submit=submit
Spring will take this String from the body of the request as request parameters and try to reconstruct your command object (ex. foo) from its values. The request above could be mapped to a class like
class Foo {
private String someField;
private String someOtherField;
public String getSomeField() {
return someField;
}
public void setSomeField(String someField) {
this.someField = someField;
}
public String getSomeOtherField() {
return someOtherField;
}
public void setSomeOtherField(String someOtherField) {
this.someOtherField = someOtherField;
}
}
Any fields it can't map, it ignores.

how to do binding in Spring annotated request parameter?

i have a controller that is using annotation for request mapping and requestParam.
the controller is working fine. However when submitting a command object with array, spring will crap out saying array index out of bound. i am guessing there is something wrong with binding but don't know how to fix it.
to be more specific, in eclipse i would set debugger at the beginning of the controller, and when submitting the form (by hitting a input submit button) eclipse debugger will not trigger and i will see array index out of bound error in console.
the controller is something like this:
#RequestMapping(value = {"/internal/pcsearch.dex", "/external/pcsearch.dex"},
method = {RequestMethod.POST, RequestMethod.GET})
public ModelAndView executeProductCatalogSearch(
HttpServletRequest request,
#RequestParam(value = "cat" ,required = false) String cat,
#RequestParam(value = "brand" ,required = false) String brand,
#ModelAttribute("command") ProductCatalogCommand cmd
){
[edit]
and the jsp is like:
<form name="pForm"
id="pForm"
action="<c:url value="psearch.dex"><c:param name="cat" value="${cat}"/></c:url>"
method="POST"
style="display:inline;">
...
...
<c:forEach var="model" items="${models}" varStatus="modelLinkStatus">
<script>
var modelImg<c:out value="${modelLinkStatus.index}"/>Src = '<c:out value="${model.altModelImage}"/>';
</script>
<spring:bind path="command.models[${modelLinkStatus.index}].modelSkusDisplayed">
<input type="hidden" name="<c:out value="${status.expression}"/>" id="<c:out value="${status.expression}"/>" value="<c:out value="${status.value}"/>"/>
</spring:bind>
<spring:bind path="command.updateCartButton">
<input type="submit" value="<spring:message code="orderEntryMessages.ecatalog.button.addToCart" text="Add to Cart" htmlEscape="yes" />" name="<c:out value="${status.expression}"/>" id="<c:out value="${status.expression}"/>" class="sub_buttons"/>
</spring:bind>
...
and the command object declare the model array as:
private List<ModelLink> models = new ArrayList<ModelLink>();
where modelLink is a custom ds.
the first foreach tag handle the the model command object and the 2nd part is the submit button i clicked on.
i think you should use AutoPopulatingList as models to bind list to view and controller. for example please refer link. This might resolve your problem of index.

Resources