修改为token认证方式

This commit is contained in:
2022-09-14 09:40:25 +08:00
parent 0ccb49afde
commit 19c3640f4f
31 changed files with 406 additions and 218 deletions

View File

@@ -17,7 +17,7 @@ buildscript {
subprojects {
group 'com.synebula'
version '1.4.0'
version '1.5.0'
buildscript {
repositories {

View File

@@ -17,5 +17,6 @@ dependencies {
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.auth0', name: 'java-jwt', version: '3.14.0'
api group: 'com.google.guava', name: 'guava', version: '31.1-jre'
}

View File

@@ -2,12 +2,12 @@ package com.synebula.gaea.app
import com.synebula.gaea.app.cmd.ICommandApp
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.IService
import com.synebula.gaea.log.ILogger
import com.synebula.gaea.query.IQuery
import javax.annotation.Resource
import org.springframework.beans.factory.annotation.Autowired
/**
* 联合服务同时实现了ICommandApp和IQueryApp接口
@@ -24,6 +24,6 @@ open class Application<TCommand : ICommand, TView, ID>(
override var logger: ILogger,
) : ICommandApp<TCommand, ID>, IQueryApp<TView, ID> {
@Resource
override var jsonSerializer: IJsonSerializer? = null
@Autowired
override lateinit var httpMessageFactory: HttpMessageFactory
}

View File

@@ -2,6 +2,7 @@ package com.synebula.gaea.app
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.log.ILogger
import org.springframework.security.core.context.SecurityContextHolder
@@ -18,12 +19,17 @@ interface IApplication {
*/
var logger: ILogger
/**
* 日志详细的构造器
*/
var httpMessageFactory: HttpMessageFactory
/**
* 安全执行
*/
fun safeExecute(error: String, process: ((msg: HttpMessage) -> Unit)): HttpMessage {
val msg = HttpMessage()
val msg = this.httpMessageFactory.create()
try {
process(msg)
logger.debug(this, "$name business execute success")
@@ -39,7 +45,7 @@ interface IApplication {
* 可抛出自定义异常信息的安全controller实现了异常捕获和消息组成。
*/
fun throwExecute(error: String, process: ((msg: HttpMessage) -> Unit)): HttpMessage {
val msg = HttpMessage()
val msg = this.httpMessageFactory.create()
try {
process(msg)
logger.debug(this, "$name business execute success")
@@ -54,7 +60,7 @@ interface IApplication {
* 获取用户信息
* @param clazz 用户信息结构类
*/
fun <T> sessionUser(clazz: Class<T>): T? {
fun <T> userSession(clazz: Class<T>): T? {
try {
val authentication = SecurityContextHolder.getContext().authentication.principal.toString()
try {

View File

@@ -2,12 +2,12 @@ package com.synebula.gaea.app
import com.synebula.gaea.app.cmd.ISimpleCommandApp
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.service.ISimpleService
import com.synebula.gaea.log.ILogger
import com.synebula.gaea.query.IQuery
import javax.annotation.Resource
import org.springframework.beans.factory.annotation.Autowired
/**
* 简单的服务, 取消了Command对象
@@ -24,6 +24,7 @@ open class SimpleApplication<TRoot : IAggregateRoot<ID>, ID>(
override var logger: ILogger,
) : ISimpleCommandApp<TRoot, ID>, IQueryApp<TRoot, ID> {
@Resource
override var jsonSerializer: IJsonSerializer? = null
@Autowired
override lateinit var httpMessageFactory: HttpMessageFactory
}

View File

@@ -1,10 +1,10 @@
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.IService
import com.synebula.gaea.log.ILogger
import javax.annotation.Resource
import org.springframework.beans.factory.annotation.Autowired
/**
* 指令服务同时实现ICommandApp
@@ -18,6 +18,6 @@ open class CommandApp<TCommand : ICommand, ID>(
override var service: IService<ID>,
override var logger: ILogger,
) : ICommandApp<TCommand, ID> {
@Resource
override var jsonSerializer: IJsonSerializer? = null
@Autowired
override lateinit var httpMessageFactory: HttpMessageFactory
}

View File

@@ -3,7 +3,6 @@ package com.synebula.gaea.app.cmd
import com.synebula.gaea.app.IApplication
import com.synebula.gaea.data.message.HttpMessage
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.IService
import com.synebula.gaea.spring.aop.annotation.Method
@@ -17,27 +16,25 @@ import org.springframework.web.bind.annotation.*
* @since 2020-05-15
*/
interface ICommandApp<TCommand : ICommand, ID> : IApplication {
var jsonSerializer: IJsonSerializer?
var service: IService<ID>
@PostMapping
@Method("添加")
fun add(@RequestBody command: TCommand): HttpMessage {
return HttpMessage(service.add(command))
return this.httpMessageFactory.create(service.add(command))
}
@PutMapping("/{id:.+}")
@Method("更新")
fun update(@PathVariable id: ID, @RequestBody command: TCommand): HttpMessage {
this.service.update(id, command)
return HttpMessage()
return this.httpMessageFactory.create()
}
@DeleteMapping("/{id:.+}")
@Method("删除")
fun remove(@PathVariable id: ID): HttpMessage {
val msg = HttpMessage()
val msg = this.httpMessageFactory.create()
try {
msg.data = this.service.remove(id)
} catch (ex: IllegalStateException) {

View File

@@ -3,7 +3,6 @@ package com.synebula.gaea.app.cmd
import com.synebula.gaea.app.IApplication
import com.synebula.gaea.data.message.HttpMessage
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.service.ISimpleService
import com.synebula.gaea.spring.aop.annotation.Method
@@ -17,27 +16,25 @@ import org.springframework.web.bind.annotation.*
* @since 2020-05-15
*/
interface ISimpleCommandApp<TRoot : IAggregateRoot<ID>, ID> : IApplication {
var jsonSerializer: IJsonSerializer?
var service: ISimpleService<TRoot, ID>
@PostMapping
@Method("添加")
fun add(@RequestBody entity: TRoot): HttpMessage {
return HttpMessage(service.add(entity))
return this.httpMessageFactory.create(service.add(entity))
}
@PutMapping("/{id:.+}")
@Method("更新")
fun update(@PathVariable id: ID, @RequestBody entity: TRoot): HttpMessage {
this.service.update(id, entity)
return HttpMessage()
return this.httpMessageFactory.create()
}
@DeleteMapping("/{id:.+}")
@Method("删除")
fun remove(@PathVariable id: ID): HttpMessage {
val msg = HttpMessage()
val msg = this.httpMessageFactory.create()
try {
msg.data = this.service.remove(id)
} catch (ex: IllegalStateException) {

View File

@@ -1,10 +1,10 @@
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.service.ISimpleService
import com.synebula.gaea.log.ILogger
import javax.annotation.Resource
import org.springframework.beans.factory.annotation.Autowired
/**
* 指令服务同时实现ICommandApp
@@ -18,6 +18,6 @@ open class SimpleCommandApp<TRoot : IAggregateRoot<ID>, ID>(
override var service: ISimpleService<TRoot, ID>,
override var logger: ILogger,
) : ISimpleCommandApp<TRoot, ID> {
@Resource
override var jsonSerializer: IJsonSerializer? = null
@Autowired
override lateinit var httpMessageFactory: HttpMessageFactory
}

View File

@@ -5,7 +5,7 @@ import org.dozer.DozerBeanMapper
import org.springframework.stereotype.Component
@Component
class DozerConverter : IObjectMapper {
class DozerMapper : IObjectMapper {
private val converter = DozerBeanMapper()
override fun <T> deserialize(src: Any, targetClass: Class<T>): T = converter.map(src, targetClass)

View 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()
}
}

View File

@@ -1,12 +1,11 @@
package com.synebula.gaea.app.component.security
import com.synebula.gaea.app.struct.exception.TokenCloseExpireException
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 org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
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 javax.servlet.FilterChain
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) :
BasicAuthenticationFilter(authenticationManager) {
class WebAuthorization(
var httpMessageFactory: HttpMessageFactory,
var userSessionManager: UserSessionManager,
var storage: String = "token"
) : OncePerRequestFilter() {
/**
* token 在 header 中的 key
*/
private val tokenKey = "token"
/**
* 在过滤之前和之后执行的事件
*/
@Throws(IOException::class, ServletException::class)
override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, chain: FilterChain) {
val token = request.getHeader(tokenManager.header)
try {
val user = tokenManager.verify(token)
val authentication =
UsernamePasswordAuthenticationToken(user, null, null)
val identity = if (this.storage == "cookie") {
request.cookies.find { it.name == tokenKey }?.value ?: ""
} else {
request.getHeader(tokenKey) ?: ""
}
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
super.doFilterInternal(request, response, chain)
} catch (ex: TokenCloseExpireException) {
chain.doFilter(request, response)
} else {
response.status = Status.Success
response.characterEncoding = "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()
}
}

View File

@@ -1,56 +1,68 @@
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 org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
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.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer
import org.springframework.security.config.http.SessionCreationPolicy
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.CorsConfigurationSource
import org.springframework.web.cors.UrlBasedCorsConfigurationSource
@Component
@Configuration
@EnableWebSecurity
class WebSecurity {
@Autowired
lateinit var tokenManager: TokenManager
lateinit var userSessionManager: UserSessionManager
@Autowired
lateinit var authenticationManager: AuthenticationManager
lateinit var httpMessageFactory: HttpMessageFactory
@Value("\${spring.sign-in-url}")
var signInPath = "/sign/in"
/**
* 安全配置
*/
@Bean
@Throws(Exception::class)
fun filterChain(http: HttpSecurity): SecurityFilterChain {
// 跨域共享
http.cors()
.and().csrf().disable() // 跨域伪造请求限制无效
.authorizeRequests()
.anyRequest().authenticated()// 资源任何人都可访问
.and()
.addFilter(WebAuthorization(authenticationManager, tokenManager))// 添加JWT鉴权拦截器
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 设置Session的创建策略为Spring Security永不创建HttpSession 不使用HttpSession来获取SecurityContext
.and()
.exceptionHandling()
.authenticationEntryPoint { _, response, _ ->
fun filterChain(httpSecurity: HttpSecurity): SecurityFilterChain {
httpSecurity.cors().and().csrf().disable() // 跨域伪造请求限制无效
// 设置Session的创建策略为Spring Security永不创建HttpSession 不使用HttpSession来获取SecurityContext
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
// 除了登录接口其他资源都必须登录访问
.and().authorizeRequests().antMatchers(this.signInPath).permitAll().anyRequest().authenticated()
// 添加鉴权拦截器
.and().addFilterBefore(
WebAuthorization(httpMessageFactory, userSessionManager),
UsernamePasswordAuthenticationFilter::class.java
).exceptionHandling().authenticationEntryPoint { _, response, _ ->
response.status = Status.Success
response.characterEncoding = "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)
fun filterChain(): WebSecurityCustomizer {
return WebSecurityCustomizer { web -> web.ignoring().antMatchers("/sign/**") }
fun ignoringCustomizer(): WebSecurityCustomizer {
return WebSecurityCustomizer { web -> web.ignoring().antMatchers(this.signInPath) }
}
/**

View File

@@ -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
}
}

View File

@@ -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]
}
}

View File

@@ -19,7 +19,7 @@ interface IQueryApp<TView, ID> : IApplication {
@GetMapping("/{id:.+}")
fun get(@PathVariable id: ID): HttpMessage {
val data = this.query.get(id)
val msg = HttpMessage()
val msg = this.httpMessageFactory.create()
msg.data = data
return msg
}
@@ -28,7 +28,7 @@ interface IQueryApp<TView, ID> : IApplication {
@GetMapping
fun list(@RequestParam params: LinkedHashMap<String, String>): HttpMessage {
val data = this.query.list(params)
return HttpMessage(data)
return this.httpMessageFactory.create(data)
}
@Method("获取分页数据")
@@ -40,6 +40,6 @@ interface IQueryApp<TView, ID> : IApplication {
): HttpMessage {
val params = Params(page, size, parameters)
val data = this.query.paging(params)
return HttpMessage(data)
return this.httpMessageFactory.create(data)
}
}

View File

@@ -1,7 +1,9 @@
package com.synebula.gaea.app.query
import com.synebula.gaea.data.message.HttpMessageFactory
import com.synebula.gaea.log.ILogger
import com.synebula.gaea.query.IQuery
import org.springframework.beans.factory.annotation.Autowired
/**
* 联合服务同时实现了ICommandApp和IQueryApp接口
@@ -14,4 +16,8 @@ open class QueryApp<TView, ID>(
override var name: String,
override var query: IQuery<TView, ID>,
override var logger: ILogger,
) : IQueryApp<TView, ID>
) : IQueryApp<TView, ID> {
@Autowired
override lateinit var httpMessageFactory: HttpMessageFactory
}

View File

@@ -1,7 +1,7 @@
package com.synebula.gaea.spring.aop
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.exception.NoticeUserException
import com.synebula.gaea.log.ILogger
@@ -25,6 +25,9 @@ abstract class AppAspect {
@Autowired
lateinit var applicationContext: ApplicationContext
@Autowired
lateinit var httpMessageFactory: HttpMessageFactory
/**
* 定义切面的方法
*/
@@ -74,7 +77,7 @@ abstract class AppAspect {
gson.toJson(point.args)
}"
)
return HttpMessage(Status.Error, message)
return this.httpMessageFactory.create(Status.Error, message)
}
}

View File

@@ -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
/**

View File

@@ -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
import java.lang.reflect.Method

View File

@@ -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
/**

View File

@@ -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
import java.util.*

View File

@@ -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
import kotlin.reflect.KClass

View File

@@ -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
/**

View File

@@ -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
import com.synebula.gaea.exception.NoticeUserException

View File

@@ -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
import java.lang.reflect.Method

View File

@@ -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
/**

View File

@@ -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
import com.synebula.gaea.data.message.messageTopic

View File

@@ -7,8 +7,68 @@ package com.synebula.gaea.data.cache
* @version 0.0.1
* @since 2016年8月15日 下午4:53:19
*/
interface ICache {
fun add(key: String, value: CacheEntity)
interface ICache<K, V> {
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>
}

View File

@@ -3,28 +3,24 @@ package com.synebula.gaea.data.message
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.serializer = serializer
}
constructor(status: Int, message: String, serializer: IJsonSerializer? = null) : this() {
constructor(status: Int, message: String, serializer: IJsonSerializer) : this(serializer) {
this.status = status
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,
message,
serializer
) {
this.data = data
this.serializer = serializer
}
fun load(msg: DataMessage<*>) {
@@ -34,6 +30,6 @@ class HttpMessage() : DataMessage<Any>() {
}
override fun toString(): String {
return serializer?.serialize(this) ?: super.toString()
return serializer.serialize(this)
}
}

View File

@@ -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)
}
}