I’m working on a Spring Boot application where I need to handle form submissions from an HTML page. The form data includes a list of strings that should be mapped to an enum in my UserSurvey model.
Here’s a simplified version of my model:
data class UserSurvey(
var reasonsForApplying: SurveyOptions<ApplicationReason>? = null,
var concernsAboutProcess: SurveyOptions<ApplicationConcern>? = null
)
data class SurveyOptions<T>(
var selected: MutableList<T>? = null,
var other: String? = null
)
enum class ApplicationReason {
CAREER_ADVANCEMENT, EDUCATIONAL_OPPORTUNITIES, SOCIAL_SECURITY_BENEFITS, FAMILY_REUNIFICATION, OTHER
}
enum class ApplicationConcern {
HIGH_APPLICATION_FEE, LANGUAGE_DIFFICULTIES, LENGTHY_PROCESS, FEAR_OF_DENIAL, INSUFFICIENT_INFORMATION, OTHER
}
@Controller
class SurveyController {
@PostMapping("/submitSurvey")
fun submitSurvey(
@ModelAttribute survey: UserSurvey
): String {
survey. reasonsForApplying.selected.forEach {
println(it)
}
return "survey-thank-you"
}
}
When I change SurveyOptions<ApplicationReason>
to SurveyOptions<String>
, it works fine. However, with enum, while accessing the bean reasonsForApplying, I get the following error:
java.lang.String cannot be cast to com.example.controller.ApplicationReason
Looks like, spring is creating the List with type String instead of the Enum.
My HTML page
<form action="/submitSurvey" method="post">
<label>Reasons for Applying:</label><br>
<input type="checkbox" name="reasonsForApplying.selected" value="CAREER_ADVANCEMENT"> Career Advancement<br>
<input type="checkbox" name="reasonsForApplying.selected" value="EDUCATIONAL_OPPORTUNITIES"> Educational Opportunities<br>
<input type="checkbox" name="reasonsForApplying.selected" value="SOCIAL_SECURITY_BENEFITS"> Social Security Benefits<br>
<input type="checkbox" name="reasonsForApplying.selected" value="FAMILY_REUNIFICATION"> Family Reunification<br>
<input type="checkbox" name="reasonsForApplying.selected" value="OTHER"> Other<br>
<input type="text" name="reasonsForApplying.other"><br><br>
<label>Concerns About Process:</label><br>
<input type="checkbox" name="concernsAboutProcess.selected" value="HIGH_APPLICATION_FEE"> High Application Fee<br>
<input type="checkbox" name="concernsAboutProcess.selected" value="LANGUAGE_DIFFICULTIES"> Language Difficulties<br>
<input type="checkbox" name="concernsAboutProcess.selected" value="LENGTHY_PROCESS"> Lengthy Process<br>
<input type="checkbox" name="concernsAboutProcess.selected" value="FEAR_OF_DENIAL"> Fear of Denial<br>
<input type="checkbox" name="concernsAboutProcess.selected" value="INSUFFICIENT_INFORMATION"> Insufficient Information<br>
<input type="checkbox" name="concernsAboutProcess.selected" value="OTHER"> Other<br>
<input type="text" name="concernsAboutProcess.other"><br><br>
<button type="submit">Submit</button>
</form>
I’ve tried several approaches, including:
Property Editors: Registered a custom property editor, but setAsText and getAsText methods are not called.
Converters: Used ConversionService with custom converters, but the issue persists.
Custom Deserializers: Tried using Jackson’s @JsonDeserialize but that only works for REST controllers.
DataBinder: Also didn’t resolve the issue.
None of these approaches have worked in the context of a non-REST controller. How can I correctly map a list of strings from an HTML form to enum types in my model using @ModelAttribute in a non-REST controller?