SpringBoot+SpringCloud微服务之好友业务实现【Feign实现服务之间的调用】

前期准备

创建一个微服务模块,导入pom依赖,添加配置文件

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.pure</groupId>
            <artifactId>pure_common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>


eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:7878/eureka/
  instance:
    prefer-ip-address: true #是为了在线上时模块之间能够跨域访问
jwt:
  config:
    key:  #这是盐

好友微服务的实现前提是要登陆验证
添加拦截器【自己写】
在这里插入图片描述
JwtInterceptor示例代码:

//Jwt拦截器,将公共代码写在这里
//SpringMVC配置有哪有些
//主键扫描创建实体类
//开启MVC注解支持
//配置视图解析器
//释放静态资源
@Component
public class JwtInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtUtil jwtUtil;

    public boolean preHandle ( HttpServletRequest request,HttpServletResponse response,Object handler )
            throws Exception {
        System.out.println ( "经过了拦截器" );

        //无论如何都放行,具体能不能操作还是在具体的操作中去判断
        //拦截器只负责把有请求头的token进行解析验证
        String header = request.getHeader ( "Authorization" );

        if (header != null && !"".equals ( header )) {
            //如果包含有头信息Authorization,就对其进行解析
            if (header.startsWith ( "Bearer " )) {//是以Bearer开头得到token
                String token = header.substring ( 7 );

                try {
                    Claims claims = jwtUtil.parseJWT ( token );
                    String roles = (String) claims.get ( "roles" );
                    //这是管理员的权限判断
                    if (roles != null && roles.equals ( "admin" )) {
                        request.setAttribute ( "claims_admin",claims );
                    }
                    //普通用户的判断
                    if (roles != null && roles.equals ( "user" )) {
                        request.setAttribute ( "claims_user",claims );
                    }
                } catch (Exception e) {
                    throw new RuntimeException ( );
                }
            }
        }
        return true;
    }

InterceptorConfig示例代码

@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {

    @Autowired
    private JwtInterceptor jwtInterceptor;

    //注册拦截器,要声名拦截器对象和拦截的请求
    protected void addInterceptors ( InterceptorRegistry registry ) {
        registry.addInterceptor ( jwtInterceptor )
                .addPathPatterns ( "/**" )
                .excludePathPatterns ( "/**/login/**" );
    }

}

启动类配置:
需要用Feign去调用其他模块的服务,在启动类上添加相关注解,需要获取当前用户的userId,也需要将JwtUtils注入到Bean

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableEurekaClient
public class FriendApplication {
    public static void main ( String[] args ) {
        SpringApplication.run ( FriendApplication.class,args );
    }

    @Bean
    public JwtUtil jwtUtil () {
        return new JwtUtil ( );
    }
}

好友微服务业务分析

首先设想几种情况
1、当前用户A喜欢用户B,B不喜欢A
2、当前用户A不喜欢用户B,B喜欢A
2、用户A和用户B相互喜欢
4、用户A不喜欢用户B,B也不喜欢A
5、喜欢之后,A和B粉丝数,关注数也要随着更新
还有另外两种种情况
1、A把B拉入黑名单,或者B把A拉入黑名单
2、删除好友,单向双向删除

全部的情况也就这几种
那我们就得去创建数据库了
好友,一个非好友
好友表字段分别为,userId、friendId、isLike【喜欢为1,不喜欢为0】
非好友表字段就存userId、friendId

A把B拉入黑名单,或者B把A拉入黑名单也有单向,和双向拉黑
那么我们需要联合主键去在数据库中判断
userIdfriendId,好友表和非好友表

#############################
具体怎么判断,我的想法是这样的
1、如果A喜欢B,A的isLike加一 【在代码里,要注意userId和friendId的前后顺序,她们是联合主键】
2、A喜欢B,B不喜欢A,B的isLike为0,A的isLike为1【注意,是联合主键】
3、两个都互相不喜欢,各自的isLike都为0
:这里的操作要在用户表中更新粉丝数和关注数,加一操作

那么删除好友和拉黑怎么做呢
A拉黑B,以A为主键在非好友表中保存A的userId和B的userId
反之B也一样
但是,删除之后,各自的用户表中,粉丝数和关注数要执行减一操作【在公司的实际开发中可不是真删除】

代码实现

我们需要通过 Feign去调用User模块服务
1、在需要调用其他服务的启动类上加上@EnableFeignClients注解
2、在服务调用接口添加@FeignClient ( “你要调用的服务名称” )
3、前提是Eureka服务器已经搭建以及相互调用的模块加了@EnableEurekaClient注解,将服务注册进Eureka
可以参考我这篇文章

更新粉丝数和关注数是在UserService中的操作
具体实现
在这里插入图片描述
Friend模块加上
UserClient

@FeignClient ( "pure-user" )
public interface UserClient {
    @RequestMapping ( value = "/user/{userid}/{friendid}/{type}", method = RequestMethod.PUT )
    //字段要保持一直,不然它找不着
    public void UpdateFansCountAndFollowCount ( @PathVariable ( "userid" ) String userid,@PathVariable ( "friendid" ) String friendid,@PathVariable ( "type" ) int type );


}

User模块
UserService

  /**
     * 更新好友的粉丝数和用户的关注数
     * 这是服务之间的调用,不用Result
     */
    @Transactional
    public void UpdateFansCountAndFollowCount ( int type,String userid,String friendid ) {
        userDao.UpdateFansCount(type,friendid); //粉丝数
        userDao.UpdateFollowCount(type,userid);
    }

UserDao

public interface UserDao extends JpaRepository<User,String>,JpaSpecificationExecutor<User>{


	@Modifying
	@Query(value = "UPDATE tb_user SET fanscount = fanscount+? WHERE id = ?",nativeQuery = true)
     public void UpdateFansCount ( int type,String friendid );

    @Modifying
    @Query(value = "UPDATE tb_user SET followcount = followcount+? WHERE id = ?",nativeQuery = true)
    public  void UpdateFollowCount ( int type,String userid );
}

Friend模块
FriendController

@RestController
@RequestMapping ( "/friend" )
public class FriendController {

    @Autowired
    private HttpServletRequest request;
    @Autowired
    private FriendService friendService;
    @Autowired
    private UserClient userClient;

    /**
     * * /friend/like/{friendid}/{type}
     * * 添加好友或非好友
     *
     * @return
     */
    @RequestMapping ( value = "/like/{friendid}/{type}", method = RequestMethod.PUT )
    public Result AddFriend ( @PathVariable String friendid,@PathVariable String type ) {
        //验证是否登陆,并且拿到当前用户id
        Claims claims = (Claims) request.getAttribute ( "claims_user" );  //这里强转类型
        if (claims == null) {
            //进入这一步,说明当前角色不是普通用户,或者未登录
            return new Result ( false,StatusCode.ACCESS_ERROR );
        }
        //得到当前用户id
        String userId = claims.getId ( );

        //判断是添加好友还是非好友
        if (type != null) {
            if (type.equals ( "1" )) {
                //添加好友
                int flag = friendService.AddFidend ( userId,friendid );
                if (flag == 0) {
                    return new Result ( false,StatusCode.ADD_FRIEND_ERROR );
                }
                if (flag == 1) {
                    userClient.UpdateFansCountAndFollowCount ( userId,friendid,1 );
                    return new Result ( true,StatusCode.ADD_FRIEND_SUCCESS );
                }
            } else if (type.equals ( "2" )) {
                //添加非好友
                int flag = friendService.AddNoFriend ( userId,friendid );
                if (flag == 0) {
                    return new Result ( false,StatusCode.ADD_NOFRIEND_ERROR );
                }
                if (flag == 1) {
                    return new Result ( true,StatusCode.ADD_NOFRIEND_SUCCESS );
                }
            }
            return new Result ( false,StatusCode.PARAMETER_ERROR );
        } else {
            return new Result ( false,StatusCode.PARAMETER_ERROR );
        }

    }

    /**
     * /{friendid}
     * 删除好友
     */
    @RequestMapping ( value = "/{friendid}", method = RequestMethod.DELETE )
    public Result DeleteFriend ( @PathVariable String friendid ) {
        //验证是否登陆,并且拿到当前用户id
        Claims claims = (Claims) request.getAttribute ( "claims_user" );  //这里强转类型
        if (claims == null) {
            //进入这一步,说明当前角色不是普通用户,或者未登录
            return new Result ( false,StatusCode.ACCESS_ERROR );
        }
        //得到当前用户id
        String userId = claims.getId ( );
        friendService.DeleteFriend ( userId,friendid );
        userClient.UpdateFansCountAndFollowCount ( userId,friendid,-1 );
        return new Result ( true,StatusCode.DELETE_OK );
    }
}

代码中有注释,就不解释了
FriendService

@Service
@Transactional
public class FriendService {

    @Autowired
    private FriendMapper friendMapper;
    @Autowired
    private NoFriendMapper noFriendMapper;

    public int AddFidend ( String userId,String friendid ) {
        //先判断useId到friendId是否有数据,有就是重复添加数据,返回0
        Friend friend = friendMapper.findByUseridAndFriendid ( userId,friendid );
        if (friend != null) {
            return 0;
        }
        //直接添加好友,让好友表中userId到friendId的type为0
        friend = new Friend ( );
        friend.setUserid ( userId );
        friend.setFriendid ( friendid );
        friend.setIslike ( "0" );
        friendMapper.save ( friend );

        //判断userId到friedId是否有数据,有就是把双方的数据改为1
        if (friendMapper.findByUseridAndFriendid ( friendid,userId ) != null) {
            //把双方的isLike都改为1
            friendMapper.upDateIsLike ( "1",userId,friendid );
            friendMapper.upDateIsLike ( "1",friendid,userId );
        }
        return 1;
    }

    public int AddNoFriend ( String userId,String friendid ) {
        //先判断是否已经是非好友
        NoFriend noFriend = noFriendMapper.findByUseridAndFriendid ( userId,friendid );
        if (noFriend != null) {
            return 0;
        }
        noFriend = new NoFriend ( );
        noFriend.setUserid ( userId );
        noFriend.setFriendid ( friendid );
        noFriendMapper.save ( noFriend );
        return 1;
    }

    /**
     * /{friendid}
     * 删除好友
     */
    public void DeleteFriend ( String userId,String friendid ) {
        //先删除好友表中userid到friendid的数据
        friendMapper.DeleteFriend ( userId,friendid );
        //更新friendid到userId的islike为0
        friendMapper.upDateIsLike ( "0",friendid,userId );
        //非好友表中添加数据
        NoFriend noFriend = new NoFriend ( );
        noFriend.setUserid ( userId );
        noFriend.setFriendid ( friendid );
        noFriendMapper.save ( noFriend );
    }
}

这只是本人的开发经验分享,还有很多不成熟的地方,请指导!!!!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值