网站首页 > java教程 正文
书接上文:
聚合接口层(BFF)之Go语言版(二)获取请求Header、参数
统一响应
返回JSON格式的响应,前文用的都是:
ctx.JSON(http.StatusOK, gin.H{"userName": userName})
实际工作中一般响应格式:
{
"code": 0,
"msg": "success",
"data": {
"id": "111AAA",
"userName": "张三"
}
}
每个请求都手工拼接JSON响应,不现实,需要一个统一的响应。
common包下新建文件ResponseVo.go
package common
import (
"net/http"
"github.com/gin-gonic/gin"
)
type ResponseVo struct {
Code int32 `json:"code"`
Msg string `json:"msg"`
DataName string `json:"dataName"`
Data interface{} `json:"data,omitempty"`
}
func SuccessResponse(ctx *gin.Context, dataName string, data interface{}) {
ctx.JSON(http.StatusOK, ResponseVo{Code: 0, Msg: "success", DataName: dataName, Data: data})
}
func FailResponse(ctx *gin.Context, msg string, dataName string, data interface{}) {
ctx.JSON(http.StatusOK, ResponseVo{Code: 1, Msg: msg, DataName: dataName, Data: data})
}
func SuccessVo(dataName string, data interface{}) ResponseVo {
return ResponseVo{Code: 0, Msg: "success", DataName: dataName, Data: data}
}
func FailVo(msg string, dataName string, data interface{}) ResponseVo {
return ResponseVo{Code: 1, Msg: msg, DataName: dataName, Data: data}
}
SuccessResponse、FailResponse可以直接将响应输出至前端。
SuccessVo、FailVo会返回响应至Controller,供进一步处理。
具体的参数,可以根据实际工作需要进行增减。例如:
func FailResponseWithoutData(ctx *gin.Context, msg string, dataName string) {
ctx.JSON(http.StatusOK, ResponseVo{Code: 1, Msg: msg, DataName: dataName, Data: nil})
}
func FailResponseWithCode(ctx *gin.Context, code int32, msg string, dataName string) {
ctx.JSON(http.StatusOK, ResponseVo{Code: code, Msg: msg, DataName: dataName, Data: nil})
}
dataName的作用后续会介绍,先放在这。
code是业务码,与HTTP的响应码要区分开。
msg是具体的业务错误信息,例如:XX参数校验失败。Token失效等等。
data是具体的响应内容,在Java里这是一个T(泛型),在Go里就是interface{}。
Code int32 `json:"code"`
代表JSON序列化反序列化的时候,key是“code”。
`json:"data,omitempty"`
omittempty代表此字段可以为nil。
至此,Controller可以改造如下:
func GetParamFronPost(ctx *gin.Context) {
userAddParam := common.UserAddParam{}
bindErr := ctx.ShouldBindJSON(&userAddParam)
if bindErr != nil {
common.FailResponse(ctx, "参数转换失败", "UserAddParam", nil)
return
}
// 如果是13位时间戳,需/1000
unixTime := time.Unix(userAddParam.CreateTime, 0)
formattedTime := unixTime.Format(time.DateTime)
log.Println(userAddParam.UserName, userAddParam.Account.Mobile, userAddParam.CreateTime, formattedTime)
// 方案一
data := common.SuccessVo("UserAddParam", userAddParam)
ctx.JSON(http.StatusOK, data)
// 方案二(推荐)
//common.SuccessResponse(ctx, "UserAddParam", userAddParam)
}
中间件
Go的中间件,大家可以当成是Java里的Filter。
例如Javaer经常用Filter校验Token,在Go里面可以这么写。
common包新建CurrentUserInfo.go
package common
var CURRENT_USER_INFO = "CurrentUserInfo"
type CurrentUserInfo struct {
UserId string `json:"userId"`
UserName string `json:"userName"`
}
新增文件夹middleware,新增tokenCheck.go:
package middleware
import (
"gows/common"
"log"
"github.com/gin-gonic/gin"
)
func TokenCheck() gin.HandlerFunc {
return func(ctx *gin.Context) {
token := ctx.Request.Header.Get("Token")
if len(token) != 0 {
log.Println("Token内容:", token)
//此处应该解析JWT Token,并从Redis或DB处获取用户信息
//如果解析失败,或令牌过期、用户被锁,则直接返回错误信息
currentUserInfo := common.CurrentUserInfo{
UserId: token,
UserName: "用户名:" + token,
}
//将用户信息写入Context,供Controller使用
ctx.Set(common.CURRENT_USER_INFO, currentUserInfo)
//执行下一个中间件
ctx.Next()
} else {
log.Println("没有Token")
//不使用HTTP响应码
//common.FailResponse(ctx, "没有Token", "token", nil)
//使用HTTP响应码s
ctx.AbortWithStatusJSON(403, common.FailVo("没有Token", "", nil))
}
}
}
写一个测试Controller方法:
func MiddleWareTest(ctx *gin.Context) {
currentUserInfo, exists := ctx.Get(common.CURRENT_USER_INFO)
if !exists {
common.FailResponse(ctx, "有Token,没用户", "token", nil)
return
}
loginUser := currentUserInfo.(common.CurrentUserInfo)
common.SuccessResponse(ctx, "loginUser", loginUser)
}
接着改造main.go里面的路由配置:
// 新增一个名为authGroup的路由组,拦截路径以/api开头的请求,使用TokenCheck中间件
authGroup := r.Group("/api", middleware.TokenCheck())
//在authGroup路由组下新增请求/testmw
authGroup.GET("/testmw", controller.MiddleWareTest)
请求如下:
猜你喜欢
- 2024-10-23 阿里蚂蚁金服中间件(Java 4轮面试题含答案):Re...
- 2024-10-23 阿里Java60万年薪(4面真题):线程同步+数据库锁+中间件等
- 2024-10-23 面试分享:中间件RabbitMQ面试专题及Java架构知识点整理!
- 2024-10-23 吐血总结了各个中间件是如何实现持久化的
- 2024-10-23 学习分享之《大型网站系统与Java中间件实践》
- 2024-10-23 Arquillian:针对Java中间件的集成测试和功能性测试平台
- 2024-10-23 java数据库读写分离-数据库中间件DBProxy
- 2024-10-23 java面试中,面试官:如何处理消息中间件(MQ)消息丢失问题?
- 2024-10-23 阿里Java高级岗中间件二面:GC+IO+JVM+多线程+Redis+数据库+源码
- 2024-10-23 Java中间件-ehcache(Java中间件错误整理)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)