以下是一个基于Spring Boot的RESTful Web服务的完整示例代码,包括项目结构、依赖配置、控制器、服务层、数据访问层以及实体类。这个示例实现了一个简单的博客系统,包含帖子(Post)的增删改查功能。
项目结构
springboot-restful
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── springbootrestful
│ │ │ ├── SpringbootRestfulApplication.java
│ │ │ ├── controller
│ │ │ │ └── PostController.java
│ │ │ ├── service
│ │ │ │ └── PostService.java
│ │ │ ├── repository
│ │ │ │ └── PostRepository.java
│ │ │ └── model
│ │ │ └── Post.java
│ │ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── com
│ └── example
│ └── springbootrestful
│ └── SpringbootRestfulApplicationTests.java
└── pom.xml
1. 依赖配置(pom.xml
)
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>springboot-restful</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.0</version>
</parent>
<dependencies>
<!-- Spring Boot Web Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Data JPA Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- MySQL Driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Spring Boot Test Starter -->
<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>
2. 启动类(SpringbootRestfulApplication.java
)
package com.example.springbootrestful;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootRestfulApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootRestfulApplication.class, args);
}
}
3. 实体类(Post.java
)
package com.example.springbootrestful.model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String content;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
4. 数据访问层(PostRepository.java
)
package com.example.springbootrestful.repository;
import com.example.springbootrestful.model.Post;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
}
5. 服务层(PostService.java
)
package com.example.springbootrestful.service;
import com.example.springbootrestful.model.Post;
import com.example.springbootrestful.repository.PostRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class PostService {
@Autowired
private PostRepository postRepository;
public List<Post> getAllPosts() {
return postRepository.findAll();
}
public Optional<Post> getPostById(Long id) {
return postRepository.findById(id);
}
public Post createPost(Post post) {
return postRepository.save(post);
}
public Post updatePost(Long id, Post post) {
return postRepository.findById(id)
.map(existingPost -> {
existingPost.setTitle(post.getTitle());
existingPost.setContent(post.getContent());
return postRepository.save(existingPost);
}).orElseThrow(() -> new RuntimeException("Post not found"));
}
public void deletePost(Long id) {
postRepository.deleteById(id);
}
}
6. 控制器层(PostController.java
)
package com.example.springbootrestful.controller;
import com.example.springbootrestful.model.Post;
import com.example.springbootrestful.service.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/posts")
public class PostController {
@Autowired
private PostService postService;
@GetMapping
public List<Post> getAllPosts() {
return postService.getAllPosts();
}
@GetMapping("/{id}")
public ResponseEntity<Post> getPostById(@PathVariable Long id) {
return postService.getPostById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PostMapping
public Post createPost(@RequestBody Post post) {
return postService.createPost(post);
}
@PutMapping("/{id}")
public ResponseEntity<Post> updatePost(@PathVariable Long id, @RequestBody Post post) {
try {
Post updatedPost = postService.updatePost(id, post);
return ResponseEntity.ok(updatedPost);
} catch (RuntimeException e) {
return ResponseEntity.notFound().build();
}
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deletePost(@PathVariable Long id) {
try {
postService.deletePost(id);
return ResponseEntity.noContent().build();
} catch (RuntimeException e) {
return ResponseEntity.notFound().build();
}
}
}
7. 配置文件(application.properties
)
# 数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/blogdb
spring.datasource.username=root
spring.datasource.password=yourpassword
# JPA配置
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
8. 测试类(SpringbootRestfulApplicationTests.java
)
package com.example.springbootrestful;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpringbootRestfulApplicationTests {
@Test
void contextLoads() {
}
}
项目运行
- 确保MySQL数据库已安装并运行。
- 创建一个名为
blogdb
的数据库。 - 运行项目,访问
http://localhost:8080/api/posts
即可测试RESTful API。
功能说明
- GET
/api/posts
:获取所有帖子。 - GET
/api/posts/{id}
:通过ID获取特定帖子。 - POST
/api/posts
:创建新帖子。 - PUT
/api/posts/{id}
:更新特定帖子。 - DELETE
/api/posts/{id}
:删除特定帖子。
这个示例展示了如何使用Spring Boot构建一个简单的RESTful Web服务,涵盖了从数据库操作到API交互的完整流程。
Spring 与 Restful 整合才是微架构的核心,虽然在整个 SpringBoot(SpringCloud)之中提供有大量的服务方便整合,但是这些 整合都不如 Rest 重要,因为 Rest 是整个在微架构之中进行通讯的基础模式。那么对于 Rest 首先必须对其有一个最为核心的解释: 利用 JSON 实现数据的交互处理。而且 Spring 里面提供有一个非常强大的 RestTemplate 操作模版,利用此模版可以非常轻松的实现 Rest 的 JSON 数据与各种对象间的自动转换。
在默认状态下 Spring 里面针对于 Rest 的处理使用的都是 jackson 开发包支持包。
springboot系类代码:springboot-restful
package com.programb.pos;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
package com.programb.pos.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import com.programb.pos.model.BaseResponse;
import com.programb.pos.model.User;
import java.util.*;
@RestController
@RequestMapping(value = "/users")
public class UserController {
private static final Logger _logger = LoggerFactory.getLogger(UserController.class);
// 创建线程安全的Map
private static Map<Long, User> users = Collections.synchronizedMap(new HashMap<Long, User>());
@RequestMapping(value = "/", method = RequestMethod.GET)
public BaseResponse<List<User>> getUserList() {
// 处理"/users/"的GET请求,用来获取用户列表
// 还可以通过@RequestParam从页面中传递参数来进行查询条件或者翻页信息的传递
List<User> r = new ArrayList<>(users.values());
return new BaseResponse<>(true, "查询列表成功", r);
}
@RequestMapping(value = "/", method = RequestMethod.POST)
public BaseResponse<String> postUser(@ModelAttribute User user) {
// 处理"/users/"的POST请求,用来创建User
// 除了@ModelAttribute绑定参数之外,还可以通过@RequestParam从页面中传递参数
users.put(user.getId(), user);
return new BaseResponse<>(true, "新增成功", "");
}
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public BaseResponse<User> getUser(@PathVariable Long id) {
// 处理"/users/{id}"的GET请求,用来获取url中id值的User信息
// url中的id可通过@PathVariable绑定到函数的参数中
return new BaseResponse<>(true, "查询成功", users.get(id));
}
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public BaseResponse<String> putUser(@PathVariable Long id, @ModelAttribute User user) {
// 处理"/users/{id}"的PUT请求,用来更新User信息
User u = users.get(id);
u.setName(user.getName());
u.setAge(user.getAge());
users.put(id, u);
return new BaseResponse<>(true, "更新成功", "");
}
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public BaseResponse<String> deleteUser(@PathVariable Long id) {
// 处理"/users/{id}"的DELETE请求,用来删除User
users.remove(id);
return new BaseResponse<>(true, "删除成功", "");
}
}
package com.programb.pos.model;
public class BaseResponse<T> {
private boolean success;
private String msg;
private T data;
public BaseResponse() {
}
public BaseResponse(boolean success, String msg, T data) {
this.success = success;
this.msg = msg;
this.data = data;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
package com.programb.pos.model;
public class User {
private Long id;
private String name;
private Integer age;
public User() {
}
public User(Long id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
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 getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
package com.programb.pos.util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
public class JacksonUtil {
private static ObjectMapper mapper = new ObjectMapper();
public static String bean2Json(Object obj) {
try {
return mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
public static <T> T json2Bean(String jsonStr, TypeReference<T> typeReference) {
try {
return mapper.readValue(jsonStr, typeReference);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
server.port: 8092
spring:
profiles:
active: dev
logging:
level:
org.springframework.web.servlet: ERROR
spring:
profiles: dev
logging:
level:
ROOT: INFO
com:
xncoding: DEBUG
file: E:/programb/logs/app.log
spring:
profiles: test
logging:
level:
ROOT: INFO
com:
xncoding: DEBUG
file: /programb/logs/app.log
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.programb</groupId>
<artifactId>springboot-restful</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-restful</name>
<description>RESTful API</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<!--<proc>none</proc>-->
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>