Golang Echo框架实现API统一返回格式
Golang的Echo框架中,上下文echo.Context
是一个接口,可以通过它重写默认的Context.JSON
方法来自定义返回格式
首先定义一下接口的格式
type CommonResponse struct {
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
}
Golang的Echo框架中,上下文echo.Context
是一个接口,可以通过它重写默认的Context.JSON
方法来自定义返回格式
首先定义一下接口的格式
type CommonResponse struct {
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
}
对于前后端分离的项目,采用统一的返回格式可以有效减少前后端开发人员的交流成本,对于Spring MVC可以利用切面无侵入地、优雅地实现这一点。
Spring MVC提供了AbstractMappingJacksonResponseBodyAdvice抽象类对返回的JSON做二次处理
首先定义返回结构
关于JWT是什么就不赘述了,可以看看阮一峰大佬的文章:https://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
首先需要定义一个Bean用来存放JWT Body,字段可以根据具体业务决定。这一步当然可以跳过,你可以用Map传值,只不过可维护性会差点
通常我们用Cloudflare WARP通过替换VPS的双栈或单栈网络来通过获得所谓“原生IP”,从而解锁Netflex等流媒体,而如果直接替换掉双栈网络会导致VPS失联,即使通过修改路由表正常使用也会影响到Docker等应用的NAT。实际上我们只需要让Xray的流量走WARP接口出去就行了,outbounds配置提供了sendThrough
用来指定出口IP,streamSettings.sockopt.mark
用来设置fwmark
。我之前直接指定为WARP的IP发现并不行,收不到回包(实际上如果直接指定接口名就正常使用了,可惜不支持)。在翻Xray的文档时才发现还需要配置一下路由表才行。
通常我们会通过spring的异常处理器来自定义响应格式,即通过@RestControllerAdvice
来实现,但是如果只是为了自定义一个返回格式的话有更好的选择,那就是自定义ErrorController
,所有未被处理的异常都会被它处理,@RestControllerAdvice
也被视为异常处理,即被@RestControllerAdvice
处理的异常将不会到达这里,直接上代码,以Kotlin为例
@RestController
@RequestMapping("/error")
class GlobalErrorController : ErrorController {
@Autowired
lateinit var errorAttributes: ErrorAttributes
@GetMapping
fun error(request: HttpServletRequest): ResponseEntity<ErrorResponse> {
val ex: Throwable? = errorAttributes.getError(ServletWebRequest(request))
val status = getStatus(request)
return ResponseEntity.status(status)
.body(ErrorResponse(status = status.name, message = ex?.localizedMessage ?: ""))
}
private fun getStatus(request: HttpServletRequest): HttpStatus {
val statusCode = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE)
if (statusCode !is Int) {
return HttpStatus.INTERNAL_SERVER_ERROR
}
return try {
HttpStatus.valueOf(statusCode)
} catch (e: Exception) {
HttpStatus.INTERNAL_SERVER_ERROR
}
}
}
这里注入了一个ErrorAttributes
类型的bean,它包含了请求上下文的错误信息,通过getError
方法可以获取到异常类
匹配到路由/error
的方法的返回值会作为响应发送到客户端,当然这个路由是可以自定义的
实现类似于zsh和fish的命令高亮和提示效果
Set-PSReadLineOption -PredictionSource History
Set-PSReadLineKeyHandler -Key Tab -Function MenuComplete
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward
Set-PSReadLineOption -Colors @{ InlinePrediction = "#666666" }
Set-PSReadLineOption -BellStyle none
Set-PSReadLineOption -HistorySearchCursorMovesToEnd
直接上代码
open class BaseController<T : BaseEntity>(val baseService: BaseService<T>) {
@Transactional
@AuthRequired
@PatchMapping("/{id}")
open fun updateById(@PathVariable("id") id: Long, @RequestBody entity: T): ResponseEntity<T> {
entity.id = id
return ResponseEntity.ok(baseService.updateById(entity))
}
}
访问controller时出现NullPointerException,此时baseService为null
在尝试用kotlin写springboot项目时发现springboot的kotlin项目模板的注解处理器没生效,结果就是自定义的配置类在idea中没有语法提示,且有一堆黄线警告,解决方法就是用kapt进行注解处理
在build.gradle.kts加入
plugins {
...
kotlin("kapt") version "1.4.20"
}
dependencies {
...
kapt("org.springframework.boot:spring-boot-configuration-processor")
}
重新构建,这样就能正确生成spring-configuration-metadata.json
在MySQL中,当使用timestamp
作为储存时间的类型时,其读写都与session
的time_zone
有关。当没有显式指定时,当前session的time_zone
会继承全局设置
time_zone
转换成UTC时间,将其时间戳进行储存time_zone
所对应的时间根据其他资料在连接字符串中添加参数serverTimezone