Json序列化
This commit is contained in:
parent
74c813be8d
commit
df6e52ce15
|
|
@ -0,0 +1,242 @@
|
|||
package com.bonus.config;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.data.redis.core.script.DefaultRedisScript;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@JsonIgnoreProperties(
|
||||
ignoreUnknown = true
|
||||
)
|
||||
public class AccessToken {
|
||||
private static final Logger log = LoggerFactory.getLogger(AccessToken.class);
|
||||
@JsonIgnore
|
||||
protected static ObjectMapper objectMapper;
|
||||
@JsonIgnore
|
||||
protected static SecureProperties secureProperties;
|
||||
@JsonIgnore
|
||||
protected static StringRedisTemplate redisTemplate;
|
||||
@JsonIgnore
|
||||
protected static AuthenticationPredicate authenticationPredicate;
|
||||
private String id;
|
||||
private Long subjectId;
|
||||
private String subjectName;
|
||||
private Map<String, String> subjectData = Maps.newHashMap();
|
||||
private String scope;
|
||||
private boolean identified;
|
||||
private long createTime;
|
||||
private long lastTime;
|
||||
|
||||
public static Optional<AccessToken> recovery(String clientToken) {
|
||||
StringRedisTemplate var10000 = redisTemplate;
|
||||
String var10001 = secureProperties.getServer().getStoreKey();
|
||||
clientToken = (String)var10000.boundValueOps(var10001 + ":" + clientToken).get();
|
||||
if (StringUtils.isBlank(clientToken)) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
try {
|
||||
AccessToken existToken = (AccessToken)objectMapper.readValue(clientToken, AccessToken.class);
|
||||
return authenticationPredicate.authenticated(existToken) ? Optional.of(existToken) : Optional.empty();
|
||||
} catch (Exception var2) {
|
||||
log.error("Deserialize exist token error", var2);
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static AccessToken create(long subjectId) {
|
||||
AccessToken accessToken = create();
|
||||
accessToken.setSubjectId(subjectId);
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public static AccessToken create(long subjectId, String subjectName) {
|
||||
AccessToken accessToken = create(subjectId);
|
||||
accessToken.setSubjectName(subjectName);
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public static AccessToken create() {
|
||||
AccessToken accessToken = new AccessToken();
|
||||
accessToken.setId(UUID.randomUUID().toString());
|
||||
accessToken.setCreateTime(Instant.now().getEpochSecond());
|
||||
accessToken.setLastTime(Instant.now().getEpochSecond());
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public AccessToken touch() {
|
||||
this.identified = this.isAuthenticated();
|
||||
this.lastTime = Instant.now().getEpochSecond();
|
||||
return this.store();
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public boolean isAuthenticated() {
|
||||
return this.identified && !this.isExpired();
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
private boolean isExpired() {
|
||||
return this.lastTime + secureProperties.getExpireAfter() < Instant.now().getEpochSecond();
|
||||
}
|
||||
|
||||
public AccessToken withData(Map<String, String> data) {
|
||||
this.subjectData = data;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AccessToken setData(String name, String value) {
|
||||
this.subjectData.put(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AccessToken removeData(String... keys) {
|
||||
if (ArrayUtil.isEmpty(keys)) {
|
||||
return this;
|
||||
} else {
|
||||
String[] var2 = keys;
|
||||
int var3 = keys.length;
|
||||
|
||||
for(int var4 = 0; var4 < var3; ++var4) {
|
||||
String key = var2[var4];
|
||||
this.subjectData.remove(key);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public AccessToken revokeAuthenticate() {
|
||||
this.identified = false;
|
||||
return this.store();
|
||||
}
|
||||
|
||||
public AccessToken authenticate() {
|
||||
if (this.subjectId == null) {
|
||||
throw new RuntimeException("required subjectId is not provide");
|
||||
} else {
|
||||
this.identified = true;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public AccessToken store() {
|
||||
try {
|
||||
StringRedisTemplate var10000 = redisTemplate;
|
||||
DefaultRedisScript var10001 = new DefaultRedisScript("redis.call('SET',KEYS[1],ARGV[1],'EX',ARGV[3]);redis.call('SET',KEYS[2],ARGV[2],'EX',ARGV[3]);");
|
||||
String[] var10002 = new String[2];
|
||||
String var10005 = secureProperties.getServer().getStoreKey();
|
||||
var10002[0] = var10005 + ":" + this.getId();
|
||||
var10005 = secureProperties.getServer().getSubjectRefTokenKey();
|
||||
var10002[1] = var10005 + ":" + this.getSubjectId() + ":" + this.getId() + ":" + this.getCreateTime();
|
||||
var10000.execute(var10001, Lists.newArrayList(var10002), new Object[]{objectMapper.writeValueAsString(this), this.getId(), String.valueOf(secureProperties.getServer().getTtl())});
|
||||
} catch (Exception var2) {
|
||||
log.error("Token store error", var2);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public AccessToken bind() {
|
||||
WebContext.get().setAccessToken(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void write() {
|
||||
WebContext.get().getResponse().ifPresent((response) -> {
|
||||
response.setHeader(secureProperties.getTokenSymbol(), this.getId());
|
||||
});
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
try {
|
||||
StringRedisTemplate var10000 = redisTemplate;
|
||||
DefaultRedisScript var10001 = new DefaultRedisScript("redis.call('DEL',KEYS[1],KEYS[2]);");
|
||||
String[] var10002 = new String[2];
|
||||
String var10005 = secureProperties.getServer().getStoreKey();
|
||||
var10002[0] = var10005 + ":" + this.getId();
|
||||
var10005 = secureProperties.getServer().getSubjectRefTokenKey();
|
||||
var10002[1] = var10005 + ":" + this.getSubjectId() + ":" + this.getId() + ":" + this.getCreateTime();
|
||||
var10000.execute(var10001, Lists.newArrayList(var10002), new Object[0]);
|
||||
} catch (Exception var2) {
|
||||
log.error("Token clear error", var2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public Long getSubjectId() {
|
||||
return this.subjectId;
|
||||
}
|
||||
|
||||
public String getSubjectName() {
|
||||
return this.subjectName;
|
||||
}
|
||||
|
||||
public Map<String, String> getSubjectData() {
|
||||
return this.subjectData;
|
||||
}
|
||||
|
||||
public String getScope() {
|
||||
return this.scope;
|
||||
}
|
||||
|
||||
public boolean isIdentified() {
|
||||
return this.identified;
|
||||
}
|
||||
|
||||
public long getCreateTime() {
|
||||
return this.createTime;
|
||||
}
|
||||
|
||||
public long getLastTime() {
|
||||
return this.lastTime;
|
||||
}
|
||||
|
||||
public void setId(final String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setSubjectId(final Long subjectId) {
|
||||
this.subjectId = subjectId;
|
||||
}
|
||||
|
||||
public void setSubjectName(final String subjectName) {
|
||||
this.subjectName = subjectName;
|
||||
}
|
||||
|
||||
public void setSubjectData(final Map<String, String> subjectData) {
|
||||
this.subjectData = subjectData;
|
||||
}
|
||||
|
||||
public void setScope(final String scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public void setIdentified(final boolean identified) {
|
||||
this.identified = identified;
|
||||
}
|
||||
|
||||
public void setCreateTime(final long createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public void setLastTime(final long lastTime) {
|
||||
this.lastTime = lastTime;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package com.bonus.config;
|
||||
|
||||
public interface AuthenticationPredicate {
|
||||
boolean authenticated(AccessToken accessToken);
|
||||
}
|
||||
|
|
@ -0,0 +1,366 @@
|
|||
package com.bonus.config;
|
||||
|
||||
import cn.hutool.core.codec.Base64Decoder;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
@RefreshScope
|
||||
@ConfigurationProperties(
|
||||
prefix = "secure"
|
||||
)
|
||||
public class SecureProperties {
|
||||
public static final String PREFIX = "secure";
|
||||
private boolean enabled = true;
|
||||
private boolean prohibitUnannotatedHandler = false;
|
||||
private String tokenSymbol = "X-Token";
|
||||
private String permissionKey = "secure:pms";
|
||||
private long permissionTTL = 7200L;
|
||||
private long expireAfter = 7200L;
|
||||
private ServerStore server = new ServerStore();
|
||||
private Security security = new Security();
|
||||
private MdcLogParameter mdc = new MdcLogParameter();
|
||||
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public boolean isProhibitUnannotatedHandler() {
|
||||
return this.prohibitUnannotatedHandler;
|
||||
}
|
||||
|
||||
public String getTokenSymbol() {
|
||||
return this.tokenSymbol;
|
||||
}
|
||||
|
||||
public String getPermissionKey() {
|
||||
return this.permissionKey;
|
||||
}
|
||||
|
||||
public long getPermissionTTL() {
|
||||
return this.permissionTTL;
|
||||
}
|
||||
|
||||
public long getExpireAfter() {
|
||||
return this.expireAfter;
|
||||
}
|
||||
|
||||
public ServerStore getServer() {
|
||||
return this.server;
|
||||
}
|
||||
|
||||
public Security getSecurity() {
|
||||
return this.security;
|
||||
}
|
||||
|
||||
public MdcLogParameter getMdc() {
|
||||
return this.mdc;
|
||||
}
|
||||
|
||||
public void setEnabled(final boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public void setProhibitUnannotatedHandler(final boolean prohibitUnannotatedHandler) {
|
||||
this.prohibitUnannotatedHandler = prohibitUnannotatedHandler;
|
||||
}
|
||||
|
||||
public void setTokenSymbol(final String tokenSymbol) {
|
||||
this.tokenSymbol = tokenSymbol;
|
||||
}
|
||||
|
||||
public void setPermissionKey(final String permissionKey) {
|
||||
this.permissionKey = permissionKey;
|
||||
}
|
||||
|
||||
public void setPermissionTTL(final long permissionTTL) {
|
||||
this.permissionTTL = permissionTTL;
|
||||
}
|
||||
|
||||
public void setExpireAfter(final long expireAfter) {
|
||||
this.expireAfter = expireAfter;
|
||||
}
|
||||
|
||||
public void setServer(final ServerStore server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
public void setSecurity(final Security security) {
|
||||
this.security = security;
|
||||
}
|
||||
|
||||
public void setMdc(final MdcLogParameter mdc) {
|
||||
this.mdc = mdc;
|
||||
}
|
||||
|
||||
public static class ServerStore {
|
||||
private String storeKey = "secure:token";
|
||||
private String subjectRefTokenKey = "secure:subject-token";
|
||||
private long ttl = 14400L;
|
||||
|
||||
public String getStoreKey() {
|
||||
return this.storeKey;
|
||||
}
|
||||
|
||||
public String getSubjectRefTokenKey() {
|
||||
return this.subjectRefTokenKey;
|
||||
}
|
||||
|
||||
public long getTtl() {
|
||||
return this.ttl;
|
||||
}
|
||||
|
||||
public void setStoreKey(final String storeKey) {
|
||||
this.storeKey = storeKey;
|
||||
}
|
||||
|
||||
public void setSubjectRefTokenKey(final String subjectRefTokenKey) {
|
||||
this.subjectRefTokenKey = subjectRefTokenKey;
|
||||
}
|
||||
|
||||
public void setTtl(final long ttl) {
|
||||
this.ttl = ttl;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Security {
|
||||
private String encryptUriPrefix = "/security";
|
||||
private String keyExchangePath = "/exchange/key";
|
||||
private String publicKeyExchangePath = "/exchange/public-key";
|
||||
private Set<String> ignoredUri = Sets.newHashSet();
|
||||
private String requestBodySignParamName = "body";
|
||||
private String clientKeySignParamName = "clientKey";
|
||||
private Set<String> addonSignHeaderPrefix = Sets.newHashSet(new String[]{"X-Security-Ext"});
|
||||
private Set<String> tokenHeaderNames = Sets.newHashSet(new String[]{"X-Security-Token", "X-Security-Tenant-Id", "X-Security-Sn"});
|
||||
private String tokenSignHeaderName = "X-Security-Token-Sign";
|
||||
private String serverKeySignParamName = "serverKey";
|
||||
private String serverSm4Key = "McaCOPft5/J3bUG4pdVjhg==";
|
||||
private byte[] serverSm4KeyBytes;
|
||||
private String serverSm2Key;
|
||||
private byte[] serverSm2KeyBytes;
|
||||
private String clientSm2Key;
|
||||
private byte[] clientSm2KeyBytes;
|
||||
private String timestampHeaderName;
|
||||
private String nonceHeaderName;
|
||||
private String signHeaderName;
|
||||
private String serverEncryptedClientKeyHeaderName;
|
||||
private long maxWindowSeconds;
|
||||
private String playKey;
|
||||
|
||||
public void setServerSm4Key(String serverSm4Key) {
|
||||
this.serverSm4Key = serverSm4Key;
|
||||
this.serverSm4KeyBytes = Base64Decoder.decode(serverSm4Key);
|
||||
}
|
||||
|
||||
public Security() {
|
||||
this.serverSm4KeyBytes = Base64Decoder.decode(this.serverSm4Key);
|
||||
this.serverSm2Key = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgCtqk5Jj7pPWh91d9mPA4Kd7fOfzBULrnAERNDV+4XBCgCgYIKoEcz1UBgi2hRANCAARykhB6sXHWTbB60Pr+laPqEP5JBRpEcySONKKP5Q03o/g3OpnQXc7aVMdLUxL8wD1wQHEu4KHmHQr7jvVt0rkM";
|
||||
this.serverSm2KeyBytes = Base64Decoder.decode(this.serverSm2Key);
|
||||
this.clientSm2Key = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEcpIQerFx1k2wetD6/pWj6hD+SQUaRHMkjjSij+UNN6P4NzqZ0F3O2lTHS1MS/MA9cEBxLuCh5h0K+471bdK5DA==";
|
||||
this.clientSm2KeyBytes = Base64Decoder.decode(this.serverSm2Key);
|
||||
this.timestampHeaderName = "X-Security-Timestamp";
|
||||
this.nonceHeaderName = "X-Security-Nonce";
|
||||
this.signHeaderName = "X-Security-Sign";
|
||||
this.serverEncryptedClientKeyHeaderName = "X-Security-Server-Encrypted-Client-Key";
|
||||
this.maxWindowSeconds = 90L;
|
||||
this.playKey = "__play:";
|
||||
}
|
||||
|
||||
public String getEncryptUriPrefix() {
|
||||
return this.encryptUriPrefix;
|
||||
}
|
||||
|
||||
public String getKeyExchangePath() {
|
||||
return this.keyExchangePath;
|
||||
}
|
||||
|
||||
public String getPublicKeyExchangePath() {
|
||||
return this.publicKeyExchangePath;
|
||||
}
|
||||
|
||||
public Set<String> getIgnoredUri() {
|
||||
return this.ignoredUri;
|
||||
}
|
||||
|
||||
public String getRequestBodySignParamName() {
|
||||
return this.requestBodySignParamName;
|
||||
}
|
||||
|
||||
public String getClientKeySignParamName() {
|
||||
return this.clientKeySignParamName;
|
||||
}
|
||||
|
||||
public Set<String> getAddonSignHeaderPrefix() {
|
||||
return this.addonSignHeaderPrefix;
|
||||
}
|
||||
|
||||
public Set<String> getTokenHeaderNames() {
|
||||
return this.tokenHeaderNames;
|
||||
}
|
||||
|
||||
public String getTokenSignHeaderName() {
|
||||
return this.tokenSignHeaderName;
|
||||
}
|
||||
|
||||
public String getServerKeySignParamName() {
|
||||
return this.serverKeySignParamName;
|
||||
}
|
||||
|
||||
public String getServerSm4Key() {
|
||||
return this.serverSm4Key;
|
||||
}
|
||||
|
||||
public byte[] getServerSm4KeyBytes() {
|
||||
return this.serverSm4KeyBytes;
|
||||
}
|
||||
|
||||
public String getServerSm2Key() {
|
||||
return this.serverSm2Key;
|
||||
}
|
||||
|
||||
public byte[] getServerSm2KeyBytes() {
|
||||
return this.serverSm2KeyBytes;
|
||||
}
|
||||
|
||||
public String getClientSm2Key() {
|
||||
return this.clientSm2Key;
|
||||
}
|
||||
|
||||
public byte[] getClientSm2KeyBytes() {
|
||||
return this.clientSm2KeyBytes;
|
||||
}
|
||||
|
||||
public String getTimestampHeaderName() {
|
||||
return this.timestampHeaderName;
|
||||
}
|
||||
|
||||
public String getNonceHeaderName() {
|
||||
return this.nonceHeaderName;
|
||||
}
|
||||
|
||||
public String getSignHeaderName() {
|
||||
return this.signHeaderName;
|
||||
}
|
||||
|
||||
public String getServerEncryptedClientKeyHeaderName() {
|
||||
return this.serverEncryptedClientKeyHeaderName;
|
||||
}
|
||||
|
||||
public long getMaxWindowSeconds() {
|
||||
return this.maxWindowSeconds;
|
||||
}
|
||||
|
||||
public String getPlayKey() {
|
||||
return this.playKey;
|
||||
}
|
||||
|
||||
public void setEncryptUriPrefix(final String encryptUriPrefix) {
|
||||
this.encryptUriPrefix = encryptUriPrefix;
|
||||
}
|
||||
|
||||
public void setKeyExchangePath(final String keyExchangePath) {
|
||||
this.keyExchangePath = keyExchangePath;
|
||||
}
|
||||
|
||||
public void setPublicKeyExchangePath(final String publicKeyExchangePath) {
|
||||
this.publicKeyExchangePath = publicKeyExchangePath;
|
||||
}
|
||||
|
||||
public void setIgnoredUri(final Set<String> ignoredUri) {
|
||||
this.ignoredUri = ignoredUri;
|
||||
}
|
||||
|
||||
public void setRequestBodySignParamName(final String requestBodySignParamName) {
|
||||
this.requestBodySignParamName = requestBodySignParamName;
|
||||
}
|
||||
|
||||
public void setClientKeySignParamName(final String clientKeySignParamName) {
|
||||
this.clientKeySignParamName = clientKeySignParamName;
|
||||
}
|
||||
|
||||
public void setAddonSignHeaderPrefix(final Set<String> addonSignHeaderPrefix) {
|
||||
this.addonSignHeaderPrefix = addonSignHeaderPrefix;
|
||||
}
|
||||
|
||||
public void setTokenHeaderNames(final Set<String> tokenHeaderNames) {
|
||||
this.tokenHeaderNames = tokenHeaderNames;
|
||||
}
|
||||
|
||||
public void setTokenSignHeaderName(final String tokenSignHeaderName) {
|
||||
this.tokenSignHeaderName = tokenSignHeaderName;
|
||||
}
|
||||
|
||||
public void setServerKeySignParamName(final String serverKeySignParamName) {
|
||||
this.serverKeySignParamName = serverKeySignParamName;
|
||||
}
|
||||
|
||||
public void setServerSm4KeyBytes(final byte[] serverSm4KeyBytes) {
|
||||
this.serverSm4KeyBytes = serverSm4KeyBytes;
|
||||
}
|
||||
|
||||
public void setServerSm2Key(final String serverSm2Key) {
|
||||
this.serverSm2Key = serverSm2Key;
|
||||
}
|
||||
|
||||
public void setServerSm2KeyBytes(final byte[] serverSm2KeyBytes) {
|
||||
this.serverSm2KeyBytes = serverSm2KeyBytes;
|
||||
}
|
||||
|
||||
public void setClientSm2Key(final String clientSm2Key) {
|
||||
this.clientSm2Key = clientSm2Key;
|
||||
}
|
||||
|
||||
public void setClientSm2KeyBytes(final byte[] clientSm2KeyBytes) {
|
||||
this.clientSm2KeyBytes = clientSm2KeyBytes;
|
||||
}
|
||||
|
||||
public void setTimestampHeaderName(final String timestampHeaderName) {
|
||||
this.timestampHeaderName = timestampHeaderName;
|
||||
}
|
||||
|
||||
public void setNonceHeaderName(final String nonceHeaderName) {
|
||||
this.nonceHeaderName = nonceHeaderName;
|
||||
}
|
||||
|
||||
public void setSignHeaderName(final String signHeaderName) {
|
||||
this.signHeaderName = signHeaderName;
|
||||
}
|
||||
|
||||
public void setServerEncryptedClientKeyHeaderName(final String serverEncryptedClientKeyHeaderName) {
|
||||
this.serverEncryptedClientKeyHeaderName = serverEncryptedClientKeyHeaderName;
|
||||
}
|
||||
|
||||
public void setMaxWindowSeconds(final long maxWindowSeconds) {
|
||||
this.maxWindowSeconds = maxWindowSeconds;
|
||||
}
|
||||
|
||||
public void setPlayKey(final String playKey) {
|
||||
this.playKey = playKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class MdcLogParameter {
|
||||
private String subjectId = "x-id";
|
||||
private String subjectName = "x-name";
|
||||
|
||||
public String getSubjectId() {
|
||||
return this.subjectId;
|
||||
}
|
||||
|
||||
public String getSubjectName() {
|
||||
return this.subjectName;
|
||||
}
|
||||
|
||||
public void setSubjectId(final String subjectId) {
|
||||
this.subjectId = subjectId;
|
||||
}
|
||||
|
||||
public void setSubjectName(final String subjectName) {
|
||||
this.subjectName = subjectName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
package com.bonus.config;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class WebContext {
|
||||
private static final ThreadLocal<Context> THREAD_CONTEXT = new InheritableThreadLocal<Context>() {
|
||||
protected Context initialValue() {
|
||||
return new Context();
|
||||
}
|
||||
};
|
||||
|
||||
private WebContext() {
|
||||
}
|
||||
|
||||
public static void reset() {
|
||||
THREAD_CONTEXT.remove();
|
||||
}
|
||||
|
||||
public static Context get() {
|
||||
return (Context)THREAD_CONTEXT.get();
|
||||
}
|
||||
|
||||
public static void set(Context context) {
|
||||
THREAD_CONTEXT.set(context);
|
||||
}
|
||||
|
||||
public static class Context {
|
||||
private HttpServletRequest request;
|
||||
private HttpServletResponse response;
|
||||
private AccessToken accessToken;
|
||||
private Map<String, Object> attributes = Maps.newHashMap();
|
||||
|
||||
public Context(HttpServletRequest request, HttpServletResponse response) {
|
||||
this.request = request;
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
public void setAttribute(String key, Object data) {
|
||||
this.attributes.put(key, data);
|
||||
}
|
||||
|
||||
public Object getAttribute(String key) {
|
||||
return this.attributes.get(key);
|
||||
}
|
||||
|
||||
public void removeAttribute(String key) {
|
||||
this.attributes.remove(key);
|
||||
}
|
||||
|
||||
public void clearAttribute() {
|
||||
this.attributes.clear();
|
||||
}
|
||||
|
||||
public Optional<AccessToken> getAccessToken() {
|
||||
return Optional.ofNullable(this.accessToken);
|
||||
}
|
||||
|
||||
public Optional<HttpServletRequest> getRequest() {
|
||||
return Optional.ofNullable(this.request);
|
||||
}
|
||||
|
||||
public Optional<HttpServletResponse> getResponse() {
|
||||
return Optional.ofNullable(this.response);
|
||||
}
|
||||
|
||||
public Map<String, Object> getAttributes() {
|
||||
return this.attributes;
|
||||
}
|
||||
|
||||
public void setRequest(final HttpServletRequest request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
public void setResponse(final HttpServletResponse response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
public void setAccessToken(final AccessToken accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
public void setAttributes(final Map<String, Object> attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public Context() {
|
||||
}
|
||||
|
||||
public Context(final HttpServletRequest request, final HttpServletResponse response, final AccessToken accessToken, final Map<String, Object> attributes) {
|
||||
this.request = request;
|
||||
this.response = response;
|
||||
this.accessToken = accessToken;
|
||||
this.attributes = attributes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.bonus.config.json;
|
||||
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.InstantSerializer;
|
||||
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public class InstantsSerializer extends InstantSerializer {
|
||||
public InstantsSerializer(DateTimeFormatter defaultFormat) {
|
||||
super(InstantSerializer.INSTANCE, false, defaultFormat);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
package com.bonus.config.json;
|
||||
|
||||
import com.bonus.config.WebContext;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.Module;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.PackageVersion;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.time.*;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.TimeZone;
|
||||
|
||||
@AutoConfiguration(
|
||||
before = {JacksonAutoConfiguration.class}
|
||||
)
|
||||
@ConditionalOnClass({ObjectMapper.class})
|
||||
public class JacksonConfiguration {
|
||||
public static final StdSerializer<Long> LONG_STD_SERIALIZER;
|
||||
|
||||
@Bean
|
||||
Jackson2ObjectMapperBuilderCustomizer objectMapperBuilderCustomizer() {
|
||||
return (builder) -> {
|
||||
builder.serializerByType(Long.TYPE, LONG_STD_SERIALIZER);
|
||||
builder.serializerByType(Long.class, LONG_STD_SERIALIZER);
|
||||
builder.locale(Locale.CHINA);
|
||||
builder.timeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
|
||||
builder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
builder.modules(new Module[]{new SimpleModule(PackageVersion.VERSION) {
|
||||
{
|
||||
this.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||
this.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
||||
this.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
||||
this.addSerializer(Instant.class, new InstantsSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));
|
||||
this.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||
this.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
||||
this.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
||||
}
|
||||
}});
|
||||
};
|
||||
}
|
||||
|
||||
static {
|
||||
LONG_STD_SERIALIZER = new StdSerializer<Long>(Long.TYPE) {
|
||||
@Override
|
||||
public void serialize(Long value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
|
||||
if (value == null) {
|
||||
jsonGenerator.writeNull();
|
||||
} else {
|
||||
Optional<HttpServletRequest> requestOptional = WebContext.get().getRequest();
|
||||
if ((Boolean)requestOptional.map((request) -> {
|
||||
return Objects.isNull(request.getHeader("User-Agent")) || request.getHeader("User-Agent").contains("okhttp");
|
||||
}).orElse(false)) {
|
||||
jsonGenerator.writeNumber(value);
|
||||
} else {
|
||||
jsonGenerator.writeString(value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue