Get HTML Form Data as a Map with Spring Boot Controller


 

Spring Boot Application with using Thymeleaf


A survey application, different surveys have different numbers of questions and each question can have different numbers of option. Inputs are not static, so I couldn't use model for PathVariable. 

I could get form data with using MultiValueMap.

@PostMapping("/SurveySubmit")
public ModelAndView surveyPost(@RequestBody MultiValueMap<String, String> formDataMvMap) {
Map<String, String> formData = formDataMvMap.toSingleValueMap();
Map<String, Object> map = new LinkedHashMap<>();
answerService.saveResultFromMap(formData);
map.put("redirectingPage", "survey.html");
return new ModelAndView("index",map);
}

With using .toSingleValueMap() I can get keys and values.
Keys are the name attributes of input elements.
Values are the value attributes. (for some other elements than input like textarea, it can be inner html)

In the service layer, I can separate data and fit to model.

@Override
public void saveResultFromMap(Map<String, String> map) {
Answer answer = new Answer();
map.forEach((x, y) -> {
Answer tempAnswerObj = new Answer();
if (x.equals(_QUESTION_USER_KEY)) answer.setUsername(y);
if (x.equals(_QUESTION_SURVEY_KEY)) answer.setSurveyId(Integer.parseInt(y));

tempAnswerObj.setUsername(answer.getUsername());
tempAnswerObj.setSurveyId(answer.getSurveyId());

if (x.contains(_QUESTION_TYPE_RADIO) || x.contains(_QUESTION_TYPE_CHECK)) {
tempAnswerObj.setQuestionNo(Integer.parseInt(y.split(_SPLITTER)[0]));
tempAnswerObj.setQuestionOptionNo(Integer.parseInt(y.split(_SPLITTER)[1]));
save(tempAnswerObj);
}
if (x.contains(_QUESTION_TYPE_TEXT)) {
System.out.println(x + x.split(_SPLITTER)[0]);
tempAnswerObj.setQuestionNo(Integer.parseInt(x.split(_SPLITTER)[1]));
tempAnswerObj.setTextAnswer(y);
save(tempAnswerObj);
}
});
}

If x (key) equals to _QUESTION_USER_KEY , y (value) is username. I know that because I set this input's name attribute _QUESTION_USER_KEY . And it goes for model's userName. For standardization, I get the string from property file, use it into the bean and also html.

@Value("${s.user.key}")
private String _QUESTION_USER_KEY;
<form method="post" th:action="@{/SurveySubmit}" id="survey-form">
<input id="user" th:name="#{s.user.key}" type="hidden" th:value="${surveyUser}"/>

Comments