SpringBoot项目的分层

SpringBoot框架项目一般分为五层:

  • View层:向用户展示页面

  • Controller层:前后端交互层,接收前端请求,调用Service层中的方法,接收Service层返回的数据并将其返回到前端。

  • Service层:存放业务处理的逻辑,以及一些操作数据库的接口

  • Mapper层:也可以成为DAO层,是数据库CRUD的接口,只有方法名,具体实现在mapper.xml文件中,对数据库进行数据持久化操作

  • Entity层:存放实体类,与数据库中的属性基本保持一致。

实现一个最简单的POST接口

一个最简单的POST接口,只需要在Controller层中声明一个RestController类,随后在类中使用PostMapping注解,表明这是一个POST接口,并填写相关方法即可,如下所示:

@RestController
@RequestMapping("/api")
public class CreateNumberController {
@PostMapping("/number")
public String createNumber(@RequestParam String param1, @RequestParam int param2) {
// 处理POST请求的代码
return "success";
}
}

运行程序后,使用Postman向http://localhost:8000/api/number发送POST请求,输入相应请求参数,得到接口响应:

将接口连接事务处理逻辑函数

实际业务中的接口肯定不仅仅是如同上面的示例那么简单的一个函数,程序内部对于接收到的数据会有一定的逻辑处理。

接下来列出一个实际的业务场景:

需求

现在需要一个接口用于按照一定规则为项目赋予项目编码,项目请求内容为xml报文,例如:

<?xml version="1.0" encoding="UTF-8"?>
<name>Example Project</name>
<operate>01</operate>
<source>A</source>
<status>01</status>

当请求参数operate是1时为新增项目编码,请求参数source是A、B、C时,项目编码为Axxxx,“xxxx”为四位包含「09的10个阿拉伯数字」和「AZ的26个大写英文字母」共同组成的流水码次序为:0/1/2/3/4/5/6/7/8/9/A/B/C/D~/X/Y/Z,增加2条约束:

①第5位、第4位与第3位从000开始取值,第2位从B开始取值,即初始编码为:AB000;第5位至第2位,每一位的取值范围为「09的10个阿拉伯数字」和「AZ的24个大写英文字母(26个字母中去除I和O)」的34个字符,顺序依次为0/1/2/3/4/5/6/7/8/9/A/B/C/D~/X/Y/Z,此时“xxxx”为34进制的4位数。第5位0至Z循环一周期后即向第4位进1,第4位循环一周期后即向第3位进1,第3位循环一周期后向第2位进1。

②第2位除了I和O之外,A、C、Z也不可取,循环取值从B开始至A结束,依次为B/D…G/H/J/K…M/N/P…X/Y/0/1…9共计31个字符。

要求返回值为xml报文,形式为:

<?xml version="1.0" encoding="UTF-8"?>
<number>AB000</number>
<status>01</status>

由于暂未规定如何校验重复编码(这个需要用到数据库查询,在接下来的部分继续补充),因此可以将需求简单理解为:接收一个xml报文,按照规则生成一个编码,返回编码。

这时接口的输入和输出都是xml报文,仅仅依靠简单的Controller已经不能满足需求了,需要将输入报文进行处理拆分对应的参数,依靠Service对输入数据进行处理,使用函数生成符合要求的输出,并最终封装成xml报文返回。

POST接口接收XML报文

通常来说,在进行接口设计时思考问题是自顶向下的,即“接口可以接收并解析请求体→调用Service使用请求体中的数据运行业务逻辑→将得到的结果封装完成响应”。但实际的开发步骤是:根据需求明确请求体和响应体包括哪些属性以及这些属性的数据类型,构造请求类与响应类→新增Service类编写请求类的处理逻辑和响应类的生成逻辑→新增Controller类添加POST接口可以接收XML报文并在经过Service处理后返回XML报文。

导入相关依赖

处理xml报文需要Gradle导入jackson-dataformat-xml依赖,为保证项目的可迁移性与可复用性,放弃引入Lombok。

在Maven仓库(例如https://mvnrepository.com/)中搜索jackson-dataformat-xml依赖,选择Gradle,将下面这行复制进build.gradle的dependencies部分:

implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.15.2'

Jackson库会自动将XML元素映射到同名的Java属性。

创建Request类和Response类

根据请求报文,在Controller文件夹中新增ProjectNumberRequest类和ProjectNumberResponse类,分别如下:

ProjectNumberRequest.java

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;

public class ProjectNumberRequest {
private String name;
private String operate;
private String source;
private String status; //get方法
public String getName() {
return this.name;
}
public String getOperate() {
return this.operate;
}
public String getSource() {
return this.source;
}
public String getStatus() {
return this.status;
} //set方法
public void setName(String projectName) {
this.name = projectName;
}
public void setOperate(String projectOperate) {
this.operate = projectOperate;
}
public void setSource(String projectSource) {
this.source = projectSource;
}
public void setStatus(String projectStatus) {
this.status = projectStatus;
}
}

ProjectNumberResponse.java

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;

@JacksonXmlRootElement(localName = "response")
public class ProjectNumberResponse {
private String number;
private String status; //get方法
public String getNumber() {
return this.number;
}
public String getStatus() {
return this.status;
} //set方法
public void setNumber(String number) {
this.number = number;
}
public void setStatus(String projectStatus) {
this.status = projectStatus;
}
}

注意:诸如@JacksonXmlRootElement(localName = "response")的注解可以将XML的根节点重命名为response,如果不添加注解则XML文件根节点名称默认使用类名。

编写业务逻辑

在Service文件夹下新增CreateNumberService类,用于处理请求报文的请求体,并按照一定规则生成项目编码和项目状态这两个属性,将其转换为XML文件,组成响应报文的响应体。

CreateNumberService包括两部分,第一部分是response对象生成函数,用于创建响应体对象,第二部分是XML对象生成函数,用于将response对象封装成XML对象。

CreateNumberService.java

import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.springframework.stereotype.Service;
import studio.tsukistar.demo.Controller.ProjectNumberRequest;
import studio.tsukistar.demo.Controller.ProjectNumberResponse; import java.util.Objects;
@Service
public class CreateNumberService {
private static final String XML_HEAD = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"; public String createService(ProjectNumberRequest request) { //构建response对象
ProjectNumberResponse response = new ProjectNumberResponse();
response.setNumber( "AB000" );
response.setStatus(request.getStatus());
return javaBeanToXml (response);
} public static String javaBeanToXml(Object obj) { //将Object转换为xml形式
String xml= "";
if (Objects.isNull(obj)) {
return xml;
} try {
XmlMapper xmlMapper = new XmlMapper();
xml = xmlMapper.writeValueAsString(obj);
} catch (Exception e) {
return "";
} return XML_HEAD + xml;
}
}

编写控制器

在Controller文件夹下新增CreateNumberController类,设置请求体传入类型为XML格式,返回经过CreateNumberService处理请求体后得到的响应报文。

CreateNumberController.java

import jakarta.annotation.Resource;
import org.springframework.http.MediaType;
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 studio.tsukistar.demo.Service.CreateNumberService; @RestController
@RequestMapping("/api")
public class CreateNumberController {
@Resource
private CreateNumberService numberService; @PostMapping(value="/number", produces = MediaType.APPLICATION_XML_VALUE)
public String createNumber(@RequestBody ProjectNumberRequest request) { // 处理POST请求的代码
return numberService.createService(request);
}
}

运行测试

运行程序后,使用Postman向http://localhost:8000/api/number发送POST请求,在“Body”中选择“raw-XML”,填入请求体:

<?xml version="1.0" encoding="UTF-8" ?>
<request>
<name>测试</name>
<operate>01</operate>
<source>A</source>
<status>01</status>
</request>

点击“Send”可以得到接口的响应报文,如下图所示:

总结

相较于上次,这段时间新学习了POST接口的开发方式、项目分层、各层之间的交互等内容,对SpringBoot框架也有了更深入的了解(也许?希望不要误入歧途)。代码也一并传到了github仓库中,向前迈进了一大步。

本文多数开发知识来源于Bing AI,若有错误之处请各位dalao多多赐教,不胜感激!

参考文章

使用SpringBoot开发一个POST接口的更多相关文章

  1. 基于SpringBoot开发一个Restful服务,实现增删改查功能

    前言 在去年的时候,在各种渠道中略微的了解了SpringBoot,在开发web项目的时候是如何的方便.快捷.但是当时并没有认真的去学习下,毕竟感觉自己在Struts和SpringMVC都用得不太熟练. ...

  2. 开发一个登录接口(Mysql)

    分享一段代码,开发了一个登录接口: 使用Python开发,需要安装flask模块,使用pip intall flask 安装即可,这里使用的数据库是Mysql,所以导入了pymysql模块,代码如下: ...

  3. 利用MyEclipse开发一个webservice接口

    一直以来对于接口这个东西都很好奇,各种客户也一直在说那个什么什么数据我们提供给你们一个接口就好了,结果还是不是很明白.于是乎就有了下面的小故事,接下来我们就进入正文吧 ---大概可以分为这样的步骤 1 ...

  4. Python中如何开发一个注册接口小实例

    import flask from flask import request #想获取到请求参数的话,就得用这个 server = flask.Flask(__name__) #吧这个python文件 ...

  5. 利用MyEclipse开发一个调用webservice接口的程序

    上一篇文章我们已经学习了如何使用Java 工具MyEclipse开发一个webservice接口,那么接口开发好了如何调用?接下来我们就来解决这个问题. 1:首先随便创建一个Java project选 ...

  6. 【SpingBoot】 测试如何使用SpringBoot搭建一个简单后台1

    很久没写博客了,最近接到一个组内的测试开发任务是做一个使用SpringBoot 开发一个后台程序(还未完成),特写感想记录一下 1. 为什么选择SpringBoot ? 首先是目前很多公司的后台还是J ...

  7. Springboot整合elasticsearch以及接口开发

    Springboot整合elasticsearch以及接口开发 搭建elasticsearch集群 搭建过程略(我这里用的是elasticsearch5.5.2版本) 写入测试数据 新建索引book( ...

  8. 重学 Java 设计模式:实战外观模式「基于SpringBoot开发门面模式中间件,统一控制接口白名单场景」

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 你感受到的容易,一定有人为你承担不容易 这句话更像是描述生活的,许许多多的磕磕绊绊总 ...

  9. 使用electron开发一个h5的客户端应用创建http服务模拟后台接口mock

    使用electron开发一个h5的客户端应用创建http服务模拟后端接口mock 在上一篇<electron快速开始>里讲述了如何快速的开始一个electron的应用程序,既然electr ...

  10. SpringBoot开发mockserver及生成swagger接口文档

    通过springboot开发mock server,包含get及post接口,用于练习接口自动化及jmeter很方便 当然,也为后面jenkins持续集成做基础(开发push代码后  → jenkin ...

随机推荐

  1. 7.1 套接字(socket)

    套接字(socket)是计算机之间进行通信的一种技术,它允许不同主机上的进程之间进行数据交换.在Python中,我们可以使用socket模块来创建和使用套接字. 首先,我们需要导入socket模块: ...

  2. LeetCode 周赛 350(2023/06/18)01 背包变型题

    本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 和 [BaguTree Pro] 知识星球提问. 往期回顾:LeetCode 单周赛第 348 场 · 数位 DP ...

  3. Spring源码核心剖析

    前言 SpringAOP作为Spring最核心的能力之一,其重要性不言而喻.然后需要知道的是AOP并不只是Spring特有的功能,而是一种思想,一种通用的功能.而SpringAOP只是在AOP的基础上 ...

  4. FreeFileSync结合任务计划实现T级数据的全量备份和每日十几G数据的增量自动备份

    1. 背景 公司现有nas存储中有共计1.8T左右的文件数据(一般是pdf.excel.图片.压缩文件等等格式),因为nas无法做备份:担心后面nas出现故障造成数据丢失,现急需一个解决方案实现如下目 ...

  5. 行行AI人才直播第7期:奇计AI创始人左晟《AI时代的商业挑战和机遇》

    行行AI人才是博客园和顺顺智慧共同运营的AI行业人才全生命周期服务平台,是园子商业化努力的一个重要方向. 行行AI人才直播希望以直播的方式让大家更多了解AI行业的现状与未来可能的发展方向. 随着人工智 ...

  6. Unity的AssetPostprocessor之Model:深入解析与实用案例 2

    Unity AssetPostprocessor中Model相关函数的实际应用 Unity AssetPostprocessor是Unity引擎中的一个重要功能,它可以在导入资源时自动一些脚本,以便对 ...

  7. 【Python】Locust持续优化:InfluxDB与Grafana实现数据持久化与可视化分析

    前言 在进行性能测试时,我们需要对测试结果进行监控和分析,以便于及时发现问题并进行优化. Locust在内存中维护了一个时间序列数据结构,用于存储每个事件的统计信息. 这个数据结构允许我们在Chart ...

  8. 【Java 新的选择】,Solon v2.3.8 发布

    Solon 是什么开源项目? 一个,Java 新的生态型应用开发框架.它从零开始构建,有自己的标准规范与开放生态(历时五年,已有全球第二级别的生态规模).与其他框架相比,它解决了两个重要的痛点:启动慢 ...

  9. ubuntu 20.04 网络配置

    参考链接:ubuntu 20.04 网络配置 网络配置文件目录:/etc/netplan/ 配置实例 # 静态 network: version: 2 ethernets: ens33: addres ...

  10. 2021-4-14 Tabpage隐藏功能

    隐藏:只需要将tabpage的parent设置为空即可 this.tabPage1.Parent = null; 重新显示只需将parent重新设置成tabcontrol的子项 this.tabPag ...