java 庖丁解牛api_Java Restful API Best Practices
API 是后端工作的主要工作之一, 开发难度低, 但是比较繁杂。 经过几个月的学习,总结一下自己对接口开发的一些套路。
接口
首先,需要熟悉业务,熟悉数据库表结构,列出接口与表的对应关系。
确定接口需求与数据表
如某单位接口界面与表需求:
线路统计
界面需要展示的数据 <==> 数据表
按照这种关系, 制作一个对应的Excel表,将初始需求确定下来,以便后面快速进行开发。
后台项目结构
user
---> controller ---> service ---> dao
---> cache ---> 返回
---> mapper ---> DB ---> 返回
---> 管道 ---> 数据处理 ---> 返回
按照这种结构可以更好地扩展,
dao层负责数据获取与接受,方式不定,可能从DB, Cache, MQ之类的结构获取或者提交数据。
pojo 分为
dto 数据传输对象, 当model数据需要处理时返回使用
vo 最后返回给前端的对象封装
model 从DB直接出来的数据,未经过逻辑加工
项目构建
结构定下来后, 直接使用
spring initializr -- https://start.spring.io/
加入swagger-ui,交代清楚接口事宜。
package com.loyotech.bigscreenbackend;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* @Auther:chalide
* @Date:2018/8/30 11:45
* @Description:
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api(){
return new Docket(DocumentationType.SWAGGER_2)
.groupName("loyotech")
.apiInfo(apiInfo())
.select()
.apis(SwaggerConfig.basePackage("com.loyotech.bigscreenbackend"))
.paths(PathSelectors.regex("/*.*"))
.build();
}
/**
* Predicate that matches RequestHandler with given base package name for the class of the handler method.
* This predicate includes all request handlers matching the provided basePackage
*
* @param basePackage - base package of the classes
* @return this
*/
public static Predicate basePackage(final String basePackage) {
return input -> declaringClass(input).transform(handlerPackage(basePackage)).or(true);
}
/**
* 处理包路径配置规则,支持多路径扫描匹配以逗号隔开
*
* @param basePackage 扫描包路径
* @return Function
*/
private static Function, Boolean> handlerPackage(final String basePackage) {
return input -> {
for (String strPackage : basePackage.split(",")) {
boolean isMatch = input.getPackage().getName().startsWith(strPackage);
if (isMatch) {
return true;
}
}
return false;
};
}
/**
* @param input RequestHandler
* @return Optional
*/
private static Optional extends Class>> declaringClass(RequestHandler input) {
return Optional.fromNullable(input.declaringClass());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
//标题
.title("Demo-Api")
//联系人
.contact(new Contact("", "", ""))
//版本号
.version("1.0")
//描述
.description("Demo-api")
.build();
}
}
引入swagger-ui,减少交互成本
环境
上下文环境在这里指的就是Spring容器上下文,也就是在环境中定义一些对象,存储进去。
添加spring 上下文环境, spring-dao, spring-service, spring-web, web.xml
或者是使用Java Config类去定义上下文环境(推荐)。
其他环境,mybatis-config.xml, logback.xml
使用多环境配置上下文,减少因为环境变动的文件更改
当部署的时候只需要在命令行中调用对应的环境
java -jar xxx.jar --spring.profiles.active=test
这样就可以启动那个对应环境的配置
相似的,下面是会根据对应的关系启用对应的properties/yaml文件
启用对应的properties
开发流程
user
---> controller ---> service ---> dao
---> cache ---> 返回
---> mapper ---> DB ---> 返回
---> 管道 ---> 数据处理 ---> 返回
规则1.所有的类都必须有接口和实现,以便后期扩展。
规则2.所有的单条接口流程命名一致,如有其他业务则另外扩展业务类
规则3.写上业务注释,使用IDEA全局搜索辅助查找需求
规则4.所有传参统一使用Map,所有返参统一使用Object
规则5.一切都往规则靠拢,不要魔法数,命名表达意思...
以上是为了开发时可以更好利用搜索,统一命名可能不太妥当,所以如有其他业务则直接扩展业务类,重新定义业务方法名。
最外层开始 -->
@SpringBootApplication
@ComponentScan
@EnableAutoConfiguration
@EnableSwagger2
@EnableCaching
public class BigScreenBackendApplication(){}
Controller
@RestController
@Api("Ice-Module-Api")
@Log
public class IceModuleController implements IceModuleRemoteApi {
@Autowired
IceModuleService iceModuleService;
@Override
public Object selectIceMonitorDeviceCountEveryProvince(HttpServletRequest request, HttpServletResponse response) {
// 获取传输参数, 删除无效参数, 加上分页逻辑.....
Map parameterMap = MapUtil.getParameterMap(request);
log.info("方法-selectIceMonitorDeviceCountEveryProvince 参数-" + parameterMap.toString());
return iceModuleService.selectIceMonitorDeviceCountEveryProvince(parameterMap);
}
}
Service
@Service
@Transactional
@Log
public class IceModuleServiceImpl implements IceModuleService {
// 有可能会用到redisTemplate, 如果没有使用redis,
// 则这个对象为null, 使用时在最外层做一下空指针判定
@Autowired(required = false)
RedisTemplate redisTemplate;
@Autowired
IceModuleDao iceModuleDao;
// #TODO 截至编码位置, 利用TODO来标示任务项,可快速定位开发位置
@Override
public Object selectIceMonitorDeviceCountEveryProvince(Map paramterMap) {
List recCompanies = Arrays.asList("南网超高压", "广东电网", "广西电网", "云南电网", "贵州电网");
List iceMonitorDeviceCounts = iceModuleDao.selectIceMonitorDeviceCountEveryProvince(paramterMap);
List result = new LinkedList<>();
// 初始化数据
recCompanies.stream().distinct().forEach(
recCompany -> {
result.add(new IceMonitorDeviceCount(){{
setRecCompany(recCompany);
}});
}
);
result.stream().forEach(iceMonitorDeviceCount -> {
for (IceMonitorDeviceCount data : iceMonitorDeviceCounts) {
if (iceMonitorDeviceCount.getRecCompany().equalsIgnoreCase(data.getRecCompany())) {
iceMonitorDeviceCount.setCount(data.getCount());
}
}
});
return prepareGoodResult(result);
}
}
Dao
@Repository
public class IceModuleDaoImpl implements IceModuleDao {
@Autowired
IceModuleMapper iceModuleMapper;
@Override
@Cacheable(value = "demo", key = "'IMDC:' + #parameterMap.get(id)")
public List selectIceMonitorDeviceCountEveryProvince(Map parameterMap) {
List result = iceModuleMapper.selectIceMonitorDeviceCountEveryProvince(parameterMap);
return result;
}
}
Mapper
@Mapper
@Repository
public interface IceModuleMapper {
List selectIceMonitorDeviceCountEveryProvince(Map parameterMap);
}
IceModuleMapper.xml
SELECT COUNT(DISTINCT BSID) AS COUNT, COMPANY
FROM ICE_MONITOR_DATA
GROUP BY REC_COMPANY
以上,构建了最主要的API主要的轮廓,还可以往上添加很多其他的内容,如:
Servlet, Listener, Filter, Bean, ApplicationContext, CronTask, InitRunner, Exception, Cache....
这些这里暂且不做说明
java 庖丁解牛api_Java Restful API Best Practices相关推荐
- java logging api_Java Logging API - Tutorial
1.2. 创建一个logger 包 java.util.logging提供了日志的功能,可以使用类似于下面的代码来创建一个logger: import java.util.logging.Logger ...
- java+JBroFuzz对restful api进行fuzz测试
@本文原创,转载请注明 0X00: 序言 fuzz测试作为安全测试的一个基本策略,被越来越多的引入整个测试过程,来避免一些简单的可能引发的安全问题. 如何将fuzzing测试引入软件自动化测试过程是本 ...
- java 有多少api_Java常用API(二)
API 正则表达式 正则表达式的概念 正则表达式(英语:Regular Expression,在代码中常简写为regex) 正则表达式是一个字符串,使用单个字符串来描述.用来定义匹配规则,匹配一系列符 ...
- java sound api_Java Sound API
Java Sound API是javaSE平台提供底层的(low-level)处理声音接口. 例外,java也提供了简单的实用的高层媒体接口(higher-level) - JMF(Java Medi ...
- java核心api_Java核心API需要掌握的程度..你做到了多少??
评论 19 楼 lovelh 2010-09-10 编程思想啊...... 18 楼 xiang.beyond 2010-09-08 A_Jane 写道 把API烂熟于心又如何?难道一辈子去做程序员? ...
- java 庖丁解牛api_Java 微信支付 APIv3 平台证书的命令行下载工具
Certificate Downloader Certificate Downloader 是 Java 微信支付 APIv3 平台证书的命令行下载工具.该工具可从 https://api.mch.w ...
- java robot api_java机器人API学习笔记
robocode 部分 API 中文参考 ahead 向前 public void ahead(double distance) Immediately moves your robot ahead ...
- nodejs+java+restful_nodejs实现restful API
更新: 最新的源码和使用说明放到了github上 点击跳转 本文的重点在于restful接口的设计与实现,使用到了express和monogoose. 点击查看express教程 点击查看monogo ...
- java核心api_java核心API
---恢复内容开始--- Javase01 day01 关于String: String是不可变对象,java.lang.String使用了final修饰,不能被继承: 字符串一旦创建永远无法改变,但 ...
最新文章
- 柴油发电机组常见故障及处理方法
- boost::hana::div用法的测试程序
- [转载]:合并两个已排序好的int数组,并排序返回c#实现
- java 的HashMap底层数据结构
- java8根据某个id删选_Java 8可选:如何使用它
- java面试-Java并发编程(六)——线程间的通信
- 使用ffmpeg捕获USB外部摄像头视频流
- Vbs程序批量修改防火墙路由
- 推荐 | 自然语言处理、计算机视觉等机器学习实战项目练手平台
- HTML+JS好例子集锦
- iphone投屏老是显示无法连接服务器,iphone怎么投屏到电视 升级iOS11后为什么投屏会失败...
- PCB设计经验(1)
- Excel字符串拼接
- python终端小游戏_我用Python玩小游戏“跳一跳”,瞬间称霸了朋友圈!
- 写给那些常年战痘的痘友们~~~
- 微信订阅号简易开发——小白攻略图文版
- 大学英语综合教程三 Unit 6 课文内容英译中 中英翻译
- 关于常用的Lambda(拉姆达)表达式
- centos8 内核升级
- 更新win11后vmware出错,VMware Workstation 不可恢复错误: (vcpu-0)
热门文章
- FCGF-基于稀疏全卷积网络的点云特征描述子提取(ICCV2019)
- 一文详解三维重建之定位定姿算法
- 图像质量量化评估标准综述
- 机器人抓取领域相关数据集
- RDKit:基于RECAP生成片段
- 局域网连接其他机器命令_弱电工程师必备技能,PING命令使用方法大全
- GLIBC 升级安装与 SCL 知识盲区
- Seaborn使用regplot函数可视化散点图并添加回归曲线以及回归线对应的置信区间(Scatter plot with regression line)
- R语言使用ggplot2包使用geom_dotplot函数绘制分组点图(改变图例位置)实战(dot plot)
- R语言PCA主成分分析(Principle Component Analysis)实战2