問卷系統中,每道題可勾選多個選項,後端需知道「題目 ID」與「被勾選的選項 ID」對應關係。前端為動態生成的 CheckBox 群組。
採用 name="answers[${questionId}]" 陣列命名法,值為選項 ID:
<!-- 第 1 題 -->
<input type="checkbox" name="answers[1]" value="101"> 選項A
<input type="checkbox" name="answers[1]" value="102"> 選項B
<!-- 第 2 題 -->
<input type="checkbox" name="answers[2]" value="201"> 選項C
<input type="checkbox" name="answers[2]" value="202"> 選項D
@PostMapping("/submit")
public String submit(@RequestParam Map<String, String[]> allParams) {
// allParams key 為 "answers[1]",value 為被勾選的選項 ID 陣列
allParams.forEach((key, values) -> {
if (key.startsWith("answers[")) {
String qId = key.replaceAll("\\D", ""); // 提取題號
List<String> options = Arrays.asList(values);
saveAnswer(qId, options);
}
});
return "success";
}
public class AnswerForm {
private Map<Long, List<Long>> answers = new HashMap<>();
// getter/setter
}
@PostMapping("/submit")
public String submit(@ModelAttribute AnswerForm form) {
form.getAnswers().forEach(this::saveAnswer);
return "success";
}
需搭配 @InitBinder 註冊自定義 PropertyEditor 或使用 Spring 內建的集合綁定(Spring 3.2+ 自動支援 Map<K, List<V>>)。
answer_record (id, question_id, option_id),每筆一行,便於統計。{"1": [101,102], "2": [201]},查詢靈活、節省 Join。null 或空 Map,需預設處理。name="answer_1_101" 扁平化命名,後端解析成本高,不推薦。