Golang中如何移除JSON转义字符

Golang中如何移除JSON转义字符 如何从 JSON 中移除转义字符。

func myapi(ctx *gin.Context) {
_in := mystructure{}

    err := ctx.ShouldBindJSON(&_in)

    before pass this function we want to remove the escape string from the json "VALUE"
data, err := services.MyServicefunction(_in)
if err != nil {
	ctx.JSON(http.StatusBadRequest, gin.H{"exception": err.Error()})
            return
} 
ctx.JSON(http.StatusOK, gin.H{"exception": "", "data": data})

}


更多关于Golang中如何移除JSON转义字符的实战教程也可以访问 https://www.itying.com/category-94-b0.html

10 回复

感谢团队。已经完成了。

更多关于Golang中如何移除JSON转义字符的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


很好。

能否请您展示一个JSON示例以及您希望移除的内容?

我想知道为什么你要移除换行符、制表符和回车符呢?

(好吧,我完全理解最后一个)

你能分享一下你的解决方案吗?我相信社区的其他成员也能从中受益。

另一种单次遍历的方法是使用 regexp.ReplaceAll 和正则表达式 "[\n\r\t]"

func main() {
    fmt.Println("hello world")
}

在我的JSON值中,我们遇到了“\n”、“\r”、“\t”字符。

示例:

example := {
data : "jhon \r \t \n "
}

我们将相同的JSON传递给MySQL存储过程。在将JSON发送给存储过程之前,我们希望从JSON值中清除这些字符。

我编写了以下函数:Replaceunwantcharacters

func myapi(ctx *gin.Context) {
_in := mystructure{}
err := ctx.ShouldBindJSON(&_in)

在将此函数传递之前,我们希望从 JSON 的 “VALUE” 中移除转义字符串

_in.fieldname = Replaceunwantcharacters(_in.fieldname )
data, err := services.MyServicefunction(_in)
if err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"exception": err.Error()})
return
}
ctx.JSON(http.StatusOK, gin.H{"exception": "", "data": data})
}
func Replaceunwantcharacters(_in string) (_out string) {
_in = strings.ReplaceAll(_in, "\n", "")
_in = strings.ReplaceAll(_in, "\r", "")
_in = strings.ReplaceAll(_in, "\t", "")
return _in
}

你可以用一种可以说更简单且性能可能更好(虽然性能几乎肯定不是问题,而且我不想被指责为过早优化)的方式,使用字符串替换器来实现:

package main

import (
	"fmt"
	"strings"
)

func main() {
	testStr := "jhon\r\t\n"
	// 替换器,用于替换所有不需要的字符
	r := strings.NewReplacer("\n", "", "\r", "", "\t", "")
	fmt.Println(r.Replace(testStr))
}

这是一个playground链接。如果你觉得将字符串放在一行比你的strings.ReplaceAll实现更难阅读,你可以像这样将它们分开:

r := strings.NewReplacer(
	"\n", "",
	"\r", "",
	"\t", "",
)

如果你不小心创建了奇数个字符串,这也会让错误变得很明显,在这种情况下你会得到一个错误

在Golang中,从JSON中移除转义字符通常意味着处理已转义的JSON字符串。以下是几种常见情况的解决方案:

1. 处理字符串中的转义JSON

如果JSON值本身是转义的字符串,可以使用strconv.Unquotejson.RawMessage

import (
    "encoding/json"
    "strconv"
    "strings"
)

func removeEscapedJSON(input string) (map[string]interface{}, error) {
    // 方法1: 使用strconv.Unquote处理转义字符串
    unquoted, err := strconv.Unquote(`"` + input + `"`)
    if err != nil {
        return nil, err
    }
    
    var result map[string]interface{}
    err = json.Unmarshal([]byte(unquoted), &result)
    return result, err
}

// 或者直接处理JSON字符串
func processEscapedJSON() {
    escapedJSON := `{\"name\":\"John\",\"age\":30}`
    
    // 移除反斜杠转义
    cleanJSON := strings.ReplaceAll(escapedJSON, `\"`, `"`)
    
    var data map[string]interface{}
    json.Unmarshal([]byte(cleanJSON), &data)
}

2. 在Gin框架中处理转义JSON

对于你的API处理函数,可以在绑定前处理原始JSON:

import (
    "bytes"
    "encoding/json"
    "github.com/gin-gonic/gin"
    "io"
    "net/http"
    "strings"
)

func myapi(ctx *gin.Context) {
    // 读取原始请求体
    bodyBytes, err := io.ReadAll(ctx.Request.Body)
    if err != nil {
        ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    
    // 恢复请求体供后续使用
    ctx.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
    
    // 处理转义字符
    cleanedBody := strings.ReplaceAll(string(bodyBytes), `\"`, `"`)
    
    _in := mystructure{}
    
    // 使用处理后的JSON进行解析
    err = json.Unmarshal([]byte(cleanedBody), &_in)
    if err != nil {
        ctx.JSON(http.StatusBadRequest, gin.H{"exception": err.Error()})
        return
    }
    
    data, err := services.MyServicefunction(_in)
    if err != nil {
        ctx.JSON(http.StatusBadRequest, gin.H{"exception": err.Error()})
        return
    }
    
    ctx.JSON(http.StatusOK, gin.H{"exception": "", "data": data})
}

3. 使用自定义绑定处理转义

创建自定义的JSON绑定器:

import (
    "encoding/json"
    "github.com/gin-gonic/gin/binding"
    "strings"
)

type EscapeRemovingJSONBinding struct{}

func (EscapeRemovingJSONBinding) Name() string {
    return "json"
}

func (EscapeRemovingJSONBinding) Bind(req *http.Request, obj interface{}) error {
    bodyBytes, err := io.ReadAll(req.Body)
    if err != nil {
        return err
    }
    
    // 处理转义字符
    cleaned := strings.ReplaceAll(string(bodyBytes), `\"`, `"`)
    
    return json.Unmarshal([]byte(cleaned), obj)
}

// 在Gin中使用
func setupRouter() *gin.Engine {
    r := gin.Default()
    r.Use(func(c *gin.Context) {
        c.Request = binding.CustomBindingMiddleware(
            c.Request,
            EscapeRemovingJSONBinding{},
        )
    })
    return r
}

4. 处理特定字段的转义

如果只需要处理特定字段的转义:

import (
    "encoding/json"
    "strings"
)

type MyStructure struct {
    Name  string `json:"name"`
    Value string `json:"value"` // 这个字段可能包含转义JSON
}

func (m *MyStructure) CleanValue() (map[string]interface{}, error) {
    if m.Value == "" {
        return nil, nil
    }
    
    // 移除转义并解析
    cleaned := strings.ReplaceAll(m.Value, `\"`, `"`)
    var result map[string]interface{}
    err := json.Unmarshal([]byte(cleaned), &result)
    return result, err
}

// 在API中使用
func myapi(ctx *gin.Context) {
    _in := MyStructure{}
    
    err := ctx.ShouldBindJSON(&_in)
    if err != nil {
        ctx.JSON(http.StatusBadRequest, gin.H{"exception": err.Error()})
        return
    }
    
    // 清理并处理转义的值
    cleanedValue, err := _in.CleanValue()
    if err != nil {
        ctx.JSON(http.StatusBadRequest, gin.H{"exception": err.Error()})
        return
    }
    
    // 使用清理后的值继续处理
    // ...
}

5. 完整的中间件解决方案

创建一个Gin中间件自动处理转义:

func EscapeRemovingMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        if c.Request.Method == http.MethodPost || 
           c.Request.Method == http.MethodPut || 
           c.Request.Method == http.MethodPatch {
            
            bodyBytes, err := io.ReadAll(c.Request.Body)
            if err != nil {
                c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to read body"})
                c.Abort()
                return
            }
            
            if len(bodyBytes) > 0 {
                // 移除JSON字符串中的转义
                cleaned := strings.ReplaceAll(string(bodyBytes), `\"`, `"`)
                c.Request.Body = io.NopCloser(bytes.NewBufferString(cleaned))
            }
        }
        
        c.Next()
    }
}

// 使用中间件
func main() {
    r := gin.Default()
    r.Use(EscapeRemovingMiddleware())
    
    r.POST("/api", myapi)
    r.Run(":8080")
}

这些方法可以根据你的具体需求选择使用。第一种方法适合处理单个转义字符串,第二种和第三种方法适合在API层面统一处理,第四种方法适合处理特定字段,第五种方法通过中间件提供全局解决方案。

回到顶部