默认情况下,Jenkins在构建的时候会输出脚本中命令的具体内容,原因是在执行脚本的时候,使用的是-e参数执行的。
但是当我们的脚本中存在用户名,密码等关键信息的时候,这些内容会被输出到编译日志中,这样就容易导致安全问题。
解决办法是在脚本的最前面增加#!/bin/bash,来覆盖脚本执行的默认参数,如下图:
默认情况下,Jenkins在构建的时候会输出脚本中命令的具体内容,原因是在执行脚本的时候,使用的是-e参数执行的。
但是当我们的脚本中存在用户名,密码等关键信息的时候,这些内容会被输出到编译日志中,这样就容易导致安全问题。
解决办法是在脚本的最前面增加#!/bin/bash,来覆盖脚本执行的默认参数,如下图:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# 要求Java 1.8 $ yum install java $ yum install subversion $ yum install tomcat $ /bin/systemctl restart tomcat.service $ wget https://get.jenkins.io/war/2.254/jenkins.war $ cp jenkins.war /usr/share/tomcat/webapps/ $ /bin/systemctl restart tomcat.service # 服务器访问地址 # http://158.220.155.188:8080/jenkins/ # apache $ yum install httpd $ /bin/systemctl restart httpd.service # apache 默认工作目录 /var/www/html/ |
为了安全考虑,首先需要解锁Jenkins
最近在搭建Jenkins环境,实现Android自动化编译的过程中,由于内网服务器不能访问外网,因此只能配置Robolectric访问内网的服务器。
根据官方文档 Configuring Robolectric,发现如果要更改Robolectric默认的下载服务器链接地址,需要在项目的每个lib库中都配置如下参数,才能实现:
|
1 2 3 4 5 6 7 8 |
android { testOptions { unitTests.all { systemProperty 'robolectric.dependency.repo.url', 'https://local-mirror/repo' systemProperty 'robolectric.dependency.repo.id', 'local' } } } |
但是这样配置有一个问题,就是没办法动态调整链接地址。
而我们使用
|
1 |
$ bash gradlew clean build -Drobolectric.dependency.repo.url=http://127.0.0.1/jcenter |
手工指定的参数,并没有在编译的时候生效。
参数丢失的原因是因为测试用例在新的JVM中执行,传入的参数不会自动带给新创建的JVM。
这时需要在Gradle脚本中将读到的值重新设到系统属性里面,才可以被Java程序读到。
|
1 2 3 4 5 6 7 8 9 10 11 |
android { testOptions { unitTests.all { //命令行下 单元测试可能卡住的问题 jvmArgs '-noverify' //robolectric外部指定下载资源链接的参数,使用 -D 参数指定 bash gradlew clean build -Drobolectric.dependency.repo.url=http://127.0.0.1/jcenter systemProperty 'robolectric.dependency.repo.url', System.getProperty("robolectric.dependency.repo.url") systemProperty 'robolectric.dependency.repo.id', System.getProperty("robolectric.dependency.repo.id") } } } |
每个项目的build.gradle中都增加上面的配置之后,就可以保证在外部编译的时候动态指定参数了。
在 Android Studio Chipmunk | 2021.2.1 Patch 1 以及以上的版本,可能会发生如下报错:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
URI is not absolute java.lang.IllegalArgumentException: URI is not absolute at java.base/java.net.URL.fromURI(URL.java:692) at java.base/java.net.URI.toURL(URI.java:1116) at org.robolectric.internal.dependency.MavenArtifactFetcher.getRemoteUrl(MavenArtifactFetcher.java:138) at org.robolectric.internal.dependency.MavenArtifactFetcher.fetchToStagingRepository(MavenArtifactFetcher.java:145) at org.robolectric.internal.dependency.MavenArtifactFetcher.fetchArtifact(MavenArtifactFetcher.java:65) at org.robolectric.internal.dependency.MavenDependencyResolver.lambda$getLocalArtifactUrls$0(MavenDependencyResolver.java:80) at org.robolectric.internal.dependency.MavenDependencyResolver.whileLocked(MavenDependencyResolver.java:100) at org.robolectric.internal.dependency.MavenDependencyResolver.getLocalArtifactUrls(MavenDependencyResolver.java:75) at org.robolectric.internal.dependency.MavenDependencyResolver.getLocalArtifactUrls(MavenDependencyResolver.java:65) at org.robolectric.internal.dependency.MavenDependencyResolver.getLocalArtifactUrl(MavenDependencyResolver.java:116) at org.robolectric.plugins.LegacyDependencyResolver.getLocalArtifactUrl(LegacyDependencyResolver.java:89) at org.robolectric.plugins.DefaultSdkProvider$DefaultSdk.getJarPath(DefaultSdkProvider.java:146) at org.robolectric.internal.AndroidSandbox$SdkSandboxClassLoader.<init>(AndroidSandbox.java:102) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490) at org.robolectric.util.inject.Injector.inject(Injector.java:250) at org.robolectric.util.inject.Injector.lambda$memoized$1(Injector.java:232) at org.robolectric.util.inject.Injector$MemoizingProvider.get(Injector.java:498) at org.robolectric.util.inject.Injector.getInstanceInternal(Injector.java:224) at org.robolectric.util.inject.Injector.resolveDependencies(Injector.java:296) at org.robolectric.util.inject.Injector.inject(Injector.java:248) at org.robolectric.util.inject.Injector.lambda$memoized$1(Injector.java:232) at org.robolectric.util.inject.Injector$MemoizingProvider.get(Injector.java:498) at org.robolectric.util.inject.Injector.getInstanceInternal(Injector.java:224) at org.robolectric.util.inject.Injector.getInstance(Injector.java:208) at org.robolectric.util.inject.Injector.access$700(Injector.java:96) at org.robolectric.util.inject.Injector$ScopeBuilderProvider.create(Injector.java:564) at org.robolectric.util.inject.Injector$ScopeBuilderProvider.lambda$get$0(Injector.java:547) at com.sun.proxy.$Proxy19.build(Unknown Source) at org.robolectric.internal.SandboxManager.getAndroidSandbox(SandboxManager.java:57) at org.robolectric.RobolectricTestRunner.getSandbox(RobolectricTestRunner.java:285) at org.robolectric.RobolectricTestRunner.getSandbox(RobolectricTestRunner.java:68) at org.robolectric.internal.SandboxTestRunner$2.evaluate(SandboxTestRunner.java:236) at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63) at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) at org.robolectric.internal.SandboxTestRunner$1.evaluate(SandboxTestRunner.java:93) at org.junit.runners.ParentRunner.run(ParentRunner.java:413) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38) at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62) at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) at com.sun.proxy.$Proxy2.processTestClass(Unknown Source) at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176) at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129) at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100) at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60) at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56) at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133) at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71) at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69) at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74) |
该报错的原因是 Android Studio 没有正确读取我们配置的 robolectric.dependency.repo.url 环境变量,导致无法成功下载,当然也可能是由于高版本不支持 HTTP ,链接地址必须是 HTTPS 导致此问题,这个没有深究。
解决方法是,在命令行执行
|
1 |
$ bash gradlew clean build -Drobolectric.dependency.repo.url=http://127.0.0.1/jcenter |
确保在当前用户目录下的 .m2 目录下,成功完成 robolectric 需要的全部文件的下载。这样,执行测试用例的时候,就可以从本地获取依赖文件,而不需要再去服务器上获取。
另外更推荐的方法是通过 Tomcat 的配置文件完成,而不是修改代码,具体配置方法为:
在 conf/server.xml 配置文件中的 <Host> 配置项中添加如下配置:
|
1 |
<Valve className="org.apache.catalina.valves.ErrorReportValve" showReport="false" showServerInfo="false" /> |
配置项说明:
其他的方案跟 Ubuntu 14.04隐藏Tomcat-7.0.52的版本号与操作系统类型 是一致的,但是具体的细节上存在不小的差异,还是需要记录一下。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ cd ~ $ mkdir catalina $ cd catalina $ cp /usr/share/tomcat9/lib/catalina.jar . $ unzip catalina.jar $ cd org/apache/catalina/util $ vim ServerInfo.properties |
可以看到里面的内容如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. server.info=Apache Tomcat/9.0.16 (Ubuntu) server.number=9.0.16.0 server.built=Sep 11 2019 19:47:51 UTC |
直接注释掉里面的内容,如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # server.info=Apache Tomcat/9.0.16 (Ubuntu) # server.number=9.0.16.0 # server.built=Sep 11 2019 19:47:51 UTC |
修改完成后,把修改完成的数据存储到catalina.jar中。
|
1 2 3 4 5 6 7 |
$ cd ~ $ cd catalina $ sudo apt install openjdk-11-jdk-headless $ jar uvf catalina.jar org/apache/catalina/util/ServerInfo.properties |
把修改后的catalina.jar放回到Tomcat的目录下面:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ cd ~ $ cd catalina $ sudo unlink /usr/share/tomcat9/lib/catalina.jar $ sudo mv /usr/share/java/tomcat9-catalina.jar /usr/share/java/tomcat9-catalina.jar.old $ sudo cp catalina.jar /usr/share/java/ $ sudo chmod +r /usr/share/java/catalina.jar $ cd /usr/share/tomcat9/lib $ sudo ln -s ../../java/catalina.jar catalina.jar |
重启Tomcat的服务
|
1 |
$ sudo service tomcat9 restart |
腾讯云Ubuntu Server 16.04.7 LTS升级系统到Ubuntu Server 18.04.5 LTS之后,letsencrypt证书更新出现异常,如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$ sudo ./letsencrypt-auto Error: couldn't get currently installed version for /opt/eff.org/certbot/venv/bin/letsencrypt: Traceback (most recent call last): File "/opt/eff.org/certbot/venv/bin/letsencrypt", line 7, in <module> from certbot.main import main File "/opt/eff.org/certbot/venv/local/lib/python2.7/site-packages/certbot/main.py", line 2, in <module> from certbot._internal import main as internal_main File "/opt/eff.org/certbot/venv/local/lib/python2.7/site-packages/certbot/_internal/main.py", line 6, in <module> import logging.handlers File "/usr/lib/python2.7/logging/__init__.py", line 26, in <module> import sys, os, time, cStringIO, traceback, warnings, weakref, collections File "/usr/lib/python2.7/weakref.py", line 14, in <module> from _weakref import ( ImportError: cannot import name _remove_dead_weakref |
原因为系统版本变化过大导致以前安装的Python组件不能适应最新的系统,最简单的方法就是删除之前安装的Python组件,让letsencrypt重新安装即可。
|
1 2 3 4 5 |
$ sudo apt-get install python-pip $ sudo rm -rf /opt/eff.org/ $ sudo ./letsencrypt-auto |
Cannot renew certificate “ImportError: cannot import name _remove_dead_weakref”
参考 阿里云ECS ubuntu 14.04.5 LTS升级到ubuntu 16.04.2 LTS / 阿里云从ubuntu16.04.5升级到ubuntu 18.04.3后调整PHP 7.0到PHP 7.2 整个的升级步骤是差不多的,腾讯的升级流程更加顺利。
但是在升级完成之后,遇到了一个域名解析问题,报错如下:
|
1 2 3 4 5 6 7 8 9 10 |
$ ping www.baidu.com ping: www.baidu.com: Temporary failure in name resolution $ sudo apt-get update Err:1 http://mirrors.tencentyun.com/ubuntu bionic InRelease Temporary failure resolving 'mirrors.tencentyun.com' Err:2 http://mirrors.tencentyun.com/ubuntu bionic-security InRelease Temporary failure resolving 'mirrors.tencentyun.com' Err:3 http://mirrors.tencentyun.com/ubuntu bionic-updates InRelease Temporary failure resolving 'mirrors.tencentyun.com' |
这个原因是因为我们在安装过程中,覆盖了腾讯设置的域名解析服务配置文件。
这个配置文件是/etc/resolv.conf。
但是,在Ubuntu Server 18.04.5 LTS系统上,直接修改/etc/resolv.conf的话,重启系统之后,设置会被还原。我们需要修改/etc/systemd/resolved.conf才行。
根据地域的不同,服务器的地址存在差异,参考下面的脚本即可。
广州服务器:
|
1 2 3 4 5 6 7 8 |
# 不存在则增加 $ sudo sed -i "s/^#DNS=.*/DNS=10.138.224.65 10.182.20.26 10.182.24.12/g" /etc/systemd/resolved.conf # 存在则替换 $ sudo sed -i "s/^DNS=.*/DNS=10.138.224.65 10.182.20.26 10.182.24.12/g" /etc/systemd/resolved.conf # 重启服务,配置生效 $ sudo systemctl restart systemd-resolved.service |
上海服务器:
|
1 2 3 4 5 6 7 8 |
# 不存在则增加 $ sudo sed -i "s/^#DNS=.*/DNS=10.236.158.106 10.237.148.54 10.237.148.60/g" /etc/systemd/resolved.conf # 存在则替换 $ sudo sed -i "s/^DNS=.*/DNS=10.236.158.106 10.237.148.54 10.237.148.60/g" /etc/systemd/resolved.conf # 重启服务,配置生效 $ sudo systemctl restart systemd-resolved.service |
香港服务器:
|
1 2 3 4 5 6 7 8 |
# 不存在则增加 $ sudo sed -i "s/^#DNS=.*/DNS=10.243.28.52 10.145.0.57 10.145.0.58/g" /etc/systemd/resolved.conf # 存在则替换 $ sudo sed -i "s/^DNS=.*/DNS=10.243.28.52 10.145.0.57 10.145.0.58/g" /etc/systemd/resolved.conf # 重启服务,配置生效 $ sudo systemctl restart systemd-resolved.service |
编辑strings.xml的时候
|
1 |
<string name="myurl">http://code.dd.com/rr?q=%rr.55</string> |
或者
|
1 |
<string name="message_content'>恭喜您你获得%1s 积分,占比%2s %</string> |
提示下面的错误
|
1 2 3 4 |
Multiple annotations found at this line: - error: Multiple substitutions specified in non-positional format; did you mean to add the formatted="false" attribute? - error: Unexpected end tag string |
出现这个错误的原因主要是因为strings字串中包含百分号(%),
|
1 2 3 |
<string name="myurl">http://code.dd.com/rr?q=%%rr.55</string> <string name="message_content">恭喜您你获得%1s 积分,占比%2s %%</string> |
|
1 |
<string name="myurl">http://code.dd.com/rr?q=\%rr.55</string> |
根据错误提示可知,如果字符串无需格式化,可在<string> 标签上增加属性:formatted="false",即
|
1 |
<string name="myurl" formatted="false">http://code.dd.com/rr?q=%rr.55</string> |
如果你需要使用String.format(String, Object...) 来格式化你的字符串,你可以把格式化参数放在你的字符串中,参见下面的例子:
|
1 |
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string> |
在这个例子中,这个格式化的字符串有2个参数, %1$s是个字符串%2$d是个浮点数,你可以在你的程序中按照下面的方法来根据参数来格式化字符串:
|
1 2 3 |
Resources res = getResources(); String text = String.format(res.getString(R.string.welcome_messages), username, mailCount); |
目前Android的SDK已经支持直接格式化字符串,不需要使用String.format(String, Object...) ,如下
|
1 2 3 |
Resources res = getResources(); String text = res.getString(R.string.welcome_messages, username, mailCount); |
那么根据例子上说的我需要把%s换成%1$s才行了,修改后编译通过,程序成功启动。
今天发现cn.archive.ubuntu.com不能更新了,只能换成国内源:
|
1 2 3 4 |
$ sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak # 阿里云 $ sudo sed -i "s/cn.archive.ubuntu.com/mirrors.aliyun.com/g" /etc/apt/sources.list |
如题所示,之前一直使用commons-lang3-3.x.jar 这个jar包里面的 org.apache.commons.lang3.StringEscapeUtils 类来转义特殊字符,但是最近发现使用这个类会出现以下提示:
|
1 2 3 4 |
Multiple markers at this line - The type StringEscapeUtils is deprecated - The method escapeXml11(String) from the type StringEscapeUtils is deprecated |
看提示是说 StringEscapeUtils 这个类已经过期了,提醒使用新的替代类。看了下这个类的官方文档,很自然地找到了新的替代类——org.apache.commons.text.StringEscapeUtils
因此,使用Maven引用相应的jar包即可解决这个问题:
|
1 2 3 4 5 |
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-text</artifactId> <version>1.9</version> </dependency> |
或者直接去Maven仓库下载这个jar包,下载地址如下:http://mvnrepository.com/artifact/org.apache.commons/commons-text/1.1
apache日志记录的中文,是内码如下:
|
1 |
\xb6\xd4\xb6\xc0\xc1\xa2\xd1\xa7\xd4\xba\xbf\xc9\xb3\xd6\xd0\xf8\xb7\xa2\xd5\xb9\xce\xca\xcc\xe2 |
编码后中文是:
|
1 |
对独立学院可持续发展问题 |
完全看不懂是什么意思,如何解析出里面的中文出来呢?
php参考如下代码:
|
1 2 3 4 5 |
<?php $str="\xb6\xd4\xb6\xc0\xc1\xa2\xd1\xa7\xd4\xba\xbf\xc9\xb3\xd6\xd0\xf8\xb7\xa2\xd5\xb9\xce\xca\xcc\xe2"; eval("\$str = \"$str\";"); echo iconv('GB2312','UTF-8',$str."\n"); ?> |
golang参考如下代码:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import ( "fmt" "log" "os" "code.google.com/p/mahonia" ) func main() { var use_logfile bool use_logfile = true f, err := os.OpenFile("testlogfile", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) if err != nil { log.Fatalf("error opening file: %v", err) } defer f.Close() if use_logfile { log.SetOutput(f) } s := "\xb6\xd4\xb6\xc0\xc1\xa2\xd1\xa7\xd4\xba\xbf\xc9\xb3\xd6\xd0\xf8\xb7\xa2\xd5\xb9\xce\xca\xcc\xe2" enc := mahonia.NewDecoder("UTF-8") x := enc.ConvertString(s) gbk := mahonia.NewDecoder("gbk") n := gbk.ConvertString(s) log.Printf("file:", x, n) fmt.Println(x, n) } |
java参考如下代码:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.StandardCharsets; public class HelloWorld { private static String unescapeGBK(final String s) { final StringBuilder buf = new StringBuilder(); int i = 0; int len = s.length(); while (i < len) { int ch = s.charAt(i); if (ch == '\\') { // \xXX\xXX : map to unicode(XXXX) int c = (char) ((Character.digit(s.charAt(i + 2), 16) << 4) + Character.digit(s.charAt(i + 3), 16)); c = c << 8; c += (char) ((Character.digit(s.charAt(i + 6), 16) << 4) + Character.digit(s.charAt(i + 7), 16)); buf.append((char) c); i += 7; } else { buf.append((char) ch); } i++; } return buf.toString(); } public static void main(String args[]) throws UnsupportedEncodingException { // UTF-8 String coderStr = "\\x22\\xE5\\x93\\x88\\xE5\\x93\\x88\\x22"; String str = coderStr.replaceAll("\\\\x", "%"); str = URLDecoder.decode(str, StandardCharsets.UTF_8.toString()); System.out.println(str); // GBK coderStr = "\\xb6\\xd4\\xb6\\xc0\\xc1\\xa2\\xd1\\xa7\\xd4\\xba\\xbf\\xc9\\xb3\\xd6\\xd0\\xf8\\xb7\\xa2\\xd5\\xb9\\xce\\xca\\xcc\\xe2"; str = getApacheChineseGBK(coderStr); System.out.println(str); } public static String getApacheChineseGBK(String str) throws UnsupportedEncodingException { str = str.trim().toLowerCase(); str = unescapeGBK(str); final ByteBuffer byteBuffer = ByteBuffer.allocate(str.length() * Character.SIZE / Byte.SIZE); final CharBuffer converter = byteBuffer.asCharBuffer(); converter.append(CharBuffer.wrap(str)); str = new String(byteBuffer.array(), "GBK"); return str; } } |