前言
本文是一个入门级Restful风格微服务的开发流程,是本人的学习笔记,通过对开发流程的整体叙述,记录了此次入门DEMO的实现过程。
RESTFUL 风格微服务 VS 传统Web Service 服务(RPC风格)
两者的简单对比:
与传统Web Service 服务(RPC风格)采用的SOAP协议(Simple Object Access protocol,简单对象访问协议)不同,RESTFUL 风格微服务使用的传输协议为HTTP协议。HTTP协议在网络层模型中在最高一级的位置,因此在性能上略低于Web Service的SOAP协议。RESTFUL服务使用统一的接口URL,使用GET、POST、PUT、DELETE等操作方法,来处理资源。
RPC风格服务使用xml参数作为数据交换的参数,重量级,此外由于客户端需要有服务端的接口,因此它也被限定用在同构应用中;
RESTFUL 风格服务使用Json做数据交换,轻量级,只需要解析Json对象,因此它能够在异构应用中运用;
关键词:RESTFUL;微服务;
项目搭建
使用Maven构建项目,Spring Boot框架进行开发。以一个简单的数据库表作数据源为例,开发一个RESTFUL 风格微服务。
依赖包导入
只需要一般SSM框架依赖,数据库连接驱动即可:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</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>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.10</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
数据库连接
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: 'jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8'
username: root
password: 123456
开发实例
项目整体概览:
POJO 、Mapper
接口与映射文件xml由反向工程自动创建。根据数据表创建实体类Items,字段如下,Get、Set方法、构造器由于篇幅原因省略。
public class Items{
private Integer id;
private String name;
private Integer price;
private String pic;
private Date createtime;
private String detail;
}
PespBean:用于响应请求结果的返回。Get、Set方法这里篇幅原因省略。同时,将这个类的构造器设为私有,暴露静态方法返回对应的实例。
public class RespBean {
private Integer code;
private String msg;
private Object data;
private RespBean(Integer code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
private RespBean(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public static RespBean success(Integer code, String msg) {
return new RespBean(code,msg);
}
public static RespBean success(Integer code, String msg,Object data) {
return new RespBean(code,msg,data);
}
public static RespBean error(Integer code, String msg) {
return new RespBean(code,msg);
}
public static RespBean error(Integer code, String msg,Object data) {
return new RespBean(code,msg,data);
}
}
Service
1.interface
简单的CRUD操作:增加(Create)、读取查询(Retrieve)、更新(Update)和删除(Delete)。
public interface ItemService {
int deleteByPrimaryKey(Integer id);
int insert(Items record);
Items selectByPrimaryKey(Integer id);
int updateByPrimaryKey(Items record);
List<Items> selectAllItems();
}
2.interfaceImpl
对上面的接口进行实现
@Service
public class ItemServiceImpl implements ItemService {
@Autowired
private ItemsMapper mapper;
@Override
public int deleteByPrimaryKey(Integer id) {
return mapper.deleteByPrimaryKey(id);
}
@Override
public int insert(Items record) {
return mapper.insert(record);
}
@Override
public Items selectByPrimaryKey(Integer id) {
return mapper.selectByPrimaryKey(id);
}
@Override
public int updateByPrimaryKey(Items record) {
return mapper.updateByPrimaryKey(record);
}
@Override
public List<Items> selectAllItems() {
return mapper.selectByExample(new ItemsExample());
}
}
Utils
涉及到日期的参数使用格式转换器:
@Configuration
public class DateConverter implements Converter<String, Date> {
private SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
@Override
public Date convert(String time) {
try {
return format.parse(time);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
Controller
注解:
@RestController:等同于@Controller + @ResponseBody,返回Json对象格式数据。
@Autowired:注入接口
@RequestMapping:请求映射路径
@PathVariable:路径传参
@RequestBody:请求参数为对象
@RestController
public class ItemsController {
@Autowired
private ItemService service;
@RequestMapping(value = {"/selectAllItems"},method = RequestMethod.GET)//查询
public List<Items> selectAllItems() {
return service.seleceAllItems();
}
@RequestMapping(value = {"/deleteByPrimaryKey/{id}"},method = RequestMethod.DELETE)//删除
public RespBean deleteByPrimaryKey(@PathVariable Integer id) {
try {
service.deleteByPrimaryKey(id);
return RespBean.success(200,"删除成功");
} catch (Exception e) {
e.printStackTrace();
return RespBean.success(500,"删除失败");
}
}
@RequestMapping(value = {"/insert"},method = RequestMethod.POST)//创建
public RespBean insert(@RequestBody Items items) {
try {
System.out.println(items.toString());
service.insert(items);
return RespBean.success(200,"添加成功",items);
} catch (Exception e) {
e.printStackTrace();
return RespBean.success(500,"添加失败");
}
}
@RequestMapping(value = {"/selectByPrimaryKey/{id}"},method = RequestMethod.GET)//查询
public Items selectByPrimaryKey(@PathVariable Integer id) {
return service.selectByPrimaryKey(id);
}
@RequestMapping(value = {"/updateByPrimaryKey"},method = RequestMethod.PUT)//修改
public RespBean updateByPrimaryKey(@RequestBody Items items) {
try {
System.out.println(items.toString());
service.insert(items);
return RespBean.success(200,"修改成功",items);
} catch (Exception e) {
e.printStackTrace();
return RespBean.success(500,"修改失败");
}
}
}
PostMan测试
查找所有商品应答的Json数据:localhost:8080/selectAllItems
插入数据构建Json对象:localhost:8080/insert
插入数据结果返回:
其他就不再一一演示。