dashan
12 months ago
4 changed files with 295 additions and 0 deletions
@ -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; |
||||
} |
||||
} |
||||
|
@ -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…
Reference in new issue