解决wiremock中velocity脚本(.vm)中文编码乱码问题
WireMock 是一個(gè)輕量級(jí)的服務(wù)器,可以快速的實(shí)現(xiàn)接口服務(wù)和部署。在前端開(kāi)發(fā)中,如果服務(wù)接口未實(shí)現(xiàn),可以使用這個(gè)工具來(lái)模擬接口。關(guān)于wiremock的使用網(wǎng)上又不少文章了,可以自行搜索,有時(shí)間我會(huì)出一篇詳細(xì)的使用教程。
在wiremock中可以使用velocity腳本來(lái)編寫(xiě)數(shù)據(jù)文件(.vm),這樣可以生產(chǎn)動(dòng)態(tài)的數(shù)據(jù)。
但是wiremock中如果在velocity腳本中存在中文,就會(huì)出現(xiàn)編碼錯(cuò)亂。而直接使用靜態(tài)的json數(shù)據(jù)文本(.json)就不會(huì)出問(wèn)題。
這是因?yàn)?vm文件在讀取后需要進(jìn)行轉(zhuǎn)換生產(chǎn)最終的數(shù)據(jù),所以wiremock需要wiremock-velocity-transformer-x.x.jar和wiremock-velocity-transformer-standalone-x.x.jar這兩個(gè)jar包。
就是在velocity轉(zhuǎn)換的過(guò)程中出現(xiàn)了編碼問(wèn)題。
實(shí)際上,velocity轉(zhuǎn)換后的數(shù)據(jù)返回的編碼不是utf-8,所以我們用utf-8來(lái)處理就會(huì)有問(wèn)題,我們?cè)谀玫竭@種數(shù)據(jù)可用單獨(dú)做些處理就能得到正常的數(shù)據(jù),比如:
new String(text.getBytes(Charsets.ISO_8859_1), Charsets.UTF_8)注意:在我的電腦上velocity轉(zhuǎn)換后的數(shù)據(jù)的編碼是ISO_8859_1,這個(gè)編碼是否固定和是否依賴終端類型還不確定,所以可能在其他機(jī)器上又是另外一個(gè)編碼,如gbk。
但是由于我們服務(wù)api基本上都使用的utf-8,所以如果wiremock不能提供utf-8的數(shù)據(jù),那么我們?cè)诖a中就要根據(jù)環(huán)境來(lái)做一些特殊處理。所以最好的辦法就是讓velocity轉(zhuǎn)換后的數(shù)據(jù)使用utf-8編碼。
轉(zhuǎn)換的代碼在wiremock-velocity-transformer-x.x.jar和wiremock-velocity-transformer-standalone-x.x.jar這兩個(gè)jar包中,其中wiremock-velocity-transformer-x.x.jar只有一個(gè)類VelocityResponseTransformer,而wiremock-velocity-transformer-standalone-x.x.jar很大包含了很多不同的包。
為了修改我們要拿到源碼,在GitHub上可以找到wiremock-velocity-transformer的源碼
 https://github.com/adamyork/wiremock-velocity-transformer
下載源碼后打開(kāi)項(xiàng)目,這時(shí)要注意當(dāng)前一定是最新版本的代碼,而自己使用的wiremock未必是最新版本的,所以要將代碼切到正確的tag下,比如使用的是wiremock-velocity-transformer-1.2.jar和wiremock-velocity-transformer-standalone-1.2.jar,那么checkout到1.2-release的tag上。否則會(huì)因?yàn)榇a的不同導(dǎo)致運(yùn)行出錯(cuò)。
打開(kāi)項(xiàng)目后可能會(huì)有一些依賴的問(wèn)題,因?yàn)檫@個(gè)build.gradle將所有層次依賴都列出的,而不是利用gradle來(lái)自動(dòng)管理依賴,這樣當(dāng)依賴版本不同時(shí)會(huì)出現(xiàn)依賴問(wèn)題。解決方法就是去掉不必要的依賴,只保留velocity-tools和wiremock這兩個(gè)依賴即可(也要保留junit用于測(cè)試),最終如下:
dependencies?{ //? ? compile? ? ? ? ?group:?"org.apache.velocity",? ? ? ? ? ?name:?"velocity",? ? ? ? ? ? ?version:?"1.7"compile? ? ? ? ?group:?"org.apache.velocity",? ? ? ? ? ?name:?"velocity-tools",? ? ? ?version:?"2.0"compile? ? ? ? ?group:?"com.github.tomakehurst",? ? ? ? name:?"wiremock",? ? ? ? ? ? ?version:?"1.57" //? ? compile? ? ? ? ?group:?"org.mortbay.jetty",? ? ? ? ? ? ?name:?"jetty",? ? ? ? ? ? ? ? version:?"6.1.26" //? ? compile? ? ? ? ?group:?"com.google.guava",? ? ? ? ? ? ? name:?"guava",? ? ? ? ? ? ? ? version:?"18.0" //? ? compile? ? ? ? ?group:?"com.fasterxml.jackson.core",? ? name:?"jackson-core",? ? ? ? ?version:?"2.4.2" //? ? compile? ? ? ? ?group:?"com.fasterxml.jackson.core",? ? name:?"jackson-annotations",? version:?"2.4.2" //? ? compile? ? ? ? ?group:?"com.fasterxml.jackson.core",? ? name:?"jackson-databind",? ? ?version:?"2.4.2" //? ? compile? ? ? ? ?group:?"org.apache.httpcomponents",? ? ?name:?"httpclient",? ? ? ? ? ?version:?"4.3.5" //? ? compile? ? ? ? ?group:?"org.skyscreamer",? ? ? ? ? ? ? ?name:?"jsonassert",? ? ? ? ? ?version:?"1.2.3" //? ? compile? ? ? ? ?group:?"xmlunit",? ? ? ? ? ? ? ? ? ? ? ?name:?"xmlunit",? ? ? ? ? ? ? version:?"1.5" //? ? compile? ? ? ? ?group:?"com.jayway.jsonpath",? ? ? ? ? ?name:?"json-path",? ? ? ? ? ? version:?"0.8.1" //? ? compile? ? ? ? ?group:?"org.slf4j",? ? ? ? ? ? ? ? ? ? ?name:?"slf4j-api",? ? ? ? ? ? version:?"1.7.6" //? ? compile? ? ? ? ?group:?"net.sf.jopt-simple",? ? ? ? ? ? name:?"jopt-simple",? ? ? ? ? version:?"4.7"compile?("junit:junit:4.11")?{exclude?group:?"org.hamcrest",?module:?"hamcrest-core"}testCompile?"org.hamcrest:hamcrest-all:1.3"testCompile?("org.jmock:jmock:2.5.1")?{exclude?group:?"junit",?module:?"junit-dep"exclude?group:?"org.hamcrest",?module:?"hamcrest-core"exclude?group:?"org.hamcrest",?module:?"hamcrest-library"}testCompile?("org.jmock:jmock-junit4:2.5.1")?{exclude?group:?"junit",?module:?"junit-dep"exclude?group:?"org.hamcrest",?module:?"hamcrest-core"exclude?group:?"org.hamcrest",?module:?"hamcrest-library"}testCompile?"net.sf.json-lib:json-lib:2.4:jdk15"testCompile?"com.googlecode.jarjar:jarjar:1.3"testCompile?"commons-io:commons-io:2.4" }在這個(gè)項(xiàng)目中也只有VelocityResponseTransformer類,轉(zhuǎn)換就是在這里進(jìn)行的,關(guān)鍵方法如下:
private?void?transformResponse(final?ResponseDefinition?response)?throws?Exception?{final?String?templatePath?=?fileSource.getPath().concat("/"?+?response.getBodyFileName());final?Template?template?=?Velocity.getTemplate(templatePath);StringWriter?writer?=?new?StringWriter();template.merge(context,?writer);final?byte[]?fileBytes?=?String.valueOf(writer.getBuffer()).getBytes();response.setBody(fileBytes);response.setBodyFileName(null); }問(wèn)題就出現(xiàn)在Velocity.getTemplate(templatePath)這句
這里沒(méi)有指定編碼,則會(huì)使用默認(rèn)編碼,實(shí)際上Velocity提供了附帶編碼的方法,所以修改為
Velocity.getTemplate(templatePath, "utf-8")
即可,在項(xiàng)目的resource下的文件中添加中文,運(yùn)行測(cè)試用例VelocityResponseTransformerTest就會(huì)發(fā)現(xiàn)可以獲得正常的中文了。
最后就是要打包jar,通過(guò)測(cè)試發(fā)現(xiàn)wiremock-velocity-transformer-x.x.jar和wiremock-velocity-transformer-standalone-x.x.jar這兩個(gè)jar包中都有VelocityResponseTransformer類,所以這兩個(gè)jar包都需要替換。但是項(xiàng)目中只有一個(gè)類,打出wiremock-velocity-transformer-x.x.jar這個(gè)jar包還比較容易,但是wiremock-velocity-transformer-standalone-x.x.jar很難手動(dòng)打出。
其實(shí)在build.gradle中已經(jīng)有了打包的task,本來(lái)的目的是為了打包上傳到倉(cāng)庫(kù)。代碼如下:
fatJar?{archiveName?=?"wiremock-velocity-transformer-standalone-"?+?fatJar.version?+?".jar"manifest?{attributes?"Implementation-Title"? ?:?"wiremock-velocity-transformer-standalone","Implementation-Version"?:?version} }task?cleanFunctional(type:?Delete)?{delete?fileTree(dir:?"functional",?include:?"*-velocity-transformer-*.jar",?exclude:?"wiremock-1.55-standalone.jar") }task?copyFunctional(type:?Copy)?{from?"build/libs/"include?"*.jar"exclude?"*-sources.jar","*-javadoc.jar"into?"functional/" }task?javadocJar(type:?Jar,?dependsOn:?javadoc)?{classifier?=?"javadoc"from?"build/docs/javadoc" }task?sourcesJar(type:?Jar)?{from?sourceSets.main.allSourceclassifier?=?"sources" }jar?{dependsOn?fatJardependsOn?cleanFunctionaldependsOn?copyFunctionalcleanFunctional.shouldRunAfter?fatJarcopyFunctional.dependsOn?cleanFunctionalcopyFunctional.shouldRunAfter?cleanFunctionalarchiveName?=?"wiremock-velocity-transformer-"?+?jar.version?+?".jar"manifest?{attributes?"Implementation-Title"? ?:?"wiremock-velocity-transformer","Implementation-Version"?:?version} }artifacts?{archives?jararchives?javadocJararchives?sourcesJar }我們只需要打包,而不需要上傳,所以要在uploadArchives中做手腳,代碼如下
uploadArchives?{repositories?{mavenDeployer?{beforeDeployment?{MavenDeployment?deployment?->?signing.signPom(deployment)}repository(url:?"https://oss.sonatype.org/service/local/staging/deploy/maven2/")?{authentication(userName:?"",?password:?"")}pom.project?{name?"wiremock-velocity-transformer"packaging?"jar"description?"transformer?used?to?render?velocity?templates?for?stubbed?responses."url?"https://github.com/radAdam/wiremock-velocity-transformer"scm?{url?"scm:git@github.com:radAdam/wiremock-velocity-transformer.git"connection?"scm:git@github.com:radAdam/wiremock-velocity-transformer.git"developerConnection?"scm:git@github.com:radAdam/wiremock-velocity-transformer.git"}licenses?{license?{name?"The?Apache?Software?License,?Version?2.0"url?"http://www.apache.org/licenses/LICENSE-2.0.txt"distribution?"repo"}}developers?{developer?{id?"adamcyork"name?"Adam?York"}}}}} }在uploadArchives這個(gè)task下,我們將倉(cāng)庫(kù)的賬號(hào)和密碼隨便修改(本來(lái)也沒(méi)有賬號(hào)和密碼,但是之前的兩個(gè)變量如果不刪掉則gradle無(wú)法成功),這樣在上傳時(shí)就會(huì)失敗停下,但是前面的步驟都會(huì)完成。
運(yùn)行uploadArchives這個(gè)task,完成后在項(xiàng)目中build/libs下就可以看到打好的jar包,將wiremock-velocity-transformer-x.x.jar和wiremock-velocity-transformer-standalone-x.x.jar替換掉wiremock中原有的。
在.vm文件中添加中文,啟動(dòng)wiremock,訪問(wèn)對(duì)應(yīng)接口就會(huì)發(fā)現(xiàn)中文數(shù)據(jù)不再亂碼了。
?
總結(jié)
以上是生活随笔為你收集整理的解决wiremock中velocity脚本(.vm)中文编码乱码问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
                            
                        - 上一篇: windows下安装配置mongodb
 - 下一篇: Android魔术——手把手教你实现水晶