修改为token认证方式
This commit is contained in:
@@ -17,7 +17,7 @@ buildscript {
|
|||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
group 'com.synebula'
|
group 'com.synebula'
|
||||||
version '1.4.0'
|
version '1.5.0'
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
|
|||||||
@@ -17,5 +17,6 @@ dependencies {
|
|||||||
api group: 'org.apache.poi', name: 'poi-ooxml', version: '5.0.0'
|
api group: 'org.apache.poi', name: 'poi-ooxml', version: '5.0.0'
|
||||||
api group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
|
api group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
|
||||||
api group: 'com.auth0', name: 'java-jwt', version: '3.14.0'
|
api group: 'com.auth0', name: 'java-jwt', version: '3.14.0'
|
||||||
|
api group: 'com.google.guava', name: 'guava', version: '31.1-jre'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ package com.synebula.gaea.app
|
|||||||
|
|
||||||
import com.synebula.gaea.app.cmd.ICommandApp
|
import com.synebula.gaea.app.cmd.ICommandApp
|
||||||
import com.synebula.gaea.app.query.IQueryApp
|
import com.synebula.gaea.app.query.IQueryApp
|
||||||
import com.synebula.gaea.data.serialization.json.IJsonSerializer
|
import com.synebula.gaea.data.message.HttpMessageFactory
|
||||||
import com.synebula.gaea.domain.service.ICommand
|
import com.synebula.gaea.domain.service.ICommand
|
||||||
import com.synebula.gaea.domain.service.IService
|
import com.synebula.gaea.domain.service.IService
|
||||||
import com.synebula.gaea.log.ILogger
|
import com.synebula.gaea.log.ILogger
|
||||||
import com.synebula.gaea.query.IQuery
|
import com.synebula.gaea.query.IQuery
|
||||||
import javax.annotation.Resource
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 联合服务,同时实现了ICommandApp和IQueryApp接口
|
* 联合服务,同时实现了ICommandApp和IQueryApp接口
|
||||||
@@ -24,6 +24,6 @@ open class Application<TCommand : ICommand, TView, ID>(
|
|||||||
override var logger: ILogger,
|
override var logger: ILogger,
|
||||||
) : ICommandApp<TCommand, ID>, IQueryApp<TView, ID> {
|
) : ICommandApp<TCommand, ID>, IQueryApp<TView, ID> {
|
||||||
|
|
||||||
@Resource
|
@Autowired
|
||||||
override var jsonSerializer: IJsonSerializer? = null
|
override lateinit var httpMessageFactory: HttpMessageFactory
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ package com.synebula.gaea.app
|
|||||||
|
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.synebula.gaea.data.message.HttpMessage
|
import com.synebula.gaea.data.message.HttpMessage
|
||||||
|
import com.synebula.gaea.data.message.HttpMessageFactory
|
||||||
import com.synebula.gaea.data.message.Status
|
import com.synebula.gaea.data.message.Status
|
||||||
import com.synebula.gaea.log.ILogger
|
import com.synebula.gaea.log.ILogger
|
||||||
import org.springframework.security.core.context.SecurityContextHolder
|
import org.springframework.security.core.context.SecurityContextHolder
|
||||||
@@ -18,12 +19,17 @@ interface IApplication {
|
|||||||
*/
|
*/
|
||||||
var logger: ILogger
|
var logger: ILogger
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日志详细的构造器
|
||||||
|
*/
|
||||||
|
var httpMessageFactory: HttpMessageFactory
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 安全执行
|
* 安全执行
|
||||||
*/
|
*/
|
||||||
fun safeExecute(error: String, process: ((msg: HttpMessage) -> Unit)): HttpMessage {
|
fun safeExecute(error: String, process: ((msg: HttpMessage) -> Unit)): HttpMessage {
|
||||||
val msg = HttpMessage()
|
val msg = this.httpMessageFactory.create()
|
||||||
try {
|
try {
|
||||||
process(msg)
|
process(msg)
|
||||||
logger.debug(this, "$name business execute success")
|
logger.debug(this, "$name business execute success")
|
||||||
@@ -39,7 +45,7 @@ interface IApplication {
|
|||||||
* 可抛出自定义异常信息的安全controller实现了异常捕获和消息组成。
|
* 可抛出自定义异常信息的安全controller实现了异常捕获和消息组成。
|
||||||
*/
|
*/
|
||||||
fun throwExecute(error: String, process: ((msg: HttpMessage) -> Unit)): HttpMessage {
|
fun throwExecute(error: String, process: ((msg: HttpMessage) -> Unit)): HttpMessage {
|
||||||
val msg = HttpMessage()
|
val msg = this.httpMessageFactory.create()
|
||||||
try {
|
try {
|
||||||
process(msg)
|
process(msg)
|
||||||
logger.debug(this, "$name business execute success")
|
logger.debug(this, "$name business execute success")
|
||||||
@@ -54,7 +60,7 @@ interface IApplication {
|
|||||||
* 获取用户信息
|
* 获取用户信息
|
||||||
* @param clazz 用户信息结构类
|
* @param clazz 用户信息结构类
|
||||||
*/
|
*/
|
||||||
fun <T> sessionUser(clazz: Class<T>): T? {
|
fun <T> userSession(clazz: Class<T>): T? {
|
||||||
try {
|
try {
|
||||||
val authentication = SecurityContextHolder.getContext().authentication.principal.toString()
|
val authentication = SecurityContextHolder.getContext().authentication.principal.toString()
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ package com.synebula.gaea.app
|
|||||||
|
|
||||||
import com.synebula.gaea.app.cmd.ISimpleCommandApp
|
import com.synebula.gaea.app.cmd.ISimpleCommandApp
|
||||||
import com.synebula.gaea.app.query.IQueryApp
|
import com.synebula.gaea.app.query.IQueryApp
|
||||||
import com.synebula.gaea.data.serialization.json.IJsonSerializer
|
import com.synebula.gaea.data.message.HttpMessageFactory
|
||||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||||
import com.synebula.gaea.domain.service.ISimpleService
|
import com.synebula.gaea.domain.service.ISimpleService
|
||||||
import com.synebula.gaea.log.ILogger
|
import com.synebula.gaea.log.ILogger
|
||||||
import com.synebula.gaea.query.IQuery
|
import com.synebula.gaea.query.IQuery
|
||||||
import javax.annotation.Resource
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 简单的服务, 取消了Command对象
|
* 简单的服务, 取消了Command对象
|
||||||
@@ -24,6 +24,7 @@ open class SimpleApplication<TRoot : IAggregateRoot<ID>, ID>(
|
|||||||
override var logger: ILogger,
|
override var logger: ILogger,
|
||||||
) : ISimpleCommandApp<TRoot, ID>, IQueryApp<TRoot, ID> {
|
) : ISimpleCommandApp<TRoot, ID>, IQueryApp<TRoot, ID> {
|
||||||
|
|
||||||
@Resource
|
|
||||||
override var jsonSerializer: IJsonSerializer? = null
|
@Autowired
|
||||||
|
override lateinit var httpMessageFactory: HttpMessageFactory
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.synebula.gaea.app.cmd
|
package com.synebula.gaea.app.cmd
|
||||||
|
|
||||||
import com.synebula.gaea.data.serialization.json.IJsonSerializer
|
import com.synebula.gaea.data.message.HttpMessageFactory
|
||||||
import com.synebula.gaea.domain.service.ICommand
|
import com.synebula.gaea.domain.service.ICommand
|
||||||
import com.synebula.gaea.domain.service.IService
|
import com.synebula.gaea.domain.service.IService
|
||||||
import com.synebula.gaea.log.ILogger
|
import com.synebula.gaea.log.ILogger
|
||||||
import javax.annotation.Resource
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 指令服务,同时实现ICommandApp
|
* 指令服务,同时实现ICommandApp
|
||||||
@@ -18,6 +18,6 @@ open class CommandApp<TCommand : ICommand, ID>(
|
|||||||
override var service: IService<ID>,
|
override var service: IService<ID>,
|
||||||
override var logger: ILogger,
|
override var logger: ILogger,
|
||||||
) : ICommandApp<TCommand, ID> {
|
) : ICommandApp<TCommand, ID> {
|
||||||
@Resource
|
@Autowired
|
||||||
override var jsonSerializer: IJsonSerializer? = null
|
override lateinit var httpMessageFactory: HttpMessageFactory
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,6 @@ package com.synebula.gaea.app.cmd
|
|||||||
import com.synebula.gaea.app.IApplication
|
import com.synebula.gaea.app.IApplication
|
||||||
import com.synebula.gaea.data.message.HttpMessage
|
import com.synebula.gaea.data.message.HttpMessage
|
||||||
import com.synebula.gaea.data.message.Status
|
import com.synebula.gaea.data.message.Status
|
||||||
import com.synebula.gaea.data.serialization.json.IJsonSerializer
|
|
||||||
import com.synebula.gaea.domain.service.ICommand
|
import com.synebula.gaea.domain.service.ICommand
|
||||||
import com.synebula.gaea.domain.service.IService
|
import com.synebula.gaea.domain.service.IService
|
||||||
import com.synebula.gaea.spring.aop.annotation.Method
|
import com.synebula.gaea.spring.aop.annotation.Method
|
||||||
@@ -17,27 +16,25 @@ import org.springframework.web.bind.annotation.*
|
|||||||
* @since 2020-05-15
|
* @since 2020-05-15
|
||||||
*/
|
*/
|
||||||
interface ICommandApp<TCommand : ICommand, ID> : IApplication {
|
interface ICommandApp<TCommand : ICommand, ID> : IApplication {
|
||||||
var jsonSerializer: IJsonSerializer?
|
|
||||||
|
|
||||||
var service: IService<ID>
|
var service: IService<ID>
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
@Method("添加")
|
@Method("添加")
|
||||||
fun add(@RequestBody command: TCommand): HttpMessage {
|
fun add(@RequestBody command: TCommand): HttpMessage {
|
||||||
return HttpMessage(service.add(command))
|
return this.httpMessageFactory.create(service.add(command))
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/{id:.+}")
|
@PutMapping("/{id:.+}")
|
||||||
@Method("更新")
|
@Method("更新")
|
||||||
fun update(@PathVariable id: ID, @RequestBody command: TCommand): HttpMessage {
|
fun update(@PathVariable id: ID, @RequestBody command: TCommand): HttpMessage {
|
||||||
this.service.update(id, command)
|
this.service.update(id, command)
|
||||||
return HttpMessage()
|
return this.httpMessageFactory.create()
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping("/{id:.+}")
|
@DeleteMapping("/{id:.+}")
|
||||||
@Method("删除")
|
@Method("删除")
|
||||||
fun remove(@PathVariable id: ID): HttpMessage {
|
fun remove(@PathVariable id: ID): HttpMessage {
|
||||||
val msg = HttpMessage()
|
val msg = this.httpMessageFactory.create()
|
||||||
try {
|
try {
|
||||||
msg.data = this.service.remove(id)
|
msg.data = this.service.remove(id)
|
||||||
} catch (ex: IllegalStateException) {
|
} catch (ex: IllegalStateException) {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package com.synebula.gaea.app.cmd
|
|||||||
import com.synebula.gaea.app.IApplication
|
import com.synebula.gaea.app.IApplication
|
||||||
import com.synebula.gaea.data.message.HttpMessage
|
import com.synebula.gaea.data.message.HttpMessage
|
||||||
import com.synebula.gaea.data.message.Status
|
import com.synebula.gaea.data.message.Status
|
||||||
import com.synebula.gaea.data.serialization.json.IJsonSerializer
|
|
||||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||||
import com.synebula.gaea.domain.service.ISimpleService
|
import com.synebula.gaea.domain.service.ISimpleService
|
||||||
import com.synebula.gaea.spring.aop.annotation.Method
|
import com.synebula.gaea.spring.aop.annotation.Method
|
||||||
@@ -17,27 +16,25 @@ import org.springframework.web.bind.annotation.*
|
|||||||
* @since 2020-05-15
|
* @since 2020-05-15
|
||||||
*/
|
*/
|
||||||
interface ISimpleCommandApp<TRoot : IAggregateRoot<ID>, ID> : IApplication {
|
interface ISimpleCommandApp<TRoot : IAggregateRoot<ID>, ID> : IApplication {
|
||||||
var jsonSerializer: IJsonSerializer?
|
|
||||||
|
|
||||||
var service: ISimpleService<TRoot, ID>
|
var service: ISimpleService<TRoot, ID>
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
@Method("添加")
|
@Method("添加")
|
||||||
fun add(@RequestBody entity: TRoot): HttpMessage {
|
fun add(@RequestBody entity: TRoot): HttpMessage {
|
||||||
return HttpMessage(service.add(entity))
|
return this.httpMessageFactory.create(service.add(entity))
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/{id:.+}")
|
@PutMapping("/{id:.+}")
|
||||||
@Method("更新")
|
@Method("更新")
|
||||||
fun update(@PathVariable id: ID, @RequestBody entity: TRoot): HttpMessage {
|
fun update(@PathVariable id: ID, @RequestBody entity: TRoot): HttpMessage {
|
||||||
this.service.update(id, entity)
|
this.service.update(id, entity)
|
||||||
return HttpMessage()
|
return this.httpMessageFactory.create()
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping("/{id:.+}")
|
@DeleteMapping("/{id:.+}")
|
||||||
@Method("删除")
|
@Method("删除")
|
||||||
fun remove(@PathVariable id: ID): HttpMessage {
|
fun remove(@PathVariable id: ID): HttpMessage {
|
||||||
val msg = HttpMessage()
|
val msg = this.httpMessageFactory.create()
|
||||||
try {
|
try {
|
||||||
msg.data = this.service.remove(id)
|
msg.data = this.service.remove(id)
|
||||||
} catch (ex: IllegalStateException) {
|
} catch (ex: IllegalStateException) {
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.synebula.gaea.app.cmd
|
package com.synebula.gaea.app.cmd
|
||||||
|
|
||||||
import com.synebula.gaea.data.serialization.json.IJsonSerializer
|
import com.synebula.gaea.data.message.HttpMessageFactory
|
||||||
import com.synebula.gaea.domain.model.IAggregateRoot
|
import com.synebula.gaea.domain.model.IAggregateRoot
|
||||||
import com.synebula.gaea.domain.service.ISimpleService
|
import com.synebula.gaea.domain.service.ISimpleService
|
||||||
import com.synebula.gaea.log.ILogger
|
import com.synebula.gaea.log.ILogger
|
||||||
import javax.annotation.Resource
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 指令服务,同时实现ICommandApp
|
* 指令服务,同时实现ICommandApp
|
||||||
@@ -18,6 +18,6 @@ open class SimpleCommandApp<TRoot : IAggregateRoot<ID>, ID>(
|
|||||||
override var service: ISimpleService<TRoot, ID>,
|
override var service: ISimpleService<TRoot, ID>,
|
||||||
override var logger: ILogger,
|
override var logger: ILogger,
|
||||||
) : ISimpleCommandApp<TRoot, ID> {
|
) : ISimpleCommandApp<TRoot, ID> {
|
||||||
@Resource
|
@Autowired
|
||||||
override var jsonSerializer: IJsonSerializer? = null
|
override lateinit var httpMessageFactory: HttpMessageFactory
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ import org.dozer.DozerBeanMapper
|
|||||||
import org.springframework.stereotype.Component
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
class DozerConverter : IObjectMapper {
|
class DozerMapper : IObjectMapper {
|
||||||
private val converter = DozerBeanMapper()
|
private val converter = DozerBeanMapper()
|
||||||
|
|
||||||
override fun <T> deserialize(src: Any, targetClass: Class<T>): T = converter.map(src, targetClass)
|
override fun <T> deserialize(src: Any, targetClass: Class<T>): T = converter.map(src, targetClass)
|
||||||
101
src/gaea.app/src/main/kotlin/com/synebula/gaea/app/component/cache/Cache.kt
vendored
Normal file
101
src/gaea.app/src/main/kotlin/com/synebula/gaea/app/component/cache/Cache.kt
vendored
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
package com.synebula.gaea.app.component.cache
|
||||||
|
|
||||||
|
import com.google.common.cache.Cache
|
||||||
|
import com.google.common.cache.CacheBuilder
|
||||||
|
import com.synebula.gaea.data.cache.ICache
|
||||||
|
import java.util.concurrent.ConcurrentMap
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存组件
|
||||||
|
*
|
||||||
|
* @param expire 滑动过期时间,单位秒
|
||||||
|
*/
|
||||||
|
open class Cache<K, V>(expire: Int) : ICache<K, V> {
|
||||||
|
|
||||||
|
private val guavaCache: Cache<K, V>
|
||||||
|
|
||||||
|
init {
|
||||||
|
var builder = CacheBuilder.newBuilder()
|
||||||
|
if (expire != 0) {
|
||||||
|
builder = builder.expireAfterAccess(expire.toLong(), TimeUnit.SECONDS)
|
||||||
|
}
|
||||||
|
this.guavaCache = builder.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun add(key: K, value: V) {
|
||||||
|
this.guavaCache.put(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加多条缓存记录
|
||||||
|
*
|
||||||
|
* @param entries 需要添加的多条缓存记录Map
|
||||||
|
*/
|
||||||
|
override fun add(entries: Map<K, V>) {
|
||||||
|
this.guavaCache.putAll(entries)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun get(key: K): V? {
|
||||||
|
return this.guavaCache.getIfPresent(key ?: "")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取给出列表key中存在的缓存元素
|
||||||
|
*
|
||||||
|
* @param keys 尝试获取的key列表
|
||||||
|
*/
|
||||||
|
override fun get(keys: Iterable<K>): Map<K, V> {
|
||||||
|
return this.guavaCache.getAllPresent(keys)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除给出key的缓存
|
||||||
|
*
|
||||||
|
* @param key 需要清楚的缓存key
|
||||||
|
*/
|
||||||
|
override fun remove(key: K) {
|
||||||
|
this.guavaCache.invalidate(key ?: "")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除给出列表key的缓存
|
||||||
|
*
|
||||||
|
* @param keys 需要清楚的缓存key列表
|
||||||
|
*/
|
||||||
|
override fun remove(keys: Iterable<K>) {
|
||||||
|
this.guavaCache.invalidateAll(keys)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断keys是否存在
|
||||||
|
*
|
||||||
|
* @param keys 需要判断的缓存key列表
|
||||||
|
*/
|
||||||
|
override fun exists(keys: Iterable<K>): Map<K, Boolean> {
|
||||||
|
val result = mutableMapOf<K, Boolean>()
|
||||||
|
keys.forEach { result[it] = guavaCache.asMap().containsKey(it) }
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断key是否存在
|
||||||
|
*
|
||||||
|
* @param key 需要判断的key
|
||||||
|
*/
|
||||||
|
override fun exists(key: K): Boolean {
|
||||||
|
return this.guavaCache.asMap().containsKey(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除所有缓存记录
|
||||||
|
*/
|
||||||
|
override fun clear() {
|
||||||
|
this.guavaCache.cleanUp()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun asMap(): ConcurrentMap<K, V> {
|
||||||
|
return this.guavaCache.asMap()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
package com.synebula.gaea.app.component.security
|
package com.synebula.gaea.app.component.security
|
||||||
|
|
||||||
import com.synebula.gaea.app.struct.exception.TokenCloseExpireException
|
import com.synebula.gaea.app.component.security.session.UserSessionManager
|
||||||
import com.synebula.gaea.data.message.HttpMessage
|
import com.synebula.gaea.data.message.HttpMessageFactory
|
||||||
import com.synebula.gaea.data.message.Status
|
import com.synebula.gaea.data.message.Status
|
||||||
import org.springframework.security.authentication.AuthenticationManager
|
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
|
||||||
import org.springframework.security.core.context.SecurityContextHolder
|
import org.springframework.security.core.context.SecurityContextHolder
|
||||||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter
|
import org.springframework.web.filter.OncePerRequestFilter
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import javax.servlet.FilterChain
|
import javax.servlet.FilterChain
|
||||||
import javax.servlet.ServletException
|
import javax.servlet.ServletException
|
||||||
@@ -16,27 +15,50 @@ import javax.servlet.http.HttpServletResponse
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录成功后 走此类进行鉴权操作
|
* 登录成功后 走此类进行鉴权操作
|
||||||
|
*
|
||||||
|
* @param httpMessageFactory HttpMessage 构建器
|
||||||
|
* @param userSessionManager 用户信息缓存
|
||||||
|
* @param storage 存储识别信息存储方式 token/cookie
|
||||||
*/
|
*/
|
||||||
class WebAuthorization(authenticationManager: AuthenticationManager, var tokenManager: TokenManager) :
|
class WebAuthorization(
|
||||||
BasicAuthenticationFilter(authenticationManager) {
|
var httpMessageFactory: HttpMessageFactory,
|
||||||
|
var userSessionManager: UserSessionManager,
|
||||||
|
var storage: String = "token"
|
||||||
|
) : OncePerRequestFilter() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* token 在 header 中的 key
|
||||||
|
*/
|
||||||
|
private val tokenKey = "token"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在过滤之前和之后执行的事件
|
* 在过滤之前和之后执行的事件
|
||||||
*/
|
*/
|
||||||
@Throws(IOException::class, ServletException::class)
|
@Throws(IOException::class, ServletException::class)
|
||||||
override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, chain: FilterChain) {
|
override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, chain: FilterChain) {
|
||||||
val token = request.getHeader(tokenManager.header)
|
val identity = if (this.storage == "cookie") {
|
||||||
try {
|
request.cookies.find { it.name == tokenKey }?.value ?: ""
|
||||||
val user = tokenManager.verify(token)
|
} else {
|
||||||
val authentication =
|
request.getHeader(tokenKey) ?: ""
|
||||||
UsernamePasswordAuthenticationToken(user, null, null)
|
}
|
||||||
|
val user = this.userSessionManager.userSession(identity)
|
||||||
|
if (user != null) {
|
||||||
|
user.ip = request.remoteAddr
|
||||||
|
user.url = request.requestURI
|
||||||
|
val authentication = UsernamePasswordAuthenticationToken(user, null, null)
|
||||||
SecurityContextHolder.getContext().authentication = authentication
|
SecurityContextHolder.getContext().authentication = authentication
|
||||||
super.doFilterInternal(request, response, chain)
|
chain.doFilter(request, response)
|
||||||
} catch (ex: TokenCloseExpireException) {
|
} else {
|
||||||
response.status = Status.Success
|
response.status = Status.Success
|
||||||
response.characterEncoding = "utf-8"
|
response.characterEncoding = "utf-8"
|
||||||
response.contentType = "text/javascript;charset=utf-8"
|
response.contentType = "text/javascript;charset=utf-8"
|
||||||
response.writer.print(HttpMessage(Status.Reauthorize, tokenManager.sign(ex.payload), "重新下发认证消息"))
|
response.writer.print(
|
||||||
|
this.httpMessageFactory.create(
|
||||||
|
Status.Unauthorized,
|
||||||
|
"登录信息失效, 请重新登录"
|
||||||
|
)
|
||||||
|
)
|
||||||
response.flushBuffer()
|
response.flushBuffer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,56 +1,68 @@
|
|||||||
package com.synebula.gaea.app.component.security
|
package com.synebula.gaea.app.component.security
|
||||||
|
|
||||||
import com.synebula.gaea.data.message.HttpMessage
|
import com.synebula.gaea.app.component.security.session.UserSessionManager
|
||||||
|
import com.synebula.gaea.data.message.HttpMessageFactory
|
||||||
import com.synebula.gaea.data.message.Status
|
import com.synebula.gaea.data.message.Status
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.beans.factory.annotation.Value
|
||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.security.authentication.AuthenticationManager
|
import org.springframework.context.annotation.Configuration
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy
|
import org.springframework.security.config.http.SessionCreationPolicy
|
||||||
import org.springframework.security.web.SecurityFilterChain
|
import org.springframework.security.web.SecurityFilterChain
|
||||||
import org.springframework.stereotype.Component
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
|
||||||
import org.springframework.web.cors.CorsConfiguration
|
import org.springframework.web.cors.CorsConfiguration
|
||||||
import org.springframework.web.cors.CorsConfigurationSource
|
import org.springframework.web.cors.CorsConfigurationSource
|
||||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource
|
||||||
|
|
||||||
|
|
||||||
@Component
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
class WebSecurity {
|
class WebSecurity {
|
||||||
@Autowired
|
@Autowired
|
||||||
lateinit var tokenManager: TokenManager
|
lateinit var userSessionManager: UserSessionManager
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
lateinit var authenticationManager: AuthenticationManager
|
lateinit var httpMessageFactory: HttpMessageFactory
|
||||||
|
|
||||||
|
@Value("\${spring.sign-in-url}")
|
||||||
|
var signInPath = "/sign/in"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 安全配置
|
* 安全配置
|
||||||
*/
|
*/
|
||||||
|
@Bean
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun filterChain(http: HttpSecurity): SecurityFilterChain {
|
fun filterChain(httpSecurity: HttpSecurity): SecurityFilterChain {
|
||||||
// 跨域共享
|
httpSecurity.cors().and().csrf().disable() // 跨域伪造请求限制无效
|
||||||
http.cors()
|
// 设置Session的创建策略为:Spring Security永不创建HttpSession 不使用HttpSession来获取SecurityContext
|
||||||
.and().csrf().disable() // 跨域伪造请求限制无效
|
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||||
.authorizeRequests()
|
// 除了登录接口其他资源都必须登录访问
|
||||||
.anyRequest().authenticated()// 资源任何人都可访问
|
.and().authorizeRequests().antMatchers(this.signInPath).permitAll().anyRequest().authenticated()
|
||||||
.and()
|
// 添加鉴权拦截器
|
||||||
.addFilter(WebAuthorization(authenticationManager, tokenManager))// 添加JWT鉴权拦截器
|
.and().addFilterBefore(
|
||||||
.sessionManagement()
|
WebAuthorization(httpMessageFactory, userSessionManager),
|
||||||
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 设置Session的创建策略为:Spring Security永不创建HttpSession 不使用HttpSession来获取SecurityContext
|
UsernamePasswordAuthenticationFilter::class.java
|
||||||
.and()
|
).exceptionHandling().authenticationEntryPoint { _, response, _ ->
|
||||||
.exceptionHandling()
|
|
||||||
.authenticationEntryPoint { _, response, _ ->
|
|
||||||
response.status = Status.Success
|
response.status = Status.Success
|
||||||
response.characterEncoding = "utf-8"
|
response.characterEncoding = "utf-8"
|
||||||
response.contentType = "text/javascript;charset=utf-8"
|
response.contentType = "text/javascript;charset=utf-8"
|
||||||
response.writer.print(HttpMessage(Status.Unauthorized, "用户未登录,请重新登录后尝试!"))
|
response.writer.print(
|
||||||
|
this.httpMessageFactory.create(
|
||||||
|
Status.Unauthorized, "用户未登录,请重新登录后尝试!"
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return http.build()
|
|
||||||
|
return httpSecurity.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun filterChain(): WebSecurityCustomizer {
|
fun ignoringCustomizer(): WebSecurityCustomizer {
|
||||||
return WebSecurityCustomizer { web -> web.ignoring().antMatchers("/sign/**") }
|
return WebSecurityCustomizer { web -> web.ignoring().antMatchers(this.signInPath) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.synebula.gaea.app.component.security.session
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登陆用户会话信息
|
||||||
|
*
|
||||||
|
* @param uid 用户id
|
||||||
|
* @param user 用户信息
|
||||||
|
*/
|
||||||
|
class UserSession(var uid: String, var user: Any) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录IP
|
||||||
|
*/
|
||||||
|
var ip = ""
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 访问的url
|
||||||
|
*/
|
||||||
|
var url = ""
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前token
|
||||||
|
*/
|
||||||
|
var token = ""
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定类型的用户信息
|
||||||
|
*/
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
fun <T> user(): T {
|
||||||
|
return user as T
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.synebula.gaea.app.component.security.session
|
||||||
|
|
||||||
|
import com.synebula.gaea.app.component.cache.Cache
|
||||||
|
import com.synebula.gaea.ext.toMd5
|
||||||
|
import org.springframework.beans.factory.annotation.Value
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class UserSessionManager {
|
||||||
|
|
||||||
|
@Value("\${spring.allow-multi-sign}")
|
||||||
|
private var allowMultiSign = "true"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户id加盐, (尽量)避免泄漏真是用户id
|
||||||
|
*/
|
||||||
|
private val salt = "68d84e0d7b9e"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* token分割符
|
||||||
|
*/
|
||||||
|
private val delimiter = "-"
|
||||||
|
|
||||||
|
// 用户的实际信息
|
||||||
|
var userSessionCache = Cache<String, UserSession>(7 * 24 * 60 * 60)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户登入方法
|
||||||
|
*/
|
||||||
|
fun signIn(uid: String, user: Any): String {
|
||||||
|
val session = UserSession(uid, user)
|
||||||
|
val id = "$uid$delimiter$salt".toMd5()
|
||||||
|
if (allowMultiSign != true.toString()) {
|
||||||
|
if (userSessionCache.asMap().keys.any { k -> k.split(delimiter).last() == id })
|
||||||
|
throw UnsupportedOperationException("用户已在另一客户端登录, 请退出后重新尝试登录")
|
||||||
|
}
|
||||||
|
val token = "${UUID.randomUUID()}$delimiter${id}"
|
||||||
|
session.token = token
|
||||||
|
userSessionCache.add(token, session)
|
||||||
|
return token
|
||||||
|
}
|
||||||
|
|
||||||
|
fun signOut(token: String) {
|
||||||
|
this.userSessionCache.remove(token)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun userSession(token: String): UserSession? {
|
||||||
|
return userSessionCache[token]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,7 @@ interface IQueryApp<TView, ID> : IApplication {
|
|||||||
@GetMapping("/{id:.+}")
|
@GetMapping("/{id:.+}")
|
||||||
fun get(@PathVariable id: ID): HttpMessage {
|
fun get(@PathVariable id: ID): HttpMessage {
|
||||||
val data = this.query.get(id)
|
val data = this.query.get(id)
|
||||||
val msg = HttpMessage()
|
val msg = this.httpMessageFactory.create()
|
||||||
msg.data = data
|
msg.data = data
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ interface IQueryApp<TView, ID> : IApplication {
|
|||||||
@GetMapping
|
@GetMapping
|
||||||
fun list(@RequestParam params: LinkedHashMap<String, String>): HttpMessage {
|
fun list(@RequestParam params: LinkedHashMap<String, String>): HttpMessage {
|
||||||
val data = this.query.list(params)
|
val data = this.query.list(params)
|
||||||
return HttpMessage(data)
|
return this.httpMessageFactory.create(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Method("获取分页数据")
|
@Method("获取分页数据")
|
||||||
@@ -40,6 +40,6 @@ interface IQueryApp<TView, ID> : IApplication {
|
|||||||
): HttpMessage {
|
): HttpMessage {
|
||||||
val params = Params(page, size, parameters)
|
val params = Params(page, size, parameters)
|
||||||
val data = this.query.paging(params)
|
val data = this.query.paging(params)
|
||||||
return HttpMessage(data)
|
return this.httpMessageFactory.create(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
package com.synebula.gaea.app.query
|
package com.synebula.gaea.app.query
|
||||||
|
|
||||||
|
import com.synebula.gaea.data.message.HttpMessageFactory
|
||||||
import com.synebula.gaea.log.ILogger
|
import com.synebula.gaea.log.ILogger
|
||||||
import com.synebula.gaea.query.IQuery
|
import com.synebula.gaea.query.IQuery
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 联合服务,同时实现了ICommandApp和IQueryApp接口
|
* 联合服务,同时实现了ICommandApp和IQueryApp接口
|
||||||
@@ -14,4 +16,8 @@ open class QueryApp<TView, ID>(
|
|||||||
override var name: String,
|
override var name: String,
|
||||||
override var query: IQuery<TView, ID>,
|
override var query: IQuery<TView, ID>,
|
||||||
override var logger: ILogger,
|
override var logger: ILogger,
|
||||||
) : IQueryApp<TView, ID>
|
) : IQueryApp<TView, ID> {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
override lateinit var httpMessageFactory: HttpMessageFactory
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.synebula.gaea.spring.aop
|
package com.synebula.gaea.spring.aop
|
||||||
|
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.synebula.gaea.data.message.HttpMessage
|
import com.synebula.gaea.data.message.HttpMessageFactory
|
||||||
import com.synebula.gaea.data.message.Status
|
import com.synebula.gaea.data.message.Status
|
||||||
import com.synebula.gaea.exception.NoticeUserException
|
import com.synebula.gaea.exception.NoticeUserException
|
||||||
import com.synebula.gaea.log.ILogger
|
import com.synebula.gaea.log.ILogger
|
||||||
@@ -25,6 +25,9 @@ abstract class AppAspect {
|
|||||||
@Autowired
|
@Autowired
|
||||||
lateinit var applicationContext: ApplicationContext
|
lateinit var applicationContext: ApplicationContext
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
lateinit var httpMessageFactory: HttpMessageFactory
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定义切面的方法
|
* 定义切面的方法
|
||||||
*/
|
*/
|
||||||
@@ -74,7 +77,7 @@ abstract class AppAspect {
|
|||||||
gson.toJson(point.args)
|
gson.toJson(point.args)
|
||||||
}"
|
}"
|
||||||
)
|
)
|
||||||
return HttpMessage(Status.Error, message)
|
return this.httpMessageFactory.create(Status.Error, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,4 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007 The Guava Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.synebula.gaea.bus
|
package com.synebula.gaea.bus
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,16 +1,4 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007 The Guava Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.synebula.gaea.bus
|
package com.synebula.gaea.bus
|
||||||
|
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
|
|||||||
@@ -1,16 +1,4 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007 The Guava Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.synebula.gaea.bus
|
package com.synebula.gaea.bus
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,16 +1,4 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 The Guava Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.synebula.gaea.bus
|
package com.synebula.gaea.bus
|
||||||
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|||||||
@@ -1,16 +1,4 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007 The Guava Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.synebula.gaea.bus
|
package com.synebula.gaea.bus
|
||||||
|
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|||||||
@@ -1,16 +1,4 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007 The Guava Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.synebula.gaea.bus
|
package com.synebula.gaea.bus
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,16 +1,4 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 The Guava Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.synebula.gaea.bus
|
package com.synebula.gaea.bus
|
||||||
|
|
||||||
import com.synebula.gaea.exception.NoticeUserException
|
import com.synebula.gaea.exception.NoticeUserException
|
||||||
|
|||||||
@@ -1,16 +1,4 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 The Guava Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.synebula.gaea.bus
|
package com.synebula.gaea.bus
|
||||||
|
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
|
|||||||
@@ -1,16 +1,4 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2013 The Guava Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.synebula.gaea.bus
|
package com.synebula.gaea.bus
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,16 +1,4 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 The Guava Authors
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
||||||
* in compliance with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
||||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing permissions and limitations under
|
|
||||||
* the License.
|
|
||||||
*/
|
|
||||||
package com.synebula.gaea.bus
|
package com.synebula.gaea.bus
|
||||||
|
|
||||||
import com.synebula.gaea.data.message.messageTopic
|
import com.synebula.gaea.data.message.messageTopic
|
||||||
|
|||||||
@@ -7,8 +7,68 @@ package com.synebula.gaea.data.cache
|
|||||||
* @version 0.0.1
|
* @version 0.0.1
|
||||||
* @since 2016年8月15日 下午4:53:19
|
* @since 2016年8月15日 下午4:53:19
|
||||||
*/
|
*/
|
||||||
interface ICache {
|
interface ICache<K, V> {
|
||||||
fun add(key: String, value: CacheEntity)
|
|
||||||
|
|
||||||
operator fun get(key: String): CacheEntity?
|
/**
|
||||||
|
* 添加一条缓存记录
|
||||||
|
*
|
||||||
|
* @param key 缓存key
|
||||||
|
* @param value 需要缓存的值
|
||||||
|
*/
|
||||||
|
fun add(key: K, value: V)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加多条缓存记录
|
||||||
|
*
|
||||||
|
* @param entries 需要添加的多条缓存记录Map
|
||||||
|
*/
|
||||||
|
fun add(entries: Map<K, V>)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 尝试获取缓存记录值
|
||||||
|
*
|
||||||
|
* @param key 缓存key
|
||||||
|
*/
|
||||||
|
operator fun get(key: K): V?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取给出列表key中存在的缓存元素
|
||||||
|
*
|
||||||
|
* @param keys 尝试获取的key列表
|
||||||
|
*/
|
||||||
|
fun get(keys: Iterable<K>): Map<K, V>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除所有缓存记录
|
||||||
|
*/
|
||||||
|
fun clear()
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除给出key的缓存
|
||||||
|
*
|
||||||
|
* @param key 需要清楚的缓存key
|
||||||
|
*/
|
||||||
|
fun remove(key: K)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除给出列表key的缓存
|
||||||
|
*
|
||||||
|
* @param keys 需要清楚的缓存key列表
|
||||||
|
*/
|
||||||
|
fun remove(keys: Iterable<K>)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断key是否存在
|
||||||
|
*
|
||||||
|
* @param key 需要判断的key
|
||||||
|
*/
|
||||||
|
fun exists(key: K): Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断keys是否存在
|
||||||
|
*
|
||||||
|
* @param keys 需要判断的缓存key列表
|
||||||
|
*/
|
||||||
|
fun exists(keys: Iterable<K>): Map<K, Boolean>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,28 +3,24 @@ package com.synebula.gaea.data.message
|
|||||||
import com.synebula.gaea.data.serialization.json.IJsonSerializer
|
import com.synebula.gaea.data.serialization.json.IJsonSerializer
|
||||||
|
|
||||||
|
|
||||||
class HttpMessage() : DataMessage<Any>() {
|
class HttpMessage(private var serializer: IJsonSerializer) : DataMessage<Any>() {
|
||||||
|
|
||||||
var serializer: IJsonSerializer? = null
|
|
||||||
|
|
||||||
constructor(data: Any, serializer: IJsonSerializer? = null) : this() {
|
constructor(data: Any, serializer: IJsonSerializer) : this(serializer) {
|
||||||
this.data = data
|
this.data = data
|
||||||
this.serializer = serializer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(status: Int, message: String, serializer: IJsonSerializer? = null) : this() {
|
constructor(status: Int, message: String, serializer: IJsonSerializer) : this(serializer) {
|
||||||
this.status = status
|
this.status = status
|
||||||
this.message = message
|
this.message = message
|
||||||
this.serializer = serializer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(status: Int, data: Any, message: String, serializer: IJsonSerializer? = null) : this(
|
constructor(status: Int, data: Any, message: String, serializer: IJsonSerializer) : this(
|
||||||
status,
|
status,
|
||||||
message,
|
message,
|
||||||
serializer
|
serializer
|
||||||
) {
|
) {
|
||||||
this.data = data
|
this.data = data
|
||||||
this.serializer = serializer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun load(msg: DataMessage<*>) {
|
fun load(msg: DataMessage<*>) {
|
||||||
@@ -34,6 +30,6 @@ class HttpMessage() : DataMessage<Any>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return serializer?.serialize(this) ?: super.toString()
|
return serializer.serialize(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.synebula.gaea.data.message
|
||||||
|
|
||||||
|
import com.synebula.gaea.data.serialization.json.IJsonSerializer
|
||||||
|
|
||||||
|
class HttpMessageFactory(private var serializer: IJsonSerializer) {
|
||||||
|
|
||||||
|
fun create(): HttpMessage {
|
||||||
|
return HttpMessage(serializer)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun create(data: Any): HttpMessage {
|
||||||
|
return HttpMessage(data, serializer)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun create(status: Int, message: String): HttpMessage {
|
||||||
|
return HttpMessage(status, message, serializer)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun create(status: Int, data: Any, message: String): HttpMessage {
|
||||||
|
return HttpMessage(status, data, message, serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user