溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

?golang中怎么增加java8對象的序列化輸出

發(fā)布時間:2021-12-15 16:05:15 來源:億速云 閱讀:159 作者:iii 欄目:大數據

本篇內容介紹了“golang中怎么增加java8對象的序列化輸出”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

1. New Features

1.1 add GetStackTrace method into Throwabler and its implements. #207

go語言client請求java語言服務時,如果java語言拋出了異常,異常對應的堆棧信息是被保存在StackTraceElement中。

這個異常信息在日志中最好能被打印出來,以方便客戶端排查問題,所以在Throwabler和對應子類中增加了StackTraceElement的獲取。

注:其實還有一種更好的方法,所有的具體的異常類型都包含java_exception/exception.go的Throwable struct。這樣只需要在Throwable中增加GetStackTrace方法就可以了。但是這種方式需要更多的測試驗證,改動的邏輯相對會復雜一些。但是代碼會更整潔。 這里先不用這種方法。

1.2 catch user defined exceptions. #208

golang中增加一個java中Exception對象的序列化輸出方法:

func JavaException() []byte {
	e := hessian.NewEncoder()
	exception := java_exception.NewException("java_exception")
	e.Encode(exception)
	return e.Buffer()
}

在output/output.go 提供調用入口:添加如下函數初始化聲明

func init() {
    funcMap["JavaException"] = testfuncs.JavaException
}

java代碼中增加調用go方法序列化結果: 說明: Assert.assertEquals 不能直接比較Exception對象是否相等

    /**
     * test java java.lang.Exception object and go java_exception Exception struct
     */
    @Test
    public void testException() {
        Exception exception = new Exception("java_exception");
        Object javaException = GoTestUtil.readGoObject("JavaException");
        if (javaException instanceof Exception) {
            Assert.assertEquals(exception.getMessage(), ((Exception) javaException).getMessage());
        }
    }

1.3 support java8 time object. #212, #221

golang中增加一個java8對象的序列化輸出方法:

// test java8 java.time.Year
func Java8TimeYear() []byte {
    e := hessian.NewEncoder()
    year := java8_time.Year{Year: 2020}
    e.Encode(year)
    return e.Buffer()
}

// test java8 java.time.LocalDate
func Java8LocalDate() []byte {
    e := hessian.NewEncoder()
    date := java8_time.LocalDate{Year: 2020, Month: 9, Day: 12}
    e.Encode(date)
    return e.Buffer()
}

在output/output.go 提供調用入口:添加函數初始化聲明

func init() {
	funcMap["Java8TimeYear"] = testfuncs.Java8TimeYear
	funcMap["Java8LocalDate"] = testfuncs.Java8LocalDate
}

java代碼中增加調用go方法序列化結果:

/**
 * test java8 java.time.* object and go java8_time/* struct
 */
@Test
public void testJava8Year() {
    Year year = Year.of(2020);
    Assert.assertEquals(year
            , GoTestUtil.readGoObject("Java8TimeYear"));
    LocalDate localDate = LocalDate.of(2020, 9, 12);
    Assert.assertEquals(localDate, GoTestUtil.readGoObject("Java8LocalDate"));
}

1.4 support test golang encoding data in java. #213

為了更好的測試驗證hessian庫,原來已經支持在golang中測試java的序列化數據,現在增加在java中測試golang的序列化數據,實現雙向測試驗證。

golang中增加序列化輸出方法:

func HelloWorldString() []byte {
    e := hessian.NewEncoder()
    e.Encode("hello world")
    return e.Buffer()
}

將該方法注冊到output/output.go中

 // add all output func here
 func init() {
     funcMap["HelloWorldString"] = testfuncs.HelloWorldString
}

output/output.go 提供調用入口:

func main() {
    flag.Parse()

    if *funcName == "" {
        _, _ = fmt.Fprintln(os.Stderr, "func name required")
        os.Exit(1)
    }
    f, exist := funcMap[*funcName]
    if !exist {
        _, _ = fmt.Fprintln(os.Stderr, "func name not exist: ", *funcName)
        os.Exit(1)
    }

    defer func() {
        if err := recover(); err != nil {
            _, _ = fmt.Fprintln(os.Stderr, "error: ", err)
            os.Exit(1)
        }
    }()
    if _, err := os.Stdout.Write(f()); err != nil {
        _, _ = fmt.Fprintln(os.Stderr, "call error: ", err)
        os.Exit(1)
    }
    os.Exit(0)
}

java代碼中增加調用go方法序列化結果:

public class GoTestUtil {

    public static Object readGoObject(String func) {
        System.out.println("read go data: " + func);
        try {
            Process process = Runtime.getRuntime()
                    .exec("go run output/output.go -func_name=" + func,
                            null,
                            new File(".."));

            int exitValue = process.waitFor();
            if (exitValue != 0) {
                Assert.fail(readString(process.getErrorStream()));
                return null;
            }

            InputStream is = process.getInputStream();
            Hessian2Input input = new Hessian2Input(is);
            return input.readObject();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private static String readString(InputStream in) throws IOException {
        StringBuilder out = new StringBuilder();
        InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8);
        char[] buffer = new char[4096];

        int bytesRead;
        while ((bytesRead = reader.read(buffer)) != -1) {
            out.append(buffer, 0, bytesRead);
        }

        return out.toString();
    }
}

增加java測試代碼:

@Test
public void testHelloWordString() {
    Assert.assertEquals("hello world"
            , GoTestUtil.readGoObject("HelloWorldString"));
}

1.5 support java.sql.Time & java.sql.Date. #219

增加了 java 類 java.sql.Time, java.sql.Date 支持,分別對應到hessian.Time 和 hessian.Date

2. Enhancement

2.1 Export function EncNull. #225

開放 hessian.EncNull 方法,以便用戶特定情況下使用。

3. Bugfixes

3.1 fix enum encode error in request. #203

原來在 dubbo request 對象中沒有判斷 enum 類型的情況,此pr增加了判斷是不是POJOEnum類型。

3.2 fix []byte field decoding issue. #216

v1.7.0 之前如果 struct中包含[]byte字段時無法反序列化, 報錯“error list tag: 0x29”,主要原因是被當做list進行處理,對于這種情況應該按照binary數據進行處理即可。

type Circular struct {
    Num      int
	Previous *Circular
	Next     *Circular
	ResponseDataBytes    []byte // <---- 
}

func (Circular) JavaClassName() string {
	return "com.company.Circular"
}

3.3 fix decoding error for map in map. #229

v1.7.0 之前嵌套map無法正確解析,主要原因是對應的map對象被當做一個數據類型卻未被自動加到類引用列表中,而嵌套map類信息是同一類型的引用,去類引用列表找,找不到就報錯了。 解決這個問題的方法就是遇到map類對象,也將其加入到類引用列表中即可。 

3.4 fix fields name mismatch in Duration class. #234

這個 PR 解決了Duration對象中字段錯誤定義,原來是"second/nano", 應該是"seconds/nanos"。

同時改善了測試驗證數據。之前使用0作為int字段的測試數據,這是不準確的,因為int類型默認值就是0.

“golang中怎么增加java8對象的序列化輸出”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI