Springcloud服务提供与服务消费

介绍

这里的服务提供与服务消费是基于Eureka注册中心。Eureka中有三个角色:服务注册中心、服务提供者、服务消费者。

服务提供者

新建一个springboot项目。

1.依赖
<?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 https://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.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.dpf</groupId>
    <artifactId>eureka-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka-provider</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR3</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.配置文件application.yml
spring:
  application:
    name: eureka-provider

server:
  port: 1115

eureka:
  client:
    service-url:
      defaultZone: http://localhost:1111/eureka

3.启动文件加@EnableDiscoveryClient注解
@SpringBootApplication
@EnableEurekaClient
public class EurekaProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaProviderApplication.class, args);
    }
}
4.controller
@RestController
public class HelloController {

    @Value("${server.port}")
    Integer port;
  
    @GetMapping("/hello")
    public String hello(){
        return "hello"+port;
    }
    @GetMapping("/hello2")
    public String hello2(String name){
        System.out.println(new Date()+">>"+name);
        return "hello"+name;
    }

    @PostMapping("/user1")
    public User add1(User user){
        return user;
    }
    @PostMapping("/user2")
    public User add2(@RequestBody User user){
        return user;
    }

    @PutMapping("/user1")
    public void updateUser1(User user){
        System.out.println(user);
    }
    @PutMapping("/user2")
    public void updateUser2(@RequestBody User user){
        System.out.println(user);
    }

    @DeleteMapping("/user1")
    public void deleteUser1(Integer id){
        System.out.println(id);
    }

    @DeleteMapping("/user2/{id}")
    public void deleteUser2(@PathVariable Integer id){
        System.out.println(id);
    }
}

@Controller
public class RegisterController {

    /**
     * 注意重定向的地址一定要写绝对地址,不要写相对地址,不然会出问题
     * @param user
     * @return
     */
    @PostMapping("register")
    public String register(User user){
        return "redirect:http://provider/loginPage?username="+user.getUsername();
    }

    @GetMapping("/loginPage")
    @ResponseBody
    public String loginPage(String username){
       return "loginPage:"+username;
    }
}

服务消费者

1.依赖
<?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 https://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.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.dpf</groupId>
    <artifactId>eureka-consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureka-consumer</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR3</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    
</project>

2.配置文件
spring:
  application:
    name: eureka-consumer

server:
  port: 1117

eureka:
  client:
    service-url:
      defaultZone: http://localhost:1111/eureka
3.启动文件
@SpringBootApplication
@EnableEurekaClient
public class EurekaConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaConsumerApplication.class, args);
    }

   /**
     * RestTemplate用于服务间的调用
     * @return
     */
    @Bean
    RestTemplate restTemplateOne(){
        return new RestTemplate();
    }

    /**
     * 服务间调用,加上负载均衡
     * @return
     */
    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        return new RestTemplate();
    }

}
4.控制层
@RestController
public class HelloController {

    /**
     * http调用,调用地址写死
     * @return
     */
    @GetMapping("/hello1")
    public String hello1(){
        HttpURLConnection con = null;
        try {
            URL url = new URL("http://localhost:1116/hello");
            con = (HttpURLConnection) url.openConnection();
            if(con.getResponseCode()==200){
                BufferedReader br =  new BufferedReader(new InputStreamReader(con.getInputStream()));
                String s = br.readLine();
                br.close();
                return s;
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return "error";
    }


    @Autowired
    DiscoveryClient discoveryClient;
    /**
     * 动态获取调用地址
     * @return
     */
    @GetMapping("/hello2")
    public String hello2(){
        HttpURLConnection con = null;
        List<ServiceInstance> instances = discoveryClient.getInstances("eureka-provider");
        ServiceInstance serviceInstance = instances.get(0);
        String host = serviceInstance.getHost();
        int port = serviceInstance.getPort();

        StringBuilder sb = new StringBuilder();
        sb.append("http://")
                .append(host)
                .append(":")
                .append(port)
                .append("/")
                .append("hello");
        try {
            URL url = new URL(sb.toString());
            con = (HttpURLConnection) url.openConnection();
            if(con.getResponseCode()==200){
                BufferedReader br =  new BufferedReader(new InputStreamReader(con.getInputStream()));
                String s = br.readLine();
                br.close();
                return s;
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return "error";
    }

    /**
     * 实现线性负载均衡
     */
    int count=0;
    @GetMapping("/hello3")
    public String hello3(){
        HttpURLConnection con = null;
        List<ServiceInstance> instances = discoveryClient.getInstances("eureka-provider");
        ServiceInstance serviceInstance = instances.get((count++)%instances.size());
        String host = serviceInstance.getHost();
        int port = serviceInstance.getPort();

        StringBuilder sb = new StringBuilder();
        sb.append("http://")
                .append(host)
                .append(":")
                .append(port)
                .append("/")
                .append("hello");
        try {
            URL url = new URL(sb.toString());
            con = (HttpURLConnection) url.openConnection();
            System.out.println(con);
            if(con.getResponseCode()==200){
                BufferedReader br =  new BufferedReader(new InputStreamReader(con.getInputStream()));
                String s = br.readLine();
                br.close();
                return s;
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return "error";
    }

    @Autowired
    @Qualifier("restTemplateOne")
    RestTemplate restTemplateOne;
    /**
     *
     * 没有负载均衡的RestTemplate必须完整地址
     * @return
     */
    @GetMapping("/hello4")
    public String hello4(){
        HttpURLConnection con = null;
        List<ServiceInstance> instances = discoveryClient.getInstances("eureka-provider");
        ServiceInstance serviceInstance = instances.get(0);
        String host = serviceInstance.getHost();
        int port = serviceInstance.getPort();

        StringBuilder sb = new StringBuilder();
        sb.append("http://")
                .append(host)
                .append(":")
                .append(port)
                .append("/")
                .append("hello");
        String s = restTemplateOne.getForObject(sb.toString(), String.class);

        return s;
    }

    @Autowired
    @Qualifier("restTemplate")
    RestTemplate restTemplate;

    /**
     * Ribbon实现负载均衡
     *
     * @return
     */
    @GetMapping("/hello5")
    public String hello5(){
        return restTemplate.getForObject("http://eureka-provider/hello",String.class);
    }


    /**
     * get方法
     * RestTemplate 两种方法体验
     *  getForObject:返回具体值
     *  getForEntity:返回带Http响应头的具体值
     *  两种方法都有三个不同的重载方法分别表示不同的传参方式
     *
     */
    @GetMapping("/hello6")
    public void hello6(){
        String s = restTemplate.getForObject("http://eureka-provider/hello2?name={1}", String.class, "runn");
        System.out.println(s);

        ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://eureka-provider/hello2?name={1}", String.class, "runn");
        HttpStatus statusCode = responseEntity.getStatusCode();
        System.out.println("HttpStatus:"+statusCode);
        int statusCodeValue = responseEntity.getStatusCodeValue();
        System.out.println("statusCodeValue:"+statusCodeValue);
        String body = responseEntity.getBody();
        System.out.println("body:"+body);
        HttpHeaders headers = responseEntity.getHeaders();
        System.out.println("----------header---");
        Set<String> keySet = headers.keySet();
        for (String key : keySet){
            System.out.println(key+"--"+headers.get(key));
        }
    }
    /**
     * get方法
     * RestTemplate方法的三种传值方法
     */
    @GetMapping("/hello7")
    public void hello7(){
        //占位符传值
        String s1 = restTemplate.getForObject("http://eureka-provider/hello2?name={1}", String.class, "runn");
        System.out.println(s1);

        //map传值
        Map<String ,Object> map = new HashMap<>();
        map.put("name","runn");
        String s2 = restTemplate.getForObject("http://eureka-provider/hello2?name={name}", String.class, map);
        System.out.println(s2);

        //uri传值
        try {
            //如果是中文需要转码,不然可能乱码
            String url = "http://eureka-provider/hello2?name="+ URLEncoder.encode("张三","UTF-8");
            URI uri = URI.create(url);
            String s3 = restTemplate.getForObject(uri, String.class);
            System.out.println(s3);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

    }

    /**
     * post方法
     * RestTemplate的post方法和get方法基本类似,多了一个postForLocation
     */
    @GetMapping("/hello8")
    public void hello8(){
        //key/value传值
        MultiValueMap<String,Object> map = new LinkedMultiValueMap<>();
        map.add("username","runn");
        map.add("password","123");
        map.add("id",999);
        User user1 = restTemplate.postForObject("http://eureka-provider/user1", map, User.class);
        System.out.println(user1);

        //json传值
        user1.setId(998);
        User user2 = restTemplate.postForObject("http://eureka-provider/user2", user1, User.class);
        System.out.println(user2);
    }
    /**
     * 测试postForLocation:用于页面重定向(注册后重定向到登录页面)
     */
    @GetMapping("/hello9")
    public void hello9(){
        MultiValueMap<String,Object> map = new LinkedMultiValueMap<>();
        map.add("username","runn");
        map.add("password","123");
        map.add("id",999);
        URI uri = restTemplate.postForLocation("http://eureka-provider/register", map);
        String s = restTemplate.getForObject(uri, String.class);
        System.out.println(s);
    }

    /**
     * 测试put请求
     */
    @GetMapping("/hello10")
    public void hello10(){
        MultiValueMap<String,Object> map = new LinkedMultiValueMap<>();
        map.add("username","runn");
        map.add("password","123");
        map.add("id",999);
        restTemplate.put("http://eureka-provider/user1",map);

        User user = new User();
        user.setId(998);
        user.setPassword("123");
        user.setUsername("runn");
        restTemplate.put("http://eureka-provider/user2",user);

    }

    /**
     * 测试delete请求
     */
    @GetMapping("/hello11")
    public void hello11(){
        restTemplate.delete("http://eureka-provider/user1?id={1}",998);
        restTemplate.delete("http://eureka-provider/user2/{1}",999);
    }

}

测试

启动注册中心eureka、两个provider服务、consumer服务,浏览器输入对应地址调用consumer接口进行调用测试。

项目地址

github

原创文章 139 获赞 52 访问量 10万+

猜你喜欢

转载自blog.csdn.net/qq_41262903/article/details/105199590