日常练习
今天练习在eclipse上使用spring boot写简单程序。
大致目标是完成一个简单的学生成绩系统。
首先是主类:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {> ``
SpringApplication.run(DemoApplication.class, args);
}
}
控制器:
package com.example.demo.controller;
import com.example.demo.entity.Student;
import com.example.demo.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.Objects;
@Controller
public class StudentController {
@Autowired
private StudentService studentService;
@GetMapping("/")
public String index(Model model,
@RequestParam(required = false) String searchName,
@RequestParam(required = false) Boolean onlyPass) {
model.addAttribute("students",
studentService.getFilteredStudents(searchName, onlyPass));
model.addAttribute("searchName", searchName);
model.addAttribute("onlyPass", onlyPass);
return "index";
}
@PostMapping("/add")
public String addStudent(
@RequestParam("name") String name, // 明确指定参数名
@RequestParam("score") Integer score, // 确保类型匹配
@RequestParam(required = false) String searchName,
@RequestParam(required = false) Boolean onlyPass) {
// 添加参数验证
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException("姓名不能为空");
}
if (score < 0 || score > 100) {
throw new IllegalArgumentException("分数必须在0-100之间");
}
studentService.addStudent(name, score);
return createRedirectUrl(searchName, onlyPass);
}
@GetMapping("/delete/{id}")
public String deleteStudent(@PathVariable Long id,
@RequestParam(required = false) String searchName,
@RequestParam(required = false) Boolean onlyPass) {
studentService.deleteStudent(id);
return createRedirectUrl(searchName, onlyPass);
}
private String createRedirectUrl(String searchName, Boolean onlyPass) {
UriComponentsBuilder builder = UriComponentsBuilder.fromPath("/");
if (searchName != null && !searchName.isEmpty()) {
builder.queryParam("searchName", searchName);
}
if (onlyPass != null) {
builder.queryParam("onlyPass", onlyPass);
}
return "redirect:" + builder.toUriString();
}
}
服务类:
package com.example.demo.service;
import com.example.demo.entity.Student;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Service
public class StudentService {
private List<Student> students = new ArrayList<>();
private Long nextId = 1L;
public List<Student> getFilteredStudents(String searchName, Boolean onlyPass) {
return students.stream()
.filter(s -> searchName == null || s.getName().startsWith(searchName))
.filter(s -> !Boolean.TRUE.equals(onlyPass) || s.getScore() >= 60)
.collect(Collectors.toList());
}
public void addStudent(String name, Integer score) {
Objects.requireNonNull(name, "姓名不能为null");
if (score == null) {
throw new IllegalArgumentException("分数不能为null");
}
students.add(new Student(nextId++, name, score));
}
public void deleteStudent(Long id) {
students.removeIf(s -> s.getId().equals(id));
}
}
实体类:
package com.example.demo.entity;
public class Student {
private Long id;
private String name;
private Integer score;
public Student() {}
public Student(Long id, String name, Integer score) {
this.id = id;
this.name = name;
this.score = score;
}
// Getter & Setter 方法
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getScore() {
return score;
}
public void setScore(Integer score) {
this.score = score;
}
}
html文件:
index.html:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>学生成绩管理系统</title>
<style>
.red { color: red; }
table { border-collapse: collapse; margin-top: 20px; }
th, td { padding: 8px; border: 1px solid #ddd; }
</style>
</head>
<body>
<h1>学生成绩管理系统</h1>
<!-- 添加表单 -->
<form th:action="@{/add}" method="post" onsubmit="return validateForm()">
<input type="text" name="name" required
minlength="2" maxlength="10"
pattern="[\u4e00-\u9fa5a-zA-Z]+"
title="姓名只能包含中文或英文字符">
<input type="number" name="score"
required min="0" max="100"
oninvalid="this.setCustomValidity('分数必须在0-100之间')"
oninput="this.setCustomValidity('')">
<!-- 保留隐藏参数 -->
<button type="submit">添加学生</button>
</form>
<!-- 过滤表单 -->
<form method="get" style="margin: 20px 0;">
<input type="text" name="searchName" placeholder="搜索姓氏"
th:value="${searchName}">
<label>
<input type="checkbox" name="onlyPass"
th:checked="${onlyPass}"> 仅显示及格
</label>
<button type="submit">筛选</button>
</form>
<script>
function validateForm() {
const scoreInput = document.querySelector('input[name="score"]');
if (scoreInput.value < 0 || scoreInput.value > 100) {
alert("分数必须在0-100之间");
return false;
}
return true;
}
</script>
<!-- 学生列表 -->
<div th:if="${#lists.isEmpty(students)}" style="color: #666;">
暂无学生数据,请添加学生信息
</div>
<table th:unless="${#lists.isEmpty(students)}">
<tr>
<th>姓名</th>
<th>分数</th>
<th>操作</th>
</tr>
<tr th:each="student : ${students}">
<td th:text="${student.name}"></td>
<td>
<span th:class="${student.score < 60} ? 'red'"
th:text="${student.score}"></span>
</td>
<td>
<a th:href="@{/delete/{id}(id=${student.id},
searchName=${searchName},
onlyPass=${onlyPass})">删除</a>
</td>
</tr>
</table>
</body>
</html>
error.html:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>错误页面</title>
<style>
.error-container {
max-width: 800px;
margin: 2rem auto;
padding: 2rem;
background: #ffe6e6;
border: 1px solid #ff9999;
border-radius: 8px;
}
</style>
</head>
<body>
<div class="error-container">
<h1>⚠️ 发生错误</h1>
<p th:text="${errorMessage}"></p>
<a href="/">返回首页</a>
</div>
</body>
</html>
我目前的练习项目的内容就是如此,我测试时发现无法运行,当点击添加学生时就会直接进入error.html,同时点击返回首页也无济于事。
我猜想错误大概是我的控制器出错了,但不知道具体在哪里,仍在摸索。