springcloud微服务之间相互调用实战
任务一实现:使用脚手架生成deepexi-spring-cloud(服务消费者)、deepeximessage-spring-cloud(服务提供者)registerCenter(注册中心,这个没用脚手架生成)一 服务消费者,实现用户管理的CRUD,然后在添加用户时调用deepeximessage-spring-cloud发送一条欢迎信息。脚手架好像没有发现有生成快速生成xml、m...
任务一实现:
使用脚手架生成deepexi-spring-cloud(服务消费者)、deepeximessage-spring-cloud(服务提供者)
registerCenter(注册中心,这个没用脚手架生成)
一 服务消费者,实现用户管理的CRUD,然后在添加用户时调用deepeximessage-spring-cloud发送一条欢迎信息。脚手架好像没有发现有生成快速生成xml、mapper、entity的方法,
所以使用mybatis generator根据数据库表快速生成相应文件,需要根据实际情况修改内容.
表结构:create table user(
uid int primary key auto_increment,
uname varchar(200) comment '姓名',
pwd varchar(50) comment '密码',
addr varchar(100) comment '详细地址'
)
1 com.deepexi.domain.entity包下的User实体类:
package com.deepexi.domain.entity;
import lombok.Data;
@Data
public class User {
private Integer uid;
private String uname;
private String pwd;
private String addr;
}
2 com.deepexi.mapper包下的mapper接口:
package com.deepexi.mapper;
import com.deepexi.domain.entity.User;
import com.deepexi.domain.query.UserQuery;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface UserMapper {
/**
* @description :通过id删除用户
* @param uid :
* @return :int
*/
int deleteByPrimaryKey(@Param(value="uid") String uid);
/**
* @description :插入用户
* @param user :
* @return :int
*/
int insert(User user);
/**
* @description :条件查询
* @param userQuery :
* @return :java.util.List<com.deepexi.domain.entity.User>
*/
List<User> selectByUser(UserQuery userQuery);
/**
* @description :修改用户
* @param user :
* @return :int
*/
int update(User user);
}
3.下面是com.deepexi.service业务层接口UserService(对于里面的UserQuery类是用于查询的实体类对象,继承PaginationRequest,添加分页参数)
package com.deepexi.service;
import com.deepexi.domain.entity.User;
import com.deepexi.domain.query.UserQuery;
import java.util.List;
public interface UserService {
int deleteByPrimaryKey(String uid);
int insert(User user);
List<User> selectUser(UserQuery userQuery);
int update(User user);
}
4 com.deepexi.domain.query下的UserQuery实体类:
package com.deepexi.domain.query;
import lombok.Data;
@Data
public class UserQuery extends PaginationRequest {
private String uname;
private String pwd;
private String addr;
}
5 接着是com.deepexi.service.impl业务层接口UserService的实现类UserServiceImpl:
package com.deepexi.service.impl;
import com.deepexi.domain.entity.User;
import com.deepexi.domain.query.UserQuery;
import com.deepexi.mapper.UserMapper;
import com.deepexi.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired(required = false)
private UserMapper userMapper;
@Override
public int deleteByPrimaryKey(String uid) {
return userMapper.deleteByPrimaryKey(uid);
}
@Override
public int insert(User user) {
return userMapper.insert(user);
}
@Override
public List<User> selectUser(UserQuery userQuery) {
return userMapper.selectByUser(userQuery);
}
@Override
public int update(User user) {
return userMapper.update(user);
}
}
6下面是控制层代码com.deepexi.controller下的UserController:(类中使用了ResultVo返回请求内容,内容使用StatusEnum填充):
package com.deepexi.controller;
import com.alibaba.fastjson.JSONObject;
import com.deepexi.domain.entity.User;
import com.deepexi.domain.query.UserQuery;
import com.deepexi.domain.vo.ResultVo;
import com.deepexi.enums.StatusEnum;
import com.deepexi.remote.MessageRemote;
import com.deepexi.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@Api(value= "用户管理")
public class UserController {
private final Logger log= LoggerFactory.getLogger(UserController.class);
@Autowired
private UserService userService;
@Autowired
MessageRemote messageRemote;
@PostMapping(value= "/login")
@ApiOperation(value= "用户登录",notes= "条件查询是否存在用户")
public ResponseEntity login(@RequestBody UserQuery userQuery){
List<User> list= null;
try {
log.info("request to login: {}",JSONObject.toJSON(userQuery));
userQuery.setIndex(userQuery.getOffset());
userQuery.setSize(userQuery.getLimit());
list = userService.selectUser(userQuery);
} catch (Exception e) {
log.info("用户查询失败");
return ResponseEntity.ok().body(ResultVo.getInstance(StatusEnum.FAIL));
}
return ResponseEntity.ok().body(list);
}
@PostMapping(value= "/updateUser")
@ApiOperation(value= "修改用户",notes ="修改用户信息,包括修改密码")
public ResponseEntity updateUser(@RequestBody User user){
try {
log.info("request to update user info:{}", JSONObject.toJSON(user));
userService.update(user);
} catch (Exception e) {
log.info("修改用户信息错误");
return ResponseEntity.ok().body(ResultVo.getInstance(StatusEnum.UPDATEFAIL));
}
return ResponseEntity.ok().body(ResultVo.getInstance(StatusEnum.SUCCESS));
}
@PostMapping(value="/addUser")
@ApiOperation(value="添加用户",notes = "添加用户信息")
public ResponseEntity addUser(@RequestBody User user){
//调用远程服务,返回欢迎信息
String msg=messageRemote.registerInfo();
try {
log.info("request to add user info: {}", JSONObject.toJSON(user));
userService.insert(user);
} catch (Exception e) {
log.info("添加用户失败");
return ResponseEntity.ok().body(ResultVo.getInstance(StatusEnum.ADDFAIL));
}
return ResponseEntity.ok().body(msg);
}
@PostMapping(value="/deleteUser")
@ApiOperation(value="删除用户",notes = "根据uid删除用户")
public ResponseEntity deleteUser(@RequestParam("uid") String uid){
try {
log.info("request to delete user info:{}", uid);
userService.deleteByPrimaryKey(uid);
} catch (Exception e) {
log.info("删除用户失败");
return ResponseEntity.ok().body(ResultVo.getInstance(StatusEnum.DALETEFAIL));
}
return ResponseEntity.ok().body(ResultVo.getInstance(StatusEnum.SUCCESS));
}
}
7 ResultVo代码如下:用于控制层返回对象
package com.deepexi.domain.vo;
import com.deepexi.enums.StatusEnum;
import lombok.Data;
@Data
public class ResultVo{
private String code;
private String msg;
public static ResultVo getInstance(StatusEnum statusEnum){
ResultVo resultVo=new ResultVo();
resultVo.setCode(statusEnum.getCode());
resultVo.setMsg(statusEnum.getMsg());
return resultVo;
}
}
8 StatusEnum代码如下:定义返回状态内容
package com.deepexi.enums;
public enum StatusEnum {
SUCCESS("200","请求成功"),
FAIL("400","请求失败"),
UPDATEFAIL("400","修改失败"),
DALETEFAIL("400","删除失败"),
ADDFAIL("400","添加失败");
private String code;
private String msg;
StatusEnum(String code, String msg) {
this.code = code;
this.msg = msg;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
9 远程服务调用:在com.deepexi.remote下创建MessageRemote:
package com.deepexi.remote;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@FeignClient(name="deepeximessage-spring-cloud")
public interface MessageRemote {
@RequestMapping(value="/alertInfo",method = RequestMethod.POST)
String registerInfo();
}
10 启动类:添加@EnableDiscoveryClient服务注册,@EnableFeignClients开启feign调用:
package com.deepexi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class StartupApplication {
public static void main(String[] args) {
SpringApplication.run(StartupApplication.class, args);
}
}
11 配置文件: 指定应用名称,注册中心地址
spring:
application:
name: deepexi-spring-cloud
profiles:
active: local
datasource:
driver-class-name: com.mysql.jdbc.Driver
druid:
web-stat-filter:
enabled: true
stat-view-servlet:
enabled: true
login-username: root
login-password: root
thymeleaf:
cache: false
redis:
timeout: 1000
swagger:
base-package: com.deepexi.controller
info:
title: deepexi-spring-cloud
server:
error:
include-stacktrace: always
include-exception: true
logging:
file: 'logs/${spring.application.name}.log'
management:
server:
port: 8081
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8761/eureka/
mybatis:
mapper-locations: 'classpath:mapper/*.xml'
feign:
hystrix:
enabled: true
shiro:
web:
mode: stateless
filter-chain-definition:
authc:
- /v1/**
anon:
- /**
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC
logging:
level:
com.deepexi.mapper: debug
server:
port: 8060
12 映射文件resoures/mapper下的UserMapper.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.deepexi.mapper.UserMapper">
<resultMap id="BaseResultMap" type="com.deepexi.domain.entity.User">
<id column="uid" jdbcType="INTEGER" property="uid" />
<result column="uname" jdbcType="VARCHAR" property="uname" />
<result column="pwd" jdbcType="VARCHAR" property="pwd" />
<result column="addr" jdbcType="VARCHAR" property="addr" />
</resultMap>
<sql id="Base_Column_List">
uid, uname, pwd, addr
</sql>
<!-- 分页条件的拼接 -->
<sql id="pageSql">
<if test="index != null and size != null">
limit ${index},${size}
</if>
</sql>
<select id="selectByUser" parameterType="com.deepexi.domain.entity.User" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user
<where>
<if test=" uname != null and uname != '' ">
and uname=#{uname,jdbcType=VARCHAR}
</if>
<if test=" pwd != null and pwd != '' ">
and pwd=#{pwd,jdbcType=VARCHAR}
</if>
<if test=" addr != null and addr != '' ">
and addr=#{addr,jdbcType=VARCHAR}
</if>
</where>
<include refid="pageSql"/>
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.String">
delete from user
where uid = #{uid,jdbcType=VARCHAR}
</delete>
<insert id="insert" parameterType="com.deepexi.domain.entity.User">
insert into user (uid, uname, pwd,
addr)
values (#{uid,jdbcType=INTEGER}, #{uname,jdbcType=VARCHAR}, #{pwd,jdbcType=VARCHAR},
#{addr,jdbcType=VARCHAR})
</insert>
<update id="update" parameterType="com.deepexi.domain.entity.User">
update user
<set>
<if test=" uname != null and uname != '' ">
uname = #{uname,jdbcType=VARCHAR},
</if>
<if test=" pwd != null and pwd != '' ">
pwd = #{pwd,jdbcType=VARCHAR},
</if>
<if test=" addr != null and addr != '' ">
addr = #{addr,jdbcType=VARCHAR},
</if>
</set>
<if test=" uid != null and uid !='' ">
where uid=#{uid,jdbcType=VARCHAR}
</if>
</update>
</mapper>
13创建完后项目结构如下:
14 开启swagger界面测试接口:
15 添加用户时调用Message服务的接口:(返回的内容是Message应用服务提供内容)
二 服务提供者deepeximessage-spring-cloud
1 表结构:
create table message(
id int primary key auto_increment,
msg varchar(100)
)
2 实体类com.deepexi.domain.entity下Message:
package com.deepexi.domain.entity;
import lombok.Data;
@Data
public class Message {
private Integer id;
private String msg;
}
3 Mapper层接口MessageMapper:
package com.deepexi.mapper;
import com.deepexi.domain.entity.Message;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface MessageMapper {
int deleteByPrimaryKey(@Param(value="id") String id);
int insert(Message message);
List<Message> selectByMessage(Message message);
int update(Message message);
}
4 业务层接口MessageService:
package com.deepexi.service;
import com.deepexi.domain.entity.Message;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface MessageService {
int deleteByPrimaryKey( String id);
int insert(Message message);
List<Message> selectByMessage(Message message);
int update(Message message);
}
5 业务层实现MessageServiceImpl:
package com.deepexi.service.impl;
import com.deepexi.domain.entity.Message;
import com.deepexi.mapper.MessageMapper;
import com.deepexi.service.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class MessageServiceImpl implements MessageService {
@Autowired(required = false)
MessageMapper messageMapper;
@Override
public int deleteByPrimaryKey(String id) {
return messageMapper.deleteByPrimaryKey(id);
}
@Override
public int insert(Message message) {
return messageMapper.insert(message);
}
@Override
public List<Message> selectByMessage(Message message) {
return messageMapper.selectByMessage(message);
}
@Override
public int update(Message message) {
return messageMapper.update(message);
}
}
6 控制层代码MessageController:
package com.deepexi.controller;
import com.alibaba.fastjson.JSONObject;
import com.deepexi.domain.entity.Message;
import com.deepexi.domain.vo.ResultVo;
import com.deepexi.enums.StatusEnum;
import com.deepexi.service.MessageService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@Api(value="信息管理")
public class MessageController {
private final Logger log= LoggerFactory.getLogger(MessageController.class);
@Autowired
private MessageService messageService;
@PostMapping(value="/addMessage")
@ApiOperation(value="信息添加")
public ResponseEntity add(@RequestBody Message message){
try {
log.info("request add message: {}", JSONObject.toJSON(message));
messageService.insert(message);
} catch (Exception e) {
log.info("添加信息失败");
return ResponseEntity.ok().body(ResultVo.getInstance(StatusEnum.ADDFAIL));
}
return ResponseEntity.ok().body(ResultVo.getInstance(StatusEnum.SUCCESS));
}
@PostMapping(value="/updateMessage")
@ApiOperation(value="修改信息")
public ResponseEntity updateMessage(@RequestBody Message message){
try {
log.info("request update message: {}",JSONObject.toJSON(message));
messageService.update(message);
} catch (Exception e) {
log.info("修改信息失败");
return ResponseEntity.ok().body(ResultVo.getInstance(StatusEnum.UPDATEFAIL));
}
return ResponseEntity.ok().body(ResultVo.getInstance(StatusEnum.SUCCESS));
}
@PostMapping(value="/selectMessage")
@ApiOperation(value="查询信息")
public ResponseEntity selectMessage(@RequestBody Message message){
List<Message> list=null;
try {
log.info("request select message: {}",JSONObject.toJSON(message));
list=messageService.selectByMessage(message);
} catch (Exception e) {
log.info("查询获取信息失败");
return ResponseEntity.ok().body(ResultVo.getInstance(StatusEnum.FAIL));
}
return ResponseEntity.ok().body(list);
}
@PostMapping(value="/deleteMessage")
@ApiOperation(value="删除信息",notes = "根据id删除信息")
public ResponseEntity deleteMessage(@RequestParam(value="id") String id){
try {
log.info("request delete message: {}",id);
messageService.deleteByPrimaryKey(id);
} catch (Exception e) {
log.info("删除信息失败");
return ResponseEntity.ok().body(ResultVo.getInstance(StatusEnum.DALETEFAIL));
}
return ResponseEntity.ok().body(ResultVo.getInstance(StatusEnum.SUCCESS));
}
@PostMapping(value="/alertInfo")
@ApiOperation(value="返回一个提示信息",notes = "用于其他服务调用")
public ResponseEntity registerInfo(){
String msg=null;
//返回所有消息列表的第一条内容返回给其他服务
List<Message> list=messageService.selectByMessage(null);
if(list.size()>0){
for (Message item:list){
msg=item.getMsg();
}
}
return ResponseEntity.ok().body(msg);
}
}
7 配置文件、启动类与上面服务相似,不同是应用名称、端口号配置
8 配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.deepexi.mapper.MessageMapper">
<resultMap id="BaseResultMap" type="com.deepexi.domain.entity.Message">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="msg" jdbcType="VARCHAR" property="msg" />
</resultMap>
<sql id="Base_Column_List">
id, msg
</sql>
<select id="selectByMessage" parameterType="com.deepexi.domain.entity.Message" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from message
<where>
<if test=" id!=null">
and id= #{id,jdbcType=VARCHAR} order by id desc
</if>
</where>
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.String">
delete from message
where id = #{id,jdbcType=VARCHAR}
</delete>
<insert id="insert" parameterType="com.deepexi.domain.entity.Message">
insert into message (id, msg)
values (#{id,jdbcType=INTEGER}, #{msg,jdbcType=VARCHAR})
</insert>
<update id="update" parameterType="com.deepexi.domain.entity.Message">
update message
<set>
<if test="msg != null">
msg=#{msg,jdbcType=VARCHAR},
</if>
</set>
<if test="id != null ">
where id = #{id,jdbcType=VARCHAR}
</if>
</update>
</mapper>
9 开启wagger2界面:
10 测试修改信息接口:
11 测试返回提示信息接口,给消费者调用:
三 注册中心
注册中心没有用脚手架生成,采用简单springboot项目导入依赖jar包,步骤如下:
1 pom文件:
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<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 application.properties配置文件:
spring.application.name=springcloud-register-center
server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.service-url.defaultZone=http://127.0.0.1:8761/eureka/
3 启动类:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
4 启动后,分别启动上面两个应用,结果如下:(有两个实例)
更多推荐
所有评论(0)