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

如何在Thymeleaf页面根据用户选择输出H2数据库指定行?排查500错误

问题:H2数据库查询与页面渲染500错误排查及功能实现

我有一个预填充数据的H2数据库,希望通过页面上的select元素选择后输出指定行数据,但访问characterCreator页面时出现HTML 500错误。

现有配置与代码

application.properties配置

spring.h2.console.enabled=true
spring.datasource.url=jdbc:h2:mem:348dae81-3b35-422e-8aa6-eb69a6163544
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=

characterCreator.html代码

<div style="margin:auto; text-align: center;">
    <form action="/characterCreator" method="get">
        <select style="align-self: center;" th:field="*{id}">
            <option th:each="race : ${RACE}"
                    th:value="${race.ID}"
                    th:text="${race.RACE_NAME}">Select Race
            </option>
        </select>
        <br><br>
        <input type="submit" value="Select">
    </form>
</div>

RaceController.java代码

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/characterCreator")
public class RaceController {

    private final RaceRepository raceRepository;

    public RaceController(RaceRepository raceRepository) {
        this.raceRepository = raceRepository;
    }

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @GetMapping("/{id}")
    public String getRace(@PathVariable int id) {
        String query = "SELECT * FROM RACE WHERE ID = ?";
        List<Map<String, Object>> rows = jdbcTemplate.queryForList(query, id);
        return rows.get(0).get("ID").toString();
    }
}

HomeController.java代码

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {
    @GetMapping({"/", "/home"})
    public String getHome() {
        return "home";
    }   

    @GetMapping("/generalLore")
    public String getGeneralLore() {
        return "generalLore";
    }

    @GetMapping("/characterCreator")
    public String getCharacterCreator() {
        return "characterCreator";
    }

    @GetMapping("/exampleCharacter")
    public String getExampleCharacter() {
        return "exampleCharacter";
    }
}

数据库表结构

H2数据库中RACE表包含ID、RACE_NAME等字段,已验证查询语句在H2控制台可正常返回对应结果。


错误原因与解决方案

1. 页面渲染500错误的核心原因

HomeController返回characterCreator页面时,未向Thymeleaf模板传递RACE列表数据,导致模板中${RACE}变量为空,触发渲染异常。

修复方法:修改HomeController
注入JdbcTemplate,查询所有种族数据并添加到模型中:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.ui.Model;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
import java.util.Map;

@Controller
public class HomeController {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @GetMapping({"/", "/home"})
    public String getHome() {
        return "home";
    }   

    @GetMapping("/generalLore")
    public String getGeneralLore() {
        return "generalLore";
    }

    @GetMapping("/characterCreator")
    public String getCharacterCreator(Model model) {
        // 查询所有种族数据传递给模板
        List<Map<String, Object>> races = jdbcTemplate.queryForList("SELECT * FROM RACE");
        model.addAttribute("RACE", races);
        return "characterCreator";
    }

    @GetMapping("/exampleCharacter")
    public String getExampleCharacter() {
        return "exampleCharacter";
    }
}

2. 表单提交与接口路径不匹配问题

当前表单提交的URL是/characterCreator?id=xxx(GET请求带参数),但RaceController的接口是/characterCreator/{id}(路径变量),两者不匹配,无法正确接收参数。

修复方法二选一:

方案A:调整RaceController接口接收请求参数

@RestController
@RequestMapping("/characterCreator")
public class RaceController {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    // 删除未使用的RaceRepository相关代码,避免不必要的依赖问题
    // private final RaceRepository raceRepository;
    // public RaceController(RaceRepository raceRepository) {
    //     this.raceRepository = raceRepository;
    // }

    @GetMapping
    public String getRace(@RequestParam int id) {
        String query = "SELECT * FROM RACE WHERE ID = ?";
        List<Map<String, Object>> rows = jdbcTemplate.queryForList(query, id);
        // 处理查询结果为空的情况,避免空指针异常
        if (rows.isEmpty()) {
            return "Race not found";
        }
        return rows.get(0).get("RACE_NAME").toString(); // 可根据需求返回字段
    }
}

方案B:调整表单提交路径(需配合JS动态修改,适合REST风格场景)

修改表单的action为动态路径,或者通过JavaScript监听select选择事件,修改表单action:

<form id="raceForm" method="get">
    <select style="align-self: center;" id="raceSelect" th:field="*{id}">
        <option th:each="race : ${RACE}"
                th:value="${race.ID}"
                th:text="${race.RACE_NAME}">Select Race
        </option>
    </select>
    <br><br>
    <input type="submit" value="Select">
</form>

<script>
document.getElementById('raceSelect').addEventListener('change', function() {
    const raceId = this.value;
    document.getElementById('raceForm').action = `/characterCreator/${raceId}`;
});
</script>

3. 其他潜在问题修复

  • 删除RaceController中未使用的RaceRepository依赖,避免因未正确定义该Repository导致的初始化错误;
  • 在查询数据库时添加空结果判断,防止rows.get(0)抛出IndexOutOfBoundsException。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 09:35:04