JHipster微服务之间的调用以及权限验证

JHipster微服务(uaa、app、gateway),下图注册中心中app和app1均为微服务(MicroService)且gateway基于uaa。

在这里插入图片描述

服务调用:

如上图注册中心所示,多个微服务进行了服务注册,那么当app应用需要app1中的数据(或者app1需要app当中的数据)时该如何调用呢?

解决办法如下:

以下是在app1中操作,app以及别的微服务调用都是同一个套路。

第一步:在client目录下新建Client请求的接口

@AuthorizedFeignClient(name = “app”)
注意:name写你要调用的微服务在注册中心中的注册名。

@RequestMapping(method = RequestMethod.GET, value = “/api/app/appString”)
注意:method 指请求方式,value写你请求微服务资源的路径。

接口中的方法返回类型和你调用返出来数据类型一致就ok。

package com.mycompany.myapp.client;

import com.mycompany.myapp.web.rest.vm.HeLikes;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;

/**
 * @author [email protected]
 * @version 1.0
 * @date 2019-08-26 09:53
 */
@AuthorizedFeignClient(name = "app")
public interface RequestAppClient {
    @RequestMapping(method = RequestMethod.GET, value = "/api/app/appString")
    public String getAppString();

    @RequestMapping(method = RequestMethod.GET, value = "/api/app/appList")
    public List<HeLikes> getAppList();
}
第二步:在web.rest.vm下创建你接收数据的接收类。

注意:这个类要和你服务调用时返回实体类一致。比如:服务A调用服务B中方法(List getAllStudents)那么,这个接收类就要定义为Student并且属性值一致。

对于这个接收类,我尝试过使用lombok,添加@Data注解后出现了一方可用,一方不可用的情况(getter setter方法可以调出来,但是赋值时提示找不到)
解决办法:1、手动添加getter setter方法 。 2、直接把那个实体类copy过来。

package com.mycompany.myapp.web.rest.vm;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import javax.persistence.*;
import java.io.Serializable;

/**
 * A HeLikes.
 */
@Entity
@Table(name = "he_likes")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class HeLikes implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "clothes")
    private String clothes;

    // jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public HeLikes name(String name) {
        this.name = name;
        return this;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getClothes() {
        return clothes;
    }

    public HeLikes clothes(String clothes) {
        this.clothes = clothes;
        return this;
    }

    public void setClothes(String clothes) {
        this.clothes = clothes;
    }
    // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof HeLikes)) {
            return false;
        }
        return id != null && id.equals(((HeLikes) o).id);
    }

    @Override
    public int hashCode() {
        return 31;
    }

    @Override
    public String toString() {
        return "HeLikes{" +
            "id=" + getId() +
            ", name='" + getName() + "'" +
            ", clothes='" + getClothes() + "'" +
            "}";
    }
}
第三步:在controller中调用自定义client中目标资源的方法。
package com.mycompany.myapp.web.rest;

import com.mycompany.myapp.client.RequestAppClient;
import com.mycompany.myapp.domain.SheLikes;
import com.mycompany.myapp.service.impl.SheLikesServiceImpl;
import com.mycompany.myapp.web.rest.vm.HeLikes;
import io.micrometer.core.annotation.Timed;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @author [email protected]
 * @version 1.0
 * @date 2019-08-26 10:04
 */
@RestController
@RequestMapping("/api/app1")
public class RequestController {
    @Autowired
    private SheLikesServiceImpl sheLikesService;

    private final RequestAppClient client;

    public RequestController(RequestAppClient client) {
        this.client = client;
    }

    /**
     * 服务调用方法,返回字符串
     * @return
     */
    @GetMapping("/appString")
    @Timed
    public String getString() {
        return client.getAppString();
    }

    /**
     * 自己调用的方法
     * @return
     */
    @GetMapping("/app1String")
    @Timed
    public String getSelfString() {
        return "我是app1";
    }

    /**
     * 服务调用的方法,返回list
     * @return
     */
    @GetMapping("/appList")
    @Timed
    public List<HeLikes> getFromApp() {
        return client.getAppList();
    }

    /**
     * 自己调用的方法,返回list
     * @return
     */
    @GetMapping("/app1List")
    @Timed
    public List<SheLikes> getApp1List() {
        return sheLikesService.getAllSheLikes();
    }
}
app的RequestController
package com.mycompany.myapp.web.rest;

import com.mycompany.myapp.client.RequestApp1Client;
import com.mycompany.myapp.domain.HeLikes;
import com.mycompany.myapp.security.AuthoritiesConstants;
import com.mycompany.myapp.service.impl.HeLikesServiceImpl;
import com.mycompany.myapp.web.rest.vm.SheLikes;
import io.micrometer.core.annotation.Timed;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @author [email protected]
 * @version 1.0
 * @date 2019-08-26 10:22
 */
@RestController
@RequestMapping("/api/app")
public class RequestController {
    private final RequestApp1Client client;
    @Autowired
    private HeLikesServiceImpl heLikesService;

    public RequestController(RequestApp1Client client) {
        this.client = client;
    }

    @GetMapping("/appString")
    @Timed
    public String getString() {

        return "我是app";
    }

    // APP实体数据
    @GetMapping("/appList")
    @Timed
    public List<HeLikes> getAppList() {
        return heLikesService.getAllHeLikes();
    }

    @GetMapping("/app1String")
    @Timed
    public String getApp1String() {

        return client.getApp1String();
    }

    @GetMapping("/app1List")
    @Timed
    // 单个权限
    // @PreAuthorize("hasRole('ROLE_USER')")
    // 多个权限
    @PreAuthorize("hasRole(\"" + AuthoritiesConstants.ADMIN + "\")or hasRole(\"" + AuthoritiesConstants.USER + "\") ")
    public List<SheLikes> getApp1List() {

        return client.getApp1List();
    }
}
数据库中数据如下
  • app
    在这里插入图片描述
  • app1
    在这里插入图片描述
swagger测试
  • 调用自身方法:
    在这里插入图片描述
  • 服务调用,调用app中方法:
    在这里插入图片描述
    在这里插入图片描述

权限验证:

  @GetMapping("/app1-list")
    @Timed
    // 单个权限
    // @PreAuthorize("hasRole('ROLE_USER')")
    // 多个权限
    // @PreAuthorize("hasAnyRole('ROLE_ADMIN,ROLE_USER')")
    @PreAuthorize("hasRole(\"" + AuthoritiesConstants.ADMIN + "\")or hasRole(\"" + AuthoritiesConstants.USER + "\") ")
    public List<SheLikes> getApp1List() {

        return client.getApp1List();
    }
  • 无权限的
    在这里插入图片描述
  • 有权限的
    在这里插入图片描述
总结:

个人感觉,相互调用本质上就是在自己的controller中定义一个方法,指定一个路由,该方法中调用client中自定义的方法,而在你接口上方又指定了RequestMapping的路径,通过@AuthorizedFeignClient找到注册中心具体的某个服务,然后调用,返回数据。

发布了74 篇原创文章 · 获赞 19 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_43770545/article/details/100075761