Spring Boot+Hibernate接口请求异常:/rest/test无法返回预期内容
我的StudentController类上配置了@RequestMapping("/rest"),test方法配置了@GetMapping("/test"),按配置访问http://localhost:8080/TestHibernate/rest/test应返回字符串'Success',但实际未得到预期结果。访问http://localhost:8080/TestHibernate可正常获取index文件内容。
提供的代码与配置
Controller层
package com.akshay.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.akshay.dao.StudentDAO; import com.akshay.entity.Student; @RestController @RequestMapping("/rest") public class StudentController { @Autowired private StudentDAO studentDAO; @PostMapping("/saveStudent") public String save(@RequestBody Student student) { studentDAO.saveStudent(student); return "Saved Successfully"; } @GetMapping("/test") public String test() { return "Success"; } }
DAO层
package com.akshay.dao; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import com.akshay.entity.Student; @Repository @Transactional public class StudentDAO { @Autowired private SessionFactory factory; private Session getSession() { Session session = factory.getCurrentSession(); if(session == null) { session = factory.openSession(); } return session; } public void saveStudent(Student student) { getSession().save(student); } }
Entity层
package com.akshay.entity; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "student") public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private int id; @Column(name = "first_name") private String firstName; @Column(name = "last_name") private String lastName; @Column(name = "email") private String email; public Student() { } public Student(String firstName, String lastName, String email) { this.firstName = firstName; this.lastName = lastName; this.email = email; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "Student [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + "]"; } }
启动类
package com.akshay.TestHibernate; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class TestHibernateApplication { public static void main(String[] args) { SpringApplication.run(TestHibernateApplication.class, args); } }
POM文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.0</version> <relativePath /> <!-- lookup parent from repository --> </parent> <groupId>com.akshay</groupId> <artifactId>TestHibernate</artifactId> <version>0.0.1-SNAPSHOT</version> <name>TestHibernate</name> <description>Demo project to test hibernate and mysql</description> <properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <!--<scope>provided</scope> --> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
application.properties配置
# # JDBC connection properties # jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/web_student_tracker jdbc.user=springstudent jdbc.password=springstudent # # Connection pool properties # connection.pool.initialPoolSize=5 connection.pool.minPoolSize=5 connection.pool.maxPoolSize=20 connection.pool.maxIdleTime=3000 # # Hibernate properties # hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.show_sql=true hibernate.packagesToScan=com.akshay.entity
核心问题及解决方法
1. Spring Boot自动扫描范围不包含Controller包
启动类TestHibernateApplication在com.akshay.TestHibernate包下,@SpringBootApplication默认只扫描启动类所在包及其子包,导致com.akshay.controller下的Controller无法被Spring容器识别。
解决方法:
- 方案一:将启动类移动到
com.akshay包下,自动扫描所有子包 - 方案二:在启动类注解中指定扫描范围:
@SpringBootApplication(scanBasePackages = "com.akshay")
2. 数据库配置不符合Spring Boot规范
当前使用的是传统Hibernate配置项,Spring Boot无法自动加载这些配置,会导致数据库连接、SessionFactory初始化失败,进而影响Controller的正常加载。
解决方法:
替换为Spring Boot标准JPA配置:
# 数据库连接配置 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/web_student_tracker?useSSL=false&serverTimezone=UTC spring.datasource.username=springstudent spring.datasource.password=springstudent # JPA/Hibernate配置 spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
注:MySQL 8.x及以上版本建议使用
com.mysql.cj.jdbc.Driver驱动,同时指定时区参数
3. DAO层SessionFactory注入问题
Spring Boot中推荐使用EntityManager而非直接注入SessionFactory,未配置的情况下SessionFactory会注入失败,导致容器启动异常。
解决方法:
改用EntityManager实现DAO逻辑:
@Repository @Transactional public class StudentDAO { @PersistenceContext private EntityManager entityManager; public void saveStudent(Student student) { entityManager.persist(student); } }
4. 项目上下文路径验证
访问URL中的TestHibernate是上下文路径,需确认Spring Boot是否配置了该路径:
- 查看启动日志,若没有
Tomcat started on port(s): 8080 (http) with context path '/TestHibernate'的日志,说明上下文路径为空,应访问http://localhost:8080/rest/test - 若需要指定上下文路径,在application.properties中添加:
server.servlet.context-path=/TestHibernate
内容的提问来源于stack exchange,提问作者Akshay

