在向Jenkins发送请求时收到了这样的403错误信息: 我们使用的Jenkins的版本是2.7。 后来通过google找到了解决方案。 在系统管理 –> Configure Global Security中调整设置: 取消“启用安全(Enable security)”的勾选; 取消“防止跨站点请求伪造(Prevent Cross Site Request Forgery exploits)”的勾选。 结果如下图: 就这样! 第一步不要执行了。我被误导了,最后丢失了用户权限系统。只需要执行第二步就可以。如果还坚持要启用“防止跨站点请求伪造”,需要先动态获取crumb。可以参考Jenkins wiki中《CSRF Protection》一节。 ########
[阅读更多...]-
no valid crumb was included in the request解决
-
一个中文乱码的问题
前两天同事问了我一个中文乱码的问题。他写了一个json请求的接口,通过浏览器请求接口的时候,返回的json中包含的中文显示了乱码。后来使用jmeter进行测试时也发现返回的是乱码。 之前也遇到过几次Java/JSP中文乱码的问题,知道乱码通常发生在字节流和字符相互转换的过程中。检查了一些这个接口涉及到的几次字节流转换的地方都没发现问题。我这个同事还是挺细心的,注意了统一使用UTF8进行编码,并且在输出接口内容时也添加了“response.setCharacterEncoding(“UTF-8”);”这样的代码。所以尝试将问题定位在浏览器显式前后:在PrintWriter输出前打印日志,如果中文在日志上可以正确显示那么问题就应该是出在浏览器端了,否则就从继续从后端找原因。结果还没观察日志呢,另一个同事查看了一下浏览器的内容编码设置,发现浏览器的内容编码设置的是GBK。问题就这样解决了:将浏览器的内容编码设置改为UTF8后问题就解决了。 问题是解决了,但是产生了一个疑问:为什么我们的程序没有提示浏览器该使用什么样的编码来解析接收到的信息呢。查了一些资料知道了该怎么设置就能完美解决这个问题了。这涉及到ServletResponse设置编码的几个方法。ServletResponse设置编码有如下三个方法: response.setCharacterEncoding(“UTF-8”); response.setContentType(“text/html;charset=UTF-8”); response.setLocale(new java.util.Locale(“zh”,”CN”)); 简单解释下这几个方法及其优先级: 第一种方法只能用来设置out输出流中所采用的编码,但是它的优先权最高,可以覆盖后面两种方法中的设置; 第二中方法可以设置out输出流中字符的编码方式,也可以设置浏览器接收到这些字符后以什么编码方式来解码,它的优先权低于第一种方法,但高于第三种方法; 第三种方法只能用来设置out输出流中字符的编码方式,但是它的优先权最低,在已经使用前两种方法中的一个设置了编码方式以后,它就被覆盖而不起作用了。 所以,使用response.setContentType可以完美解决前面提到的那个问题。 此外,还需要注意使用的ContentType,因为我同事写的接口返回的是json,所以他使用的content-type应该是“application/json”。 就这样! ########
[阅读更多...] -
关于https的一个错误
前两天我维护的服务出了一个问题,在请求一个连接时发生了Exception: 异常大致说的是在进行https请求时,验证证书出了问题。 服务基于JDK1.6,使用httpclient(版本是4.5.1)发送请求,调用的URL是https://talkingdata.qccr.com。 异常中的信息说的是请求的地址(talkingdata.qccr.com)与获得的证书中的hostName(*.qichechaoren.com)不符,因此在SSLPeerUnverifiedException.verifyHostname()方法中抛出了异常。但是在浏览器中发送请求或者是通过curl命令都是能够访问的。最让人郁闷的是在我的机器上使用原程序执行调用也没有报异常;把相关的程序封装成jar扔到服务器上调用还是正常的。 想了一段时间,在curl命令中添加了SSL信息,像这样: 2和3分别表示用的是sslv2和sslv3。果然报错了。后来又发现了SSL的实现还有TLS,试着使用TLS协议请求是正确的: 之前没有想到过SSL协议这里,打开浏览器看了一下这个地址的证书果然是TLS的: 看样子是在处理TLS请求时出了问题。 接下来就是定位问题的出处了。既然程序是可以正常执行的,那么就极有可能是出在容器上。把相关的程序重新封装下扔到jetty中执行果然报异常了。当时认为问题就是出在jetty上了,可能是服务与容器间存在类冲突。容器的类是不好轻易换的,只好改程序了。原程序是这样子的: 需要调整的就是SSL的支持那一块。将对https的验证强行去掉好了。只需要改一处: 现在请求是可以不报异常了。因为所有关于hostName的验证都是返回true 隔天和同事说起这件事,同事提供了一个信息:生产环境上的jetty容器使用的jdk和系统jre是不一样的…. jetty容器使用的是jdk1.6,服务器jre是1.7,我开发用的机器jdk是1.8。当时居然没有想到这上头。问题有可能是出在jre上啊。所以最后将jetty使用的jdk版本升级以后就好了。 今天也尝试着定位问题发生的具体位置来着,后来发现是在handshake的时候,jdk1.6和jdk1.7会返回不同的证书信息。更具体的信息想要获取就有些困难了,因为相关的部分代码是不开源的。 之前本以为是这个地址的证书是采用的TLS1.2,而jdk1.6的大部分版本都是不支持TLS1.2的。后来使用工具分析了请求的地址,发现支持的协议包括TLS1.0、TLS1.1、TLS1.2。而TLS1.0在JDK1.1的时候就已经支持了。 已经在这个问题上用了四分之一个周末的时间了,还有其他事情要做,目前只好暂时放下了。 一个SSL分析的网址:https://www.ssllabs.com/ssltest/analyze.html。 openJdk关于TLS1.2的BUG清单:https://bugs.openjdk.java.net/browse/JDK-6916074。 ##############
[阅读更多...] -
Java实现邮件发送过程中遇到的几个问题
发送邮件的代码是我从以前的一个应用上直接拷贝过来的。以前使用的腾讯的邮件服务,程序执行起来没有任何问题。后来修改为微软office365邮件服务后,却遇到了两个问题。 问题一,tls加密设置 异常信息如下: 这个解决起来比较容易。找了些资料,添加如下配置即可: 问题二,提示协议为null: 异常信息如下: 这个问题是在将应用部署到生产环境后才遇到的。经检查后发现调用的jar包不是我在maven中指定的版本。后来确认是应用使用的jar包和容器(就是jetty)使用的jar包冲突了。容器使用的jar版本较旧,不过默认优先加载容器的jar。这样问题解决思路有两个: 依赖容器的jar重新写代码; 更新容器的jar。 第二个选择多少有些危险,就采用第一个选项好了,只需要修改一行即可: 这个问题在javax.mail 1.4版本中会出现。之后较高的版本会默认采用SMTP协议发送邮件。 修改后的程序: ##
[阅读更多...]