上次,我们搭建了一个可以获取到商品信息的SpringBoot微服务。这次,我们仿照上次的代码写一个订单的微服务,让这两个服务之间进行通信。
商品微服务链接:https://blog.csdn.net/weixin_43358075/article/details/89003160
这里不再做过多的赘述。搭建一个简单的Maven项目,引入SpringBoot父容器,添加Web依赖。
配置端口,写好启动类。
需要注意的一点是配置启动端口号的时候,应与item微服务的端口号不同。
上次商品微服务我们使用了8080端口,这次我们使用8081端口。
最终项目的整体结构如下:
1. Bean层代码
现实生活中,我们通常一个购物单上会有很多的商品。因此我们的订单微服务需要与商品为服务进行通信,这次我们把上次商品Bean拿来直接使用。
package com.example.service.orderservice.bean;
public class Item {
private int id;
private String name;
private String desp;
private String pic;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesp() {
return desp;
}
public void setDesp(String desp) {
this.desp = desp;
}
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic;
}
public Item() {
}
public Item(int id, String name, String desp, String pic) {
this.id = id;
this.name = name;
this.desp = desp;
this.pic = pic;
}
@Override
public String toString() {
return "Item{" +
"id=" + id +
", name='" + name + '\'' +
", desp='" + desp + '\'' +
", pic='" + pic + '\'' +
'}';
}
}
package com.example.service.orderservice.bean;
import java.util.Date;
import java.util.List;
public class Order {
private String id;
//订单创建时间
private Date createDate;
//订单中商品列表
private List<Item> items;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
public Order() {
}
public Order(String id, Date createDate, List<Item> items) {
this.id = id;
this.createDate = createDate;
this.items = items;
}
@Override
public String toString() {
return "Order{" +
"id='" + id + '\'' +
", createDate=" + createDate +
", items=" + items +
'}';
}
}
2. Service层代码
这次我们还是先按照之前的思路,利用static关键字创建假数据。由于要和商品微服务,我们这里需要注入RestTemplate,从而和商品为服务之间进行通信。
首先我们得先配置一个RestTemplate的Bean实例。配置这个Bean实例我们可以再启动类里完成。
package com.example.service.orderservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class OrderServiceApplication {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
接着我们需要创建ItemService类,调用RestTemplate获取数据。
package com.example.service.orderservice.service;
import com.example.service.orderservice.bean.Item;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class ItemService {
@Autowired
private RestTemplate restTemplate;
Item queryItemById(int id){
return restTemplate.getForObject("http://localhost:8080/item/" + id, Item.class);
}
}
最后,我们完成订单服务的实现。
package com.example.service.orderservice.service;
import com.example.service.orderservice.bean.Item;
import com.example.service.orderservice.bean.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
public class OrderService {
@Autowired
private ItemService itemService;
private static final Map<String, Order> MAP = new HashMap<>();
static {
Item item1 = new Item();
Item item2 = new Item();
item1.setId(1);
item2.setId(2);
List<Item> itemList = new ArrayList<>();
itemList.add(item1);
itemList.add(item2);
Order order = new Order();
order.setId("123456789");
order.setCreateDate(new Date());
order.setItems(itemList);
MAP.put(order.getId(),order);
}
public Order queryOrderById(String id){
Order order = MAP.get(id);
List<Item> items = new ArrayList<>();
for (Item item : order.getItems()) {
//调用订单微服务,重新设置商品数据
Item temp = itemService.queryItemById(item.getId());
items.add(temp);
}
order.setItems(items);
return order;
}
}
RestTemplate的主要作用是模仿浏览器对数据进行请求,这一点和使用JDK原生的URLConnection、Apache的Http Client、Netty的异步HTTP Client很相似。 使用RestTemplate我们需要指定请求地址,即URL,同时我们要规定请求到的数据的类型,这里用到了类反射机制。
3. Controller层代码
package com.example.service.orderservice.controller;
import com.example.service.orderservice.bean.Order;
import com.example.service.orderservice.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping("/order/{id}")
public Order queryOrderById(@PathVariable("id") String id){
return orderService.queryOrderById(id);
}
}
最后我们分别启动商品微服务和订单微服务,使用123456789这一订单号检验我们订单微服务是否搭建成功,最终效果如下:
写到这,我们发现,这样调用一个服务会产生很多问题,比如服务的地址进行迁移。因此,我们需要一个服务注册中心帮我们管理这些服务。下次将会写如何创建Eureka服务注册中心。