前言

先创建springboot项目https://start.spring.io/ ,名称为serverClientB,然后完成以下内容。

一、搭建serverClientB服务工程

1.修改pom.xml配置文件,添加相关依赖

<!--服务调用方 添加依赖Feign-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
        <version>1.4.5.RELEASE</version>
    </dependency>

    <!-- 添加Thymeleaf依赖-->
    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf</artifactId>
        <version>3.0.9.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.thymeleaf</groupId>
        <artifactId>thymeleaf-spring4</artifactId>
        <version>3.0.9.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

2.修改application.properties配置文件

#注册中心服务ID
spring.application.name=client-serverB
#端口号
server.port=2224
eureka.instance.hostname=127.0.0.1
eureka.instance.instance-id=${spring.application.name}:${spring.cloud.client.hostname}:${server.port}
eureka.instance.prefer-ip-address=false
#设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址。
eureka.client.serviceUrl.defaultZone=http://localhost:1112/eureka/
#启动服务发现的功能,开启了才能调用其它服务
spring.cloud.config.discovery.enabled=true
#发现的服务的名字--对应注测中心的服务名字
spring.cloud.config.discovery.serviceId=eureka-server

#启用Feign
feign.hystrix.enabled=true

#Thymeleaf
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.cache=false

3.启动类中添加注解@EnableFeignClients

通过@EnableFeignClients来开启Spring Cloud的Feign支持功能。

package com.lpc.serverClientB;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class ServerClientBApplication {

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

4.新建DemoFeignService接口

接口中@RequestMapping(value = “/generate”, method = RequestMethod.GET)与serverClientA中Controller类的 generate()方法上的注解一一对应。

package com.lpc.serverClientB.dao;

import com.lpc.serverClientB.dao.fallback.DemoFeignFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@FeignClient(name = "client-serverA", fallback = DemoFeignFallback.class)
public interface DemoFeignService {

    @RequestMapping(value = "/generate", method = RequestMethod.GET)
    String generate();
}

5.新建接口实现类DemoFeignFallback

package com.lpc.serverClientB.dao.fallback;

import com.lpc.serverClientB.dao.DemoFeignService;
import org.springframework.stereotype.Component;

@Component
public class DemoFeignFallback implements DemoFeignService {

    //熔断处理
    @Override
    public String generate() {
        return "error";
    }
}

6.新建MessageGenerationController类

该类负责接收由serverClientA生成的xml报文,并解析该报文,将解析后的数据返回给前端。

package com.lpc.serverClientB.controller;

import com.lpc.serverClientB.dao.DemoFeignService;
import com.lpc.serverClientB.entity.OutputData;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.text.SimpleDateFormat;
import java.util.Date;

@Controller
public class MessageParseController {

    @Autowired
    private DemoFeignService demoFeignService;

    private Logger logger = LoggerFactory.getLogger(getClass());
    private String resultXML;
    private OutputData outputData = new OutputData();

    //初始页面index
    @RequestMapping(value = "/index", produces = "text/plain;charset=UTF-8")
    public String index(ModelMap map) {

        OutputData output = new OutputData();
        output.setDate(getDate());
        map.put("fpMessage", output);
        return "index";
    }

    // 解析xml报文,并将解析后的xml赋值给output实体类,传给前端
    //@ResponseBody  //加上ResponseBody,会返回字符串
    @RequestMapping(value = "/parseXML", method = RequestMethod.POST, produces = "text/plain;charset=UTF-8")
    private String parse(ModelMap map) {

        // 熔断降级处理
        resultXML = demoFeignService.generate();
        if ("error".equals(resultXML)) {
            return "error";
        }

        // 解析xml
        outputData = getXML(resultXML);
        map.put("fpMessage", outputData);
        return "index";
    }

    // 解析xml报文
    private OutputData getXML(String xml) {

        //OutputData outputData = new OutputData();
        try {
            Document document = DocumentHelper.parseText(xml);
            Element rootElement = document.getRootElement();// 获取根节点FPXT

            Element inputElement = rootElement.element("OUTPUT");
            outputData.setFpzl(inputElement.element("FPZL").getTextTrim());
            outputData.setFpdm(inputElement.element("FPDM").getTextTrim());
            outputData.setFpzt(inputElement.element("FPZT").getTextTrim());
            outputData.setNsrsbh(inputElement.element("NSRSBH").getTextTrim());
            outputData.setDate(inputElement.element("DATE").getTextTrim());

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("Exception = " + e.toString());
        }
        return outputData;
    }

    // 获取当前时间
    private String getDate() {

        Date date = new Date();
        SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss");
        return simpleDate.format(date);
    }

    //接收serviceA的xml报文
    @RequestMapping(value = "/serviceGet", method = RequestMethod.GET)
    public void helloService() {

        resultXML = demoFeignService.generate();
        logger.info("接收serviceA的xml报文 = " + resultXML);
    }
}

7.新建OutputData实体类

package com.lpc.serverClientB.entity;

import java.io.Serializable;

public class OutputData implements Serializable {

    String nsrsbh;//纳税人识别号
    String fpdm;//发票代码
    String fpzl;//发票种类
    String date;//日期
    String fpzt;//发票状态

    public String getFpzt() {
        return fpzt;
    }

    public void setFpzt(String fpzt) {
        this.fpzt = fpzt;
    }

    public String getNsrsbh() {
        return nsrsbh;
    }

    public void setNsrsbh(String nsrsbh) {
        this.nsrsbh = nsrsbh;
    }

    public String getFpdm() {
        return fpdm;
    }

    public void setFpdm(String fpdm) {
        this.fpdm = fpdm;
    }

    public String getFpzl() {
        return fpzl;
    }

    public void setFpzl(String fpzl) {
        this.fpzl = fpzl;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    @Override
    public String toString() {
        return "OutputData{" +
                "nsrsbh='" + nsrsbh + '\'' +
                ", fpdm='" + fpdm + '\'' +
                ", fpzl='" + fpzl + '\'' +
                ", date='" + date + '\'' +
                ", fpzt='" + fpzt + '\'' +
                '}';
    }
}

8.新建页面index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>接收解析报文</title>
</head>

<body>
<form action="#" th:action="@{/parseXML}" th:object="${fpMessage}" method="post">

    <table>
        <tr>
            <td>纳税人识别号:</td>
            <td>
                <label>
                    <p th:text="*{nsrsbh}"></p>
                </label>
            </td>
        </tr>
        <tr>
            <td>发票代码:</td>
            <td>
                <label>
                    <p th:text="*{fpdm}"></p>
                </label>
            </td>
        </tr>
        <tr>
            <td>发票种类:</td>
            <td>
                <label>
                    <p th:text="*{fpzl}"></p>
                </label>
            </td>
        </tr>
        <tr>
            <td>发票状态:</td>
            <td>
                <label>
                    <p th:text="*{fpzt}"></p>
                </label>
            </td>
        </tr>
        <tr>
            <td>时间:</td>
            <td>
                <label>
                    <p th:text="*{date}"></p>
                </label>
            </td>
        </tr>
    </table>
    <input type="submit"/>
</form>
</body>
</html>

9.新建页面error.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Error</title>
</head>
<body>
get error
</body>
</html>

运行项目后,访问此地址:http://localhost:2224/index,显示如下页面:

Springboot微服务间数据传输 springboot调用微服务_Springboot微服务间数据传输

此时点击按钮后,会跳转到error页面,说明进入了springcloud的熔断处理。

运行再eureka-server项目和serverClientA项目,在serverClientA项目中填入测试数据

,点击按钮:

Springboot微服务间数据传输 springboot调用微服务_Springboot微服务间数据传输_02

再重新进入serverClientB项目,点击按钮后显示测试数据:

Springboot微服务间数据传输 springboot调用微服务_SpringCloud_03