You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot实现下拉选值提交至方法并存储对象的配置方案

Fixing Your Spring Boot Form & Request Mapping Issues

Let's work through your code step by step to get the dropdown selection working correctly and save the chosen Test to your ActiveTest variable. Here's what's broken in your current implementation, plus how to fix it:

Key Issues in Your Current Code

  • Invalid Submit Button Configuration: Submit buttons don't have an action attribute — that belongs to the <form> tag. Use formaction on individual buttons to target different endpoints instead.
  • Missing name on <select>: Without a name attribute, the selected value won't be sent as a request parameter to your backend.
  • Bad Option Value: Setting the option value directly to the test object will send its raw toString() output, which isn't usable for matching tests. Use a unique identifier like the test's name (or ID if you have one) instead.
  • Broken Parameter Handling: Your sendTest method tries to map the selection parameter to a HttpServletRequest (which won't work), and your matching logic compares against the literal string "selection" instead of the actual user-selected value.
  • Suboptimal HTML Generation: Building HTML directly in Java is messy and hard to maintain — we'll fix this (or at least clean up the existing approach).

Corrected Full Code

@MultipartConfig // Keep this if you need file upload support
@Controller // Switched from @RestController since we're returning HTML views
@RequestMapping(value = "/Teacher", produces = "text/html;charset=UTF-8")
public class TeacherController { // Renamed to follow Java class naming conventions
    private final TestController testcont = TestController.getInstance();

    // Option 1: Clean approach using Thymeleaf (recommended)
    @GetMapping("")
    public String homePage(Model model) {
        model.addAttribute("allTests", testcont.showAllTests());
        model.addAttribute("activeTest", testcont.getActiveTest());
        return "teacher-dashboard"; // Maps to src/main/resources/templates/teacher-dashboard.html
    }

    // Option 2: If you want to keep building HTML in Java (not recommended, but works)
    /*
    @GetMapping("")
    @ResponseBody
    public String homePage() {
        StringBuilder sb = new StringBuilder();
        sb.append("<p><div style='height:200px;width:500px;border:1px solid #ccc;font:16px/26px Georgia, Garamond, Serif;overflow:auto;'>");
        sb.append("<form method='post'>"); // No action here — use formaction on buttons
        sb.append("<input type='submit' value='Submit' formaction='/Teacher/sendTest'>");
        sb.append("<input type='submit' value='Reset' formaction='/Teacher/resetCurrentTest'>");
        sb.append("<p>Current Test for students: ").append(testcont.getActiveTest()).append("</p>");
        sb.append("<fieldset><p><label>Select test</label>");
        sb.append("<select name='selection' id='selection'>"); // Added required name attribute
        sb.append(buildTestOptions());
        sb.append("</select></p></fieldset></form></div></p>");
        return sb.toString();
    }
    */

    @PostMapping("/sendTest")
    public String sendTest(@RequestParam("selection") String selectedTestName, RedirectAttributes redirectAttributes) {
        // Find the matching test using the selected name
        Test selectedTest = testcont.showAllTests()
                .stream()
                .filter(test -> test.getName().equals(selectedTestName))
                .findFirst()
                .orElse(null);

        if (selectedTest != null) {
            testcont.setActiveTest(selectedTest); // Fixed method name to follow camelCase conventions
            redirectAttributes.addFlashAttribute("successMsg", "Active test updated successfully!");
        } else {
            redirectAttributes.addFlashAttribute("errorMsg", "Selected test not found!");
        }
        return "redirect:/Teacher"; // Redirect back to refresh the page with updated data
    }

    @PostMapping("/resetCurrentTest")
    public String resetCurrentTest(RedirectAttributes redirectAttributes) {
        testcont.setActiveTest(null); // Adjust reset logic to match your needs
        redirectAttributes.addFlashAttribute("successMsg", "Active test reset!");
        return "redirect:/Teacher";
    }

    private String buildTestOptions() {
        StringBuilder sb = new StringBuilder();
        for (Test test : testcont.showAllTests()) {
            // Use test name as the value (use an ID field instead if names aren't unique)
            sb.append("<option value='").append(test.getName()).append("'>");
            sb.append(test.getName()).append(" - ").append(test.getFile().getName());
            sb.append("</option>");
        }
        return sb.toString();
    }
}

Create src/main/resources/templates/teacher-dashboard.html to separate HTML from your Java code:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Teacher Dashboard</title>
    <style>
        .dashboard-container {
            height: 200px;
            width: 500px;
            border: 1px solid #ccc;
            font: 16px/26px Georgia, Garamond, Serif;
            overflow: auto;
            padding: 15px;
        }
        .success { color: green; }
        .error { color: red; }
    </style>
</head>
<body>
<div class="dashboard-container">
    <form method="post">
        <input type="submit" value="Submit" formaction="/Teacher/sendTest">
        <input type="submit" value="Reset" formaction="/Teacher/resetCurrentTest">
        
        <p>Current Test for students: <span th:text="${activeTest} ?: 'No active test'"></span></p>
        
        <fieldset>
            <label>Select test</label>
            <select name="selection" id="selection">
                <option th:each="test : ${allTests}" 
                        th:value="${test.name}" 
                        th:text="${test.name + ' - ' + test.file.name}"></option>
            </select>
        </fieldset>
    </form>

    <p th:if="${successMsg}" class="success">[[${successMsg}]]</p>
    <p th:if="${errorMsg}" class="error">[[${errorMsg}]]</p>
</div>
</body>
</html>

Key Fixes Explained

  1. Form & Button Logic:

    • Removed invalid action attributes from submit buttons, replaced with formaction to target specific endpoints.
    • Set the form method to post (best practice for modifying data).
  2. Dropdown Configuration:

    • Added name='selection' to the <select> tag so the selected value is sent as a request parameter.
    • Changed option values to use the test's name (or ID) instead of the raw object, making it easy to match on the backend.
  3. Backend Parameter Handling:

    • Corrected the sendTest method to receive the selected value via @RequestParam("selection").
    • Used a stream to cleanly find the matching test (replacing the broken for-loop logic).
    • Added redirects with flash attributes to show user feedback and refresh the page with updated data.
  4. Java Conventions:

    • Renamed the class to TeacherController (standard for Spring controllers).
    • Fixed SetActiveTest to setActiveTest to follow camelCase method naming rules.

内容的提问来源于stack exchange,提问作者bullfighter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:22:53