交友微服务-添加与删除好友
1)创建工程friend,pom.xml引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.tensquare</groupId>
<artifactId>tensquare_common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--将friend注册成eureka客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 你去掉别人别人不用动,需要在自己这里倒openfeign的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
(2)创建application.yml
server:
port: 9010
spring:
application:
name: tensquare-friend
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.223.128:3306/tensquare_friend?characterEncoding=utf-8
username: root
password: root
jpa:
database: mysql
show-sql: true
jwt:
config:
key: itcast
eureka:
client: #Eureka客户端与Eureka服务端进行交互的地址
service-url: http://127.0.0.1:6868/eureka/
instance:
prefer-ip-address: true #为了以后布到线上的时候模块之间可以跨域访问
编写启动类
交友的话需要用户登录 所以需要进行token验签
jwtUtil工具类
@ConfigurationProperties("jwt.config")
public class JwtUtil {
private String key ;
private long ttl ;//一个小时
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public long getTtl() {
return ttl;
}
public void setTtl(long ttl) {
this.ttl = ttl;
}
public String createJWT(String id, String subject, String roles) {
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
JwtBuilder builder = Jwts.builder().setId(id)
.setSubject(subject)
.setIssuedAt(now)
.signWith(SignatureAlgorithm.HS256, key).claim("roles", roles);
if (ttl > 0) {
builder.setExpiration( new Date( nowMillis + ttl));
}
return builder.compact();
}
public Claims parseJWT(String jwtStr){
return Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(jwtStr)
.getBody();
}
@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();
}
创建JwtInterceptor
@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 ")){
//得到token
String token = header.substring(7);
//对token进行验证
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
@Component
public class InterceptorConfig extends WebMvcConfigurationSupport{
@Autowired
private JwtInterceptor jwtInterceptor;
protected void addInterceptors(InterceptorRegistry registry){
//注册拦截器要声明拦截器对象和要拦截的请求
registry.addInterceptor(jwtInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/**/login/**");
}
添加好友业务编写
SpringJpa 实体类的写法@Entity
@Table(name = "tb_friend") //表名
@IdClass(Friend.class)//表示我这个类是联合主键
public class Friend {
/**
* 两个id上面都加@Id才表示这是联合主键
*/
@Id //表示这个字段是主键
private String userid;
@Id
private String friendid;
private String islike;
}
Dao层写sql语句的方式public interface FriendDao extends JpaRepository<Friend,String>{
public Friend findByUseridAndFriendid(String userid,String friendid);
@Modifying //增删改需要加此注解 注解的方式写sql语句 ?是占位符
@Query(value = "UPDATE tb_friend SET islike = ? WHERE userid = ? AND friendid = ?",nativeQuery = true)
public void updateIslike(String islike,String userid,String friendid);
}
(2)新建dao包,创建FriendDao接口
public interface FriendDao extends JpaRepository<Friend,String>{
public Friend findByUseridAndFriendid(String userid,String friendid);
@Modifying //增删改需要加此注解 注解的方式写sql语句 ?是占位符
@Query(value = "UPDATE tb_friend SET islike = ? WHERE userid = ? AND friendid = ?",nativeQuery = true)
public void updateIslike(String islike,String userid,String friendid);
}
新建dao包,创建NoFriendDao接口
public interface NoFriendDao extends JpaRepository<NoFriend,String>{
public NoFriend findByUseridAndFriendid(String userid, String friendid);
}
(3)创建业务逻辑类
@Service
@Transactional
public class FriendService {
@Autowired
private FriendDao friendDao;
public int addFriend(String userid, String friendid) {
//先判断userid到friendid是否有数据,有就是重复添加好友 ,返回0
Friend friend = friendDao.findByUseridAndFriendid(userid, friendid);
if(friend!=null){
return 0;
}
//直接添加好友,让好友表中userid到friendid方向的type为0
friend = new Friend();
friend.setUserid(userid);
friend.setFriendid(friendid);
friend.setIslike("0");
friendDao.save(friend);
//判断从friendid到userid是否有数据,如果有,把双方的状态都改为1
if(friendDao.findByUseridAndFriendid(friendid, userid)!=null){
//把双方的islike都改为1
friendDao.updateIslike("1",userid,friendid);
friendDao.updateIslike("1",friendid,userid);
}
return 1;
}
public int addNoFriend(String userid, String friendid) {
//先判断是否已经是非好友
NoFriend noFriend = noFriendDao.findByUseridAndFriendid(userid,friendid);
if(noFriend!=null){
return 0;
}
noFriend = new NoFriend();
noFriend.setUserid(userid);
noFriend.setFriendid(friendid);
noFriendDao.save(noFriend);
return 1;
}
}
(3)控制器类
@RestController
@RequestMapping("/friend")
public class FriendController {
@Autowired
private HttpServletRequest request;
@Autowired
private FriendService friendService;
/**
* 添加好友或者添加非好友
* @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){
//说明当前用户没有user角色
return new Result(false,StatusCode.LOGINERROR,"权限不足");
}
//得到当前用户登录的id
String userid = claims.getId();
//判断是添加好友还是添加非好友
if(type!=null){
if(type.equals("1")){
//添加好友
int flag = friendService.addFriend(userid,friendid);
if(flag==0){
return new Result(false, StatusCode.ERROR,"不能重复添加好友");
}
if(flag==1){
return new Result(true, StatusCode.OK,"添加成功");
}
}else if(type.equals("2")){
//添加非好友
int flag = friendService.addNoFriend(userid,friendid);
if(flag==0){
return new Result(false, StatusCode.ERROR,"不能重复添加非好友");
}
if(flag==1){
return new Result(true, StatusCode.OK,"添加成功");
}
}
return new Result(false, StatusCode.ERROR,"参数异常");
}else{
return new Result(false, StatusCode.ERROR,"参数异常");
}
4)测试:启动用户微服务,登陆用户获取token
启动交友微服务,通过postMan测试 http://localhost:9010/friend/like/1/1,添加
头信息 Authorization 内容为Bearer 加上获取的token
粉丝数与关注数的变更
创建userController增加方法
**
* 更新好友粉丝数和用户关注数
*
* @return
*/
@RequestMapping(value = "/{userid}/{friendid}/{x}",method = RequestMethod.PUT)
public void updatefanscountandfollowcount(@PathVariable String userid,@PathVariable String friendid,@PathVariable int x){
userService.updatefanscountandfollowcount(x,userid,friendid);
}
service层方法
@Transactional
public void updatefanscountandfollowcount(int x, String userid, String friendid) {
userDao.updatefanscount(x,friendid);
userDao.updatefollowcount(x,userid);
}
Dao层方法
**
* 数据访问接口
* @author Administrator
*
*/
public interface UserDao extends JpaRepository<User,String>,JpaSpecificationExecutor<User>{
public User findByMobile(String mobile);
@Modifying
@Query(value = "update tb_user set fanscount = fanscount+? where id = ?",nativeQuery = true)
public void updatefanscount(int x, String friendid);
@Modifying
@Query(value = "update tb_user set followcount = followcount+? where id = ?",nativeQuery = true)
public void updatefollowcount(int x, String userid);
}
交友模块调用user模块
在交友模块中添加user客户端接口
@Component
@FeignClient("tensquare-user")
public interface UserClient {
@RequestMapping(value = "/user/{userid}/{friendid}/{x}",method = RequestMethod.PUT)
public void updatefanscountandfollowcount(@PathVariable("userid") String userid, @PathVariable("friendid") String friendid, @PathVariable("x") int x);
}
在friendController 当添加好友且flag是1下添加方法
@Autowired
private UserClient userClient;
/**
* 添加好友或者添加非好友
* @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){
//说明当前用户没有user角色
return new Result(false,StatusCode.LOGINERROR,"权限不足");
}
//得到当前用户登录的id
String userid = claims.getId();
//判断是添加好友还是添加非好友
if(type!=null){
if(type.equals("1")){
//添加好友
int flag = friendService.addFriend(userid,friendid);
if(flag==0){
return new Result(false, StatusCode.ERROR,"不能重复添加好友");
}
if(flag==1){
userClient.updatefanscountandfollowcount(userid,friendid,1);
return new Result(true, StatusCode.OK,"添加成功");
}
}else if(type.equals("2")){
//添加非好友
int flag = friendService.addNoFriend(userid,friendid);
if(flag==0){
return new Result(false, StatusCode.ERROR,"不能重复添加非好友");
}
if(flag==1){
return new Result(true, StatusCode.OK,"添加成功");
}
}
return new Result(false, StatusCode.ERROR,"参数异常");
}else{
return new Result(false, StatusCode.ERROR,"参数异常");
}
}
}
删除好友
1)FriendDao新增方法定义
@Modifying //增删改需要加此注解 注解的方式写sql语句 ?是占位符
@Query(value = "DELETE FROM tb_friend WHERE userid = ? AND friendid = ?",nativeQuery = true)
void deletefriend(String userid, String friendid);