I am working on Java Spring project, and I have this code that allows me to edit specific Quote based on it's Id.
//Quote's details
#GetMapping("/profile/{id}")
public String blogDetailsId(#PathVariable(value="id") long id, Model model){
if(!quoteRepository.existsById(id)){
return "redirect:/profile";
}
Optional<Quote> post = quoteRepository.findById(id);
ArrayList<Quote> res = new ArrayList<>();
post.ifPresent(res::add);
model.addAttribute("post", res);
return "detail_quote";
}
#GetMapping("/profile/{id}/edit")
public String QuoteDetails(#PathVariable(value="id") long id, Model model) {
if(!quoteRepository.existsById(id)){
return "redirect:/profile";
}
Optional<Quote> post = quoteRepository.findById(id);
ArrayList<Quote> res = new ArrayList<>();
post.ifPresent(res::add);
model.addAttribute("post", res);
return "edit_quote";
}
//Save changes into database
#PostMapping("/profile/{id}/edit")
public String QuoteEdit(#PathVariable(value="id") long id, #RequestParam String quote, #RequestParam String author, #RequestParam int votes, Model model) {
Quote post = quoteRepository.findById(id).orElseThrow(); //orElseThrow is used to throw exception when ID is not found.
post.setAuthor(author);
post.setQuote(quote);
post.setVotes(votes);
quoteRepository.save(post);
return "redirect:/profile";
}
Model code:
#Entity
public class Quote {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id; //Generate unique ID for every quote automatically.
private String quote, author;
private int votes;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getQuote() {
return quote;
}
public void setQuote(String quote) {
this.quote = quote;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public int getVotes() {
return votes;
}
public void setVotes(int votes) {
this.votes = votes;
}
public Quote() {}
public Quote(String quote, String author, int votes){
this.author = author;
this.quote = quote;
this.votes = votes;
}
}
This works as expected, and I am able to change the details of any Quote. But when I try to change specifically number of Votes by pressing upvote button - it results in following error:
There was an unexpected error (type=Bad Request, status=400).
Required parameter 'votes' is not present.
org.springframework.web.bind.MissingServletRequestParameterException: Required request parameter 'votes' for method parameter type int is not present
The code for Voting:
#PostMapping("/profile/{id}/upvote")
#ResponseBody
public String VoteUp(#PathVariable(value="id") long id, #RequestParam int votes, Model model) {
Quote post = quoteRepository.findById(id).orElseThrow();
post.setVotes(votes+1);
quoteRepository.save(post);
return "redirect:/profile";
}
The Button for Upvoting is stored inside 'detail_quote.html', which is functioning well, except for upvote button:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Quote's Details</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" crossorigin="anonymous">
<body>
<header th:insert="blocks/header :: header"></header>
<div class = "container mt-5">
<div th:each="el : ${post}" class="alert alert-info mt-2">
<h3 th:text="${el.quote}"></h3>
<p th:text="${el.author}"></p>
<p><b>Votes: </b><span th:text="${el.votes}"></span></p>
<a th:href="'/profile/' + ${el.id} + '/edit'" class="btn btn-warning">Edit</a><br>
<form th:action="'/profile/' + ${el.id} + '/upvote'" method="post"><br>
<button class="btn btn-warning" type="submit">Upvote</button><br>
</form>
<form th:action="'/profile/' + ${el.id} + '/downvote'" method="post">
<button class="btn btn-warning" type="submit">Downvote</button>
</form>
<form th:action="'/profile/' + ${el.id} + '/remove'" method="post"><br>
<button class="btn btn-warning" type="submit">Remove Quote</button><br>
</form>
</div>
</div>
<div th:insert="blocks/footer :: footer"></div>
</body>
</html>
So if anyone can explain to me why does it work when I change everything and does not work when I'm just trying to increase votes by 1 - I will be very thankful.
According to your code sample i could not see the args votes defined in your thymeleaf template as post request , but it is truely defined in backEnd Application
#PostMapping("/profile/{id}/upvote")
#ResponseBody
public String VoteUp(#PathVariable(value="id") long id, #RequestParam int votes, Model model) {
Quote post = quoteRepository.findById(id).orElseThrow();
post.setVotes(votes+1);
quoteRepository.save(post);
return "redirect:/profile";
}
so that if you do a post request to url "/profile/{id}/upvote" and have no args with votes you will get error log
There was an unexpected error (type=Bad Request, status=400). Required parameter 'votes' is not present.
as suggestion ,i advice build the api as below sample
#PostMapping("/profile/{id}/upvote")
#ResponseBody
public String VoteUp(#PathVariable(value="id") long id, #RequestParam(required = false) Integer votes, Model model) {
Quote post = quoteRepository.findById(id).orElseThrow();
votes == null ? post.getVotes():votes;
post.setVotes(votes+1);
quoteRepository.save(post);
return "redirect:/profile";
}
Related
Description of the problem
Spring boot cannot find the data sent in request body.
As specified below, in code extracts, I send form with application/x-www-form-urlencoded content-type to the endpoint POST /cards.
The good method is called by Spring boot but data from the request body aren't loaded in card entity, which is passed as parameter (see console output below).
Versions:
Spring boot: 2.3.4.RELEASE
spring-boot-starter-freemarker: 2.3.4.RELEASE
Console output (with request body read manually in request filter):
2020-10-21 00:26:58.594 DEBUG 38768 --- [nio-8080-exec-1] c.b.c.c.f.RequestResponseLoggingFilter : New request method=POST path=/cards content-type=application/x-www-form-urlencoded
2020-10-21 00:26:58.595 DEBUG 38768 --- [nio-8080-exec-1] c.b.c.c.f.RequestResponseLoggingFilter : RequestBody: title=First+card&seoCode=first-card&description=This+is+the+first+card+of+the+blog&content=I+think+I+need+help+about+this+one...
### createNewCard ###
card: Card<com.brunierterry.cards.models.Card#34e63b41>{id=null, seoCode='null', publishedDate=null, title='null', description='null', content='null'}
result: org.springframework.validation.BeanPropertyBindingResult: 0 errors
model: {card=Card<com.brunierterry.cards.models.Card#34e63b41>{id=null, seoCode='null', publishedDate=null, title='null', description='null', content='null'}, org.springframework.validation.BindingResult.card=org.springframework.validation.BeanPropertyBindingResult: 0 errors}
2020-10-21 00:26:58.790 TRACE 38768 --- [nio-8080-exec-1] c.b.c.c.f.RequestResponseLoggingFilter : Response to request method=POST path=/cards status=200 elapsedTime=196ms
(Here I read body with req.getReader(), but I comment it usually to not consume the buffer.)
Controller
#Controller
public class CardController implements ControllerHelper {
#PostMapping(value = "/cards", consumes = MediaType.ALL_VALUE)
public String createNewCard(
#ModelAttribute Card card,
BindingResult result,
ModelMap model
) {
System.out.println("\n### createNewCard ###\n");
System.out.println("card: "+card);
System.out.println("result: "+result);
System.out.println("model: "+model);
return "/cards/editor";
}
#GetMapping(value = "/cards/form")
public String newPost(
Model model
) {
model.addAttribute("card", Card.defaultEmptyCard);
return "/cards/editor";
}
}
HTML form (wrote with freemarker template):
<form action="/cards"
method="POST"
modelAttribute="card"
enctype="application/x-www-form-urlencoded"
>
<div class="form-group">
<label for="title">Title & SEO slug code</label>
<div class="form-row">
<div class="col-9">
<#spring.formInput
"card.title"
"class='form-control' placeholder='Title'"
/>
<#spring.showErrors "<br>"/>
</div>
<div class="col-2">
<#spring.formInput
"card.seoCode"
"class='form-control' placeholder='SEO slug code' aria-describedby='seoCodeHelp'"
/>
<#spring.showErrors "<br>"/>
</div>
<div class="col-1">
<#spring.formInput
"card.id"
"DISABLED class='form-control' placeholder='ID'"
/>
</div>
</div>
<div class="form-row">
<small id="seoCodeHelp" class="form-text text-muted">
Keep SEO slug very small and remove useless words.
</small>
</div>
</div>
<div class="form-group">
<label for="description">Description</label>
<#spring.formInput
"card.description"
"class='form-control' placeholder='Short description of this card..' aria-describedby='descriptionHelp'"
/>
<small id="descriptionHelp" class="form-text text-muted">
Keep this description as small as possible.
</small>
</div>
<div class="form-group">
<label for="content">Content</label>
<#spring.formTextarea
"card.content"
"class='form-control' rows='5'"
/>
</div>
<button type="submit" class="btn btn-primary">Save</button>
</form>
Card entity
#Entity
public class Card implements Comparable<Card> {
protected Card() {}
public static final Card defaultEmptyCard = new Card();
private final static Logger logger = LoggerFactory.getLogger(Card.class);
#Autowired
private ObjectMapper objectMapper;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#NotBlank(message = "Value for seoCode (the slug) is mandatory")
#Column(unique=true)
private String seoCode;
#JsonDeserialize(using = LocalDateDeserializer.class)
#JsonSerialize(using = LocalDateSerializer.class)
private LocalDate publishedDate;
#NotBlank(message = "Value for title is mandatory")
private String title;
#NotBlank(message = "Value for description is mandatory")
private String description;
#NotBlank(message = "Value for content is mandatory")
private String content;
public boolean hasIdUndefine() {
return null == id;
}
public boolean hasIdDefined() {
return null != id;
}
public Long getId() {
return id;
}
public String getSeoCode() {
return seoCode;
}
public LocalDate getPublishedDate() {
return publishedDate;
}
public String getTitle() {
return title;
}
public String getDescription() {
return description;
}
public String getContent() {
return content;
}
private String formatSeoCode(String candidateSeoCode) {
return candidateSeoCode.replaceAll("[^0-9a-zA-Z_-]","");
}
private Card(
#NonNull String rawSeoCode,
#NonNull String title,
#NonNull String description,
#NonNull String content,
#NonNull LocalDate publishedDate
) {
this.seoCode = formatSeoCode(rawSeoCode);
this.title = title;
this.description = description;
this.content = content;
this.publishedDate = publishedDate;
}
public static Card createCard(
#NonNull String seoCode,
#NonNull String title,
#NonNull String description,
#NonNull String content,
#NonNull LocalDate publishedDate
) {
return new Card(
seoCode,
title,
description,
content,
publishedDate
);
}
public static Card createCard(
#NonNull String seoCode,
#NonNull String title,
#NonNull String description,
#NonNull String content
) {
LocalDate publishedDate = LocalDate.now();
return new Card(
seoCode,
title,
description,
content,
publishedDate
);
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Card card = (Card) o;
return Objects.equals(id, card.id) &&
seoCode.equals(card.seoCode) &&
publishedDate.equals(card.publishedDate) &&
title.equals(card.title) &&
description.equals(card.description) &&
content.equals(card.content);
}
#Override
public int hashCode() {
return Objects.hash(id, seoCode, publishedDate, title, description, content);
}
#Override
public String toString() {
return "Card<"+ super.toString() +">{" +
"id=" + id +
", seoCode='" + seoCode + '\'' +
", publishedDate=" + publishedDate +
", title='" + title + '\'' +
", description='" + description + '\'' +
", content='" + content + '\'' +
'}';
}
public Either<JsonProcessingException,String> safeJsonSerialize(
ObjectMapper objectMapper
) {
try {
return Right(objectMapper.writeValueAsString(this));
} catch (JsonProcessingException e) {
logger.error(e.getMessage());
return Left(e);
}
}
public Either<JsonProcessingException,String> safeJsonSerialize() {
try {
return Right(objectMapper.writeValueAsString(this));
} catch (JsonProcessingException e) {
logger.error(e.getMessage());
return Left(e);
}
}
#Override
public int compareTo(#NotNull Card o) {
int publicationOrder = this.publishedDate.compareTo(o.publishedDate);
int defaultOrder = this.seoCode.compareTo(o.seoCode);
return publicationOrder == 0 ? defaultOrder : publicationOrder;
}
}
Edit
I got a good answer.
It works when adding empty constructor and setters to the Card entity.
However, it's not the class I want.
I want card to be only instantiated with a constructor that have all parameters.
Do you have an idea about how to achieve that ?
Should I create another class to represent the form ?
Oris there a way to only allow Spring to use such setters ?
Did you make sure that you Card.java has the appropriate getters and setters? This way spring can actually populate the data in the object it is trying to create.
I want to replace some web page elements throught using parametrized fragments with ThymeLeaf + Spring Boot.
public class Admin {
private Integer id;
public Admin(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Override
public String toString() {
return "Admin{" +
"id=" + id +
'}';
}
}
#Controller
public class AdminController {
#GetMapping("/admin-reload")
public String reloadElementDiv(Model model) {
Admin adminObj = new Admin(3);
model.addAttribute("adminObj", adminObj);
model.addAttribute("id", adminObj.getId());
return "/fragments/adminForm";
}
}
resources/templates/fragments/adminForm.html
<div th:fragment="admin_form(adminObj, id)" >
<form th:object="${adminObj}">
<p th:text="${id}"></p>
</form>
</div>
resources/templates/index.html
<div th:fragment="admin_form(adminObj, id)">
</div>
one way:
<div th:replace="fragments/adminForm :: admin_form(adminObj, id)" th:with="adminObj='${adminObj}', id='${id}'">
<p th:text="${id}"></p>
</div>
or
another way:
<div th:replace="fragments/adminForm :: admin_form(adminObj, id)">
<p th:text="${id}"></p>
</div>
So, as a result I just have got only 'id' parameter on my index.html web page, but not its value id = 3, as I set in the controller class. Can anybody help me to get the value I need?
I write simple app that let us writing, updating and removing posts. So far I can write and update, but my delete command seems to not work. Here is my jsp code:
<table>
<tr>
<th>Number</th>
<th>Title</th>
<th>Author</th>
<th></th>
</tr>
<c:forEach var="post" items="${listOfPosts}">
<tr>
<td>${post.id}</td>
<td>${post.title}</td>
<td>${post.author}</td>
<td>
<a href="<c:url value="/editPost/${post.id}" />" >Edit</a>
<form:form action="deletePost" method="post" commandName="deletedBlogpost">
<input type="submit" value="Delete post">
</form:form>
</td>
</tr>
</c:forEach>
</table>
and my controller methods, where I tried to implement Post-Redirect-Get Pattern:
#RequestMapping(value = "deletePost", method = RequestMethod.POST)
public String deletePostPOST (#ModelAttribute("deletedBlogpost") BlogPost blogpost, BindingResult bindingResult, RedirectAttributes ra) {
if (bindingResult.hasErrors()) {
return ERROR_PAGE_VIEW;
}
repo.delete(blogpost);
ra.addFlashAttribute("blogpost", blogpost);
return "redirect:/delete-success";
}
#RequestMapping(value = "delete-success", method = RequestMethod.GET)
public String deletePostGET(#ModelAttribute("deletedBlogpost") BlogPost blogpost, Model model){
model.addAttribute(M_LIST_OF_POSTS, repo.findAll());
return RESULT_PAGE_VIEW;
}
I guess it has to be something with jsp form, because my code isn't even reaching controller's code. Any help will be appreciated, 'casue I'm still a beginner here and I am still struggling with basics.
EDIT here is my entity BlogPost
#Entity
#Table(name="posts")
public class BlogPost {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(name="post_title")
private String title;
#Column(name="post_content")
private String content;
#Column(name="post_author", nullable = false)
private String author;
public BlogPost(){}
public BlogPost(String title, String content, String author) {
this.title = title;
this.content = content;
this.author = author;
}
public long getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String toString(){
return "ID: "+getId()+", tytul: "+getTitle()+", tresc: "+getContent()+", autor: "+getAuthor()+"\n";
}
}
and my application.properties where I can establish a PostgreSQL connection:
#PostgreSQL
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/blogdatabase
spring.datasource.username=username
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
EDIT:
I tried to solve it by adding to jsp form
<input name="id" type="hidden" value="${post.id}"/>
and by adding to deletePostPost method
repo.delete(deletedBlogpost.getId());
Nothing has changed. Clicking button isn't calling any action.
Try
yourRepository.deleteById(id)
Good afternoon,
I am newbie to Spring MVC. I'm stuck with the following error while running my project "The request sent by the client was syntactically incorrect."
My project has two entities, Team and Country which have a ManyToOne relationship. Both these entities map tables created in mysql database.
I started the project with only the Team entity, and sucessfuly created my classes (DAO, controller, services, etc) and jsp to create new teams.
Now, I created the class Country to relate both entities and I added a dropdown list in the "add-team-form.jsp" to select the country of the new team. This page is correctly displayed (all countries appear in the dropdown list), however, when I click "submit" to create the new team, I get the error "The request sent by the client was syntactically incorrect."
Can you please help me to identify my error? I'm guessing it's in the "add-team-form.jsp".
1 - Entity Team:
#Entity
#Table(name="teams")
public class Team implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "name", length = 40, nullable = false)
private String name;
#Column(name = "rating", length = 6, nullable = false)
private Integer rating;
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "id_country", nullable = false)
private Country country;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getRating() {
return rating;
}
public void setRating(Integer rating) {
this.rating = rating;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
}
2 - Entity Country:
#Entity
#Table(name = "countries")
public class Country implements Serializable{
#Id
#Column(name= "id_country", length = 6)
private String idCountry;
#Column(name = "name", length = 255, nullable = false)
private String name;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "country")
private List<Team> teams;
public String getIdCountry() {
return idCountry;
}
public void setIdCountry(String idCountry) {
this.idCountry = idCountry;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
My Team DAO
#Repository
public class TeamDAOImpl implements TeamDAO {
#Autowired
private SessionFactory sessionFactory;
private Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
#Override
public void addTeam(Team team) {
getCurrentSession().save(team);
}
}
My Team Service
#Service
#Transactional
public class TeamServiceImpl implements TeamService {
#Autowired
private TeamDAO teamDAO;
public void addTeam(Team team) {
teamDAO.addTeam(team);
}
My Team Controller
#Controller
#RequestMapping(value="/team")
public class TeamController {
#Autowired
private TeamService teamService;
#Autowired
private FilterService filterService;
#RequestMapping(value="/add", method=RequestMethod.GET)
public ModelAndView addTeamPage() {
ModelAndView modelAndView = new ModelAndView("add-team-form");
modelAndView.addObject("team", new Team());
return modelAndView;
}
#RequestMapping(value="/add", method=RequestMethod.POST)
public ModelAndView addingTeam(#ModelAttribute Team team) {
ModelAndView modelAndView = new ModelAndView("home");
teamService.addTeam(team);
String message = "Team was successfully added.";
modelAndView.addObject("message", message);
return modelAndView;
}
#ModelAttribute("countryList")
public Map<String, String> getCountryList(){
Map<String, String> countryList = filterService.getCountries();
return countryList;
}
...
}
My "add-team-form.jsp"
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Add team page</title>
</head>
<body>
<h1>Add team page</h1>
<form:form method="POST"
modelAttribute="team"
action="${pageContext.request.contextPath}/team/add.html">
<table>
<tbody>
<tr>
<td>Name:</td>
<td><form:input path="name" /></td>
</tr>
<tr>
<td>Rating:</td>
<td><form:input path="rating" /></td>
</tr>
<tr>
<td><label>Country</label></td>
<td>
<form:select path="country.idCountry">
<form:options items="${countryList}" />
</form:select>
</td>
<tr>
<td><input type="submit" value="Add" /></td>
<td></td>
</tr>
</tbody>
</table>
</form:form>
</body>
</html>
There is no error showing in the console of eclipse, but here is the error im receiving from the browser:
HTTP Status 400 -
type Status report
message
description The request sent by the client was syntactically incorrect.
Apache Tomcat/7.0.47
There's a couple of problems I can see here - you are posting to add/team/add.html and not hitting your post handler. You don't need the action attribute as you're posting to the same endpoint;
<form:form method="POST" modelAttribute="team" >
Secondly your are injecting the countries as a map, so these are ID/display values which works great for key/value pairs and for binding a value to a string field. In this case, Spring is trying to bind your country ID (String) to the team.country(Country) field which will fail. To help Spring out you need a databinder; in your controller add;
#InitBinder
public void initBinder (WebDataBinder binder) {
binder.registerCustomEditor(Country.class, new CountryEditor());
}
and create the property editor class;
public class CountryEditor extends PropertyEditorSupport {
#Override
public void setValue(Object value) {
super.setValue(value);
}
public String getAsText() {
if (getValue() == null) return null;
return ((Country) getValue()).getName();
};
public void setAsText(String text) throws IllegalArgumentException {
if (text != null) {
Country country = // something like filterService.getCountryById(text);
setValue(country);
}
};
}
There's more information in the Spring documentation
The error you are receiving generally happens if a parameter is missing or is in a different format and cannot be converted to the expected type.Check the values being passed to the Team object.You can either log the request and response or set the log level to "DEBUG",this will display the exact error in logs.
I'm creating a web application using Spring MVC, but all my POST request result in "The request sent by the client was syntactically incorrect". As an example, this is a search form:
<form id="projectsForm" action="#" th:action="#{/projects}" th:object="${projectsForm}" method="post">
<input type="hidden" th:field="*{page}" />
<div id="search">
<select id="expert" th:field="*{expert}">
<option value="">(select expert)</option>
<option th:each="expert : ${experts}"
th:value="${expert.id}"
th:text="${expert.firstName + ' ' + expert.lastName}"></option>
</select>
<select id="company" th:field="*{company}">
<option value="">(select company)</option>
<option th:each="company : ${companies}"
th:value="${company.id}"
th:text="${company.name}"></option>
</select>
<input type="text" id="query" th:field="*{query}" />
<button class="search" onclick="firstPage()">Search</button>
<button class="empty" onclick="empty()">Erase</button>
</div>
The form object class looks like this:
public class ProjectsForm {
private Expert expert;
private Company company;
private String query;
private Integer page = 0;
private Integer pages;
public Expert getExpert() {
return expert;
}
public void setExpert(Expert expert) {
this.expert = expert;
}
public Integer getPage() {
return page;
}
public void setPage(Integer page) {
this.page = page;
}
public Integer getPages() {
return pages;
}
public void setPages(Integer pages) {
if (pages > 0 && page >= pages) {
page = pages - 1;
}
this.pages = pages;
}
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
}
And this is the controller method:
#RequestMapping(value="/projects", method=RequestMethod.POST)
public String projectsPost(#ModelAttribute("projectsForm") ProjectsForm projectsForm, ModelMap model) {
sessionBean.setProjectsForm(projectsForm);
Page<Project> projectPage = projectService.findAll(projectsForm.getPage(), ProjectController.PAGESIZE, projectsForm.getExpert(), projectsForm.getCompany(), projectsForm.getQuery());
List<Project> projects = projectPage.getContent();
model.addAttribute("projects", projects);
projectsForm.setPage(projectPage.getNumber());
projectsForm.setPages(projectPage.getTotalPages());
model.addAttribute("projectsForm", projectsForm);
return "projects";
}
Chrome tells me the form data look like this:
page=0&expert=&company=&query=
Is there an obvious error, or is there any way I can diagnose this problem? Adding log4j.logger.org.springframework.web=DEBUG to log4j.properties didn't give me any more information. What also puzzles me is that the exact same code worked fine in a Spring Boot jar application.