前言
先创建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,显示如下页面:
此时点击按钮后,会跳转到error页面,说明进入了springcloud的熔断处理。
运行再eureka-server项目和serverClientA项目,在serverClientA项目中填入测试数据
,点击按钮:
再重新进入serverClientB项目,点击按钮后显示测试数据: