I am using Spring mvc web to submit a form. Form is rendering fine however when I am submitting this form, I am getting http status code 400, however if I use 'edit and resend' function of firefox, it is hitting corresponding controller method (which doesn't happen when I submit this form from html). But again there is another issue, within that controller method when I inspect my modelAttribute object, I find everything in this object as null. Which is not the case as I am submitting values within this form.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ include file="include.jsp"%>
<!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>${message}</title>
</head>
<body>
General:
<br>
<form:form modelAttribute="initialMatchConfiguration" action="../match/configure" method="post" >
Date and time:
<form:input path="dateAndTimeOfMatch" type="text" />
<br> Match Type:
<form:select path="matchType">
<option value="friendly">friendly</option>
<option value="international">international</option>
<option value="domestic">domestic</option>
<option value="local">local tournament</option>
</form:select>
<br> Match Rules Configuration:
<form:select path="matchConfigurationId">
<option value="0">Random</option>
<option value="1">T20</option>
<option value="2">One Day</option>
<option value="3">Test</option>
</form:select>
<button type="button">Create a new rule configuration</button>
<br> Tournament:
<form:input type="text" path="tournament" />
<form:hidden path="tournamentId"/>
<button type="button">Create a new Tournament</button>
<br> Played at Stadium:
<form:input type="text" path="stadium" />
<form:hidden path="stadiumId"/>
<button type="button">Create a new stadium</button>
<br> <input type="submit" value="Save" />
</form:form>
</body>
</html>
Following method is to render form:
@RequestMapping(value = "/match/create", method = RequestMethod.GET)
public String createMatch(Model model){
model.addAttribute("initialMatchConfiguration", new InitialMatchConfiguration());
return "config-match-initial";
}
Following method is to submit the form:
@RequestMapping(value = "/match/configure", method = RequestMethod.POST)
public String configureMatch(@ModelAttribute("initialMatchConfiguration") InitialMatchConfiguration initialMatchConfig, Model model){
System.out.println(initialMatchConfig);
return "config-match-team";
}
InitialMatchConfiguration class
public class InitialMatchConfiguration {
private Date dateAndTimeOfMatch;
private String matchType;
private Long matchConfigurationId;
private Long tournamentId;
private Long stadiumId;
private String tournament;
private String stadium;
public Date getDateAndTimeOfMatch() {
return dateAndTimeOfMatch;
}
public void setDateAndTimeOfMatch(Date dateAndTimeOfMatch) {
this.dateAndTimeOfMatch = dateAndTimeOfMatch;
}
public String getMatchType() {
return matchType;
}
public void setMatchType(String matchType) {
this.matchType = matchType;
}
public Long getMatchConfigurationId() {
return matchConfigurationId;
}
public void setMatchConfigurationId(Long matchConfigurationId) {
this.matchConfigurationId = matchConfigurationId;
}
public Long getTournamentId() {
return tournamentId;
}
public void setTournamentId(Long tournamentId) {
this.tournamentId = tournamentId;
}
public Long getStadiumId() {
return stadiumId;
}
public void setStadiumId(Long stadiumId) {
this.stadiumId = stadiumId;
}
public String getTournament() {
return tournament;
}
public void setTournament(String tournament) {
this.tournament = tournament;
}
public String getStadium() {
return stadium;
}
public void setStadium(String stadium) {
this.stadium = stadium;
}
}
Request when fired from firefox edit and resend tool:
Request Header:
POST http://localhost:8090/scoreboard.web/score/match/configure
Host: localhost:8090
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8090/scoreboard.web/score/match/create
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
Request Body:
Content-Type: application/x-www-form-urlencoded
Content-Length: 107
dateAndTimeOfMatch=&matchType=friendly&matchConfigurationId=0&tournament=&tournamentId=&stadium=&stadiumId=
ROOT CAUSE: change the type of dateAndTimeOfMatch from text to date
and in FORM class:
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
private Date dateAndTimeOfMatch;
Form :
<form:form modelAttribute="initialMatchConfiguration" action="../match/configure" method="post" >
Date and time:
<form:input path="dateAndTimeOfMatch" type="date" />
<br> Match Type:
<form:select path="matchType">
<option value="friendly">friendly</option>
<option value="international">international</option>
<option value="domestic">domestic</option>
<option value="local">local tournament</option>
</form:select>
<br> Match Rules Configuration:
<form:select path="matchConfigurationId">
<option value="0">Random</option>
<option value="1">T20</option>
<option value="2">One Day</option>
<option value="3">Test</option>
</form:select>
<button type="button">Create a new rule configuration</button>
<br> Tournament:
<form:input type="text" path="tournament" />
<form:hidden path="tournamentId"/>
<button type="button">Create a new Tournament</button>
<br> Played at Stadium:
<form:input type="text" path="stadium" />
<form:hidden path="stadiumId"/>
<button type="button">Create a new stadium</button>
<br> <input type="submit" value="Save" />
InitialMatchConfiguration.java:
public class InitialMatchConfiguration {
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
private Date dateAndTimeOfMatch;
private String matchType;
private Long matchConfigurationId;
private Long tournamentId;
private Long stadiumId;
private String tournament;
private String stadium;
//getters and setters
}
Controller:
@RequestMapping(value = "/match/configure", method = RequestMethod.POST)
public String configureMatch(@ModelAttribute("initialMatchConfiguration") InitialMatchConfiguration initialMatchConfig, Model model){
System.out.println(initialMatchConfig.toString());
return "config-match-team";
}
Response:
** InitialMatchConfiguration [dateAndTimeOfMatch=Tue Jan 10 05:30:00 IST 2017, matchType=international, matchConfigurationId=2, tournamentId=null, stadiumId=null, tournament=sa, stadium=]**