Browse Source

Merge branch 'dev' into dev-minio

dev-minio
dashan 12 months ago
parent
commit
8b28816582
  1. 11
      ds-commons/ds-utils/pom.xml
  2. 168
      ds-commons/ds-utils/src/main/java/com/ds/commons/utils/json/JsonUtil.java
  3. 10
      ds-gateway/pom.xml
  4. 106
      ds-gateway/src/main/java/com/ds/gateway/filter/SwaggerGlobalFilter.java

11
ds-commons/ds-utils/pom.xml

@ -17,4 +17,15 @@ @@ -17,4 +17,15 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>

168
ds-commons/ds-utils/src/main/java/com/ds/commons/utils/json/JsonUtil.java

@ -0,0 +1,168 @@ @@ -0,0 +1,168 @@
package com.ds.commons.utils.json;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
/**
* JSON 工具类
*/
@Slf4j
public class JsonUtil {
private static final ObjectMapper objectMapper = new ObjectMapper();
// 时间日期格式
private static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";
//以静态代码块初始化
static {
//对象的所有字段全部列入序列化
objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
//取消默认转换timestamps形式
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//忽略空Bean转json的错误
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
//所有的日期格式都统一为以下的格式,即yyyy-MM-dd HH:mm:ss
objectMapper.setDateFormat(new SimpleDateFormat(STANDARD_FORMAT));
//忽略 在json字符串中存在,但在java对象中不存在对应属性的情况。防止错误
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
/**===========================以下是从JSON中获取对象====================================*/
public static <T> T parseObject(String jsonString, Class<T> object) {
T t = null;
try {
t = objectMapper.readValue(jsonString, object);
} catch (JsonProcessingException e) {
log.error("JsonString转为自定义对象失败:{}", e.getMessage());
}
return t;
}
public static <T> T parseObject(File file, Class<T> object) {
T t = null;
try {
t = objectMapper.readValue(file, object);
} catch (IOException e) {
log.error("从文件中读取json字符串转为自定义对象失败:{}", e.getMessage());
}
return t;
}
//将json数组字符串转为指定对象List列表或者Map集合
public static <T> T parseJSONArray(String jsonArray, TypeReference<T> reference) {
T t = null;
try {
t = objectMapper.readValue(jsonArray, reference);
} catch (JsonProcessingException e) {
log.error("JSONArray转为List列表或者Map集合失败:{}", e.getMessage());
}
return t;
}
/**=================================以下是将对象转为JSON=====================================*/
public static String toJSONString(Object object) {
String jsonString = null;
try {
jsonString = objectMapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
log.error("Object转JSONString失败:{}", e.getMessage());
}
return jsonString;
}
public static byte[] toByteArray(Object object) {
byte[] bytes = null;
try {
bytes = objectMapper.writeValueAsBytes(object);
} catch (JsonProcessingException e) {
log.error("Object转ByteArray失败:{}", e.getMessage());
}
return bytes;
}
public static void objectToFile(File file, Object object) {
try {
objectMapper.writeValue(file, object);
} catch (JsonProcessingException e) {
log.error("Object写入文件失败:{}", e.getMessage());
} catch (IOException e) {
e.printStackTrace();
}
}
/**=============================以下是与JsonNode相关的=======================================*/
//JsonNode和JSONObject一样,都是JSON树形模型,只不过在jackson中,存在的是JsonNode
public static JsonNode parseJSONObject(String jsonString) {
JsonNode jsonNode = null;
try {
jsonNode = objectMapper.readTree(jsonString);
} catch (JsonProcessingException e) {
log.error("JSONString转为JsonNode失败:{}", e.getMessage());
}
return jsonNode;
}
public static JsonNode parseJSONObject(Object object) {
JsonNode jsonNode = objectMapper.valueToTree(object);
return jsonNode;
}
public static String toJSONString(JsonNode jsonNode) {
String jsonString = null;
try {
jsonString = objectMapper.writeValueAsString(jsonNode);
} catch (JsonProcessingException e) {
log.error("JsonNode转JSONString失败:{}", e.getMessage());
}
return jsonString;
}
//JsonNode是一个抽象类,不能实例化,创建JSON树形模型,得用JsonNode的子类ObjectNode,用法和JSONObject大同小异
public static ObjectNode newJSONObject() {
return objectMapper.createObjectNode();
}
//创建JSON数组对象,就像JSONArray一样用
public static ArrayNode newJSONArray() {
return objectMapper.createArrayNode();
}
/**===========以下是从JsonNode对象中获取key值的方法,个人觉得有点多余,直接用JsonNode自带的取值方法会好点,出于纠结症,还是补充进来了*/
public static String getString(JsonNode jsonObject, String key) {
String s = jsonObject.get(key).asText();
return s;
}
public static Integer getInteger(JsonNode jsonObject, String key) {
Integer i = jsonObject.get(key).asInt();
return i;
}
public static Boolean getBoolean(JsonNode jsonObject, String key) {
Boolean bool = jsonObject.get(key).asBoolean();
return bool;
}
public static JsonNode getJSONObject(JsonNode jsonObject, String key) {
JsonNode json = jsonObject.get(key);
return json;
}
}

10
ds-gateway/pom.xml

@ -30,6 +30,16 @@ @@ -30,6 +30,16 @@
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.ds</groupId>
<artifactId>ds-utils</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>

106
ds-gateway/src/main/java/com/ds/gateway/filter/SwaggerGlobalFilter.java

@ -0,0 +1,106 @@ @@ -0,0 +1,106 @@
package com.ds.gateway.filter;
import com.ds.commons.utils.json.JsonUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import org.reactivestreams.Publisher;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
/**
* 因为swagger配置在业务服务中默认的url会比网关少一层
* 这个过滤器主要给url添加上此网关这一层并且设置到swagger的basePath中使其可以正常通过swagger调用接口
*/
@Slf4j
@Component
public class SwaggerGlobalFilter implements GlobalFilter, Ordered {
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String path = request.getPath().toString();
if (!path.endsWith("/v3/api-docs/swagger-config")) {
return chain.filter(exchange);
}
String[] pathArray = path.split("/");
String basePath = pathArray[1];
ServerHttpResponse originalResponse = exchange.getResponse();
// 定义新的消息头
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
@NonNull
public Mono<Void> writeWith(@NonNull Publisher<? extends DataBuffer> body) {
if (HttpStatus.OK.equals(super.getStatusCode()) && body instanceof Flux) {
Flux<? extends DataBuffer> fluxBody = Flux.from(body);
return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
List<String> list = new ArrayList<>();
dataBuffers.forEach(dataBuffer -> {
byte[] content = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(content);
DataBufferUtils.release(dataBuffer);
list.add(new String(content, StandardCharsets.UTF_8));
});
String s = this.listToString(list);
//获取到/v3/api-docs/swagger-config返回的json串 给文档url添加上网关层url
ObjectNode jsonNodes = JsonUtil.parseObject(s,ObjectNode.class);
JsonNode urls = jsonNodes.get("urls");
urls.elements().forEachRemaining(item-> ((ObjectNode)item).put("url","/"+basePath+item.get("url").asText()));
//设置basePath
jsonNodes.put("basePath", basePath);
s = jsonNodes.toString();
// 设置更新后的header请求头长度
int length = s.getBytes().length;
HttpHeaders headers = originalResponse.getHeaders();
headers.setContentLength(length);
return bufferFactory().wrap(s.getBytes(StandardCharsets.UTF_8));
}));
}
return super.writeWith(body);
}
@Override
@NonNull
public HttpHeaders getHeaders() {
// 获取父类原始ServerHttpResponse的header请求头信息,这是代理Delegate类型
HttpHeaders httpHeaders = super.getHeaders();
httpHeaders.set(HttpHeaders.CONTENT_TYPE, "application/json;charset=UTF-8");
return httpHeaders;
}
private String listToString(List<String> list) {
StringBuilder stringBuilder = new StringBuilder();
for (String s : list) {
stringBuilder.append(s);
}
return stringBuilder.toString();
}
};
// replace response with decorator
return chain.filter(exchange.mutate().response(decoratedResponse).build());
}
@Override
public int getOrder() {
return -2;
}
}
Loading…
Cancel
Save