作者: htynkn

  • 网站乱码和ISO-8859-1与UTF-8

    今天没事看看博客访问量,发现每天有大量流量来自于关于Spring Boot乱码问题的关键字。基本上达到了网站流量的30%以上。十分费解乱码问题为什么这么多人遇到。

    Spring Boot中的乱码问题解决方案非常简单,修改配置中的force为true即可,这里不再叙述。Spring Boot和其中的Spring MVC等只是java世界构建网站的一种选项,还有很多其他语言和其他框架,不过乱码问题是一个很泛的问题,并不是绑定在任何一种语言和框架上的。

    我们常说的网站乱码其实是指http请求的编码有问题。原因很简单,默认的编码是ISO-8859-1,而这种编码是一种80年代的遗留标准,它只能表示256个字符,即便对于西方英语用户,这种编码也有很多符号不能正确解决,当然中文更不用说了。

    UTF-8是UTF家族的,相对要新,而解决的问题更多,对于绝大部分文字都有很好的支持,属于事实上的标准。

    因为ISO-8859-1是历史遗留的标准,所以绝大部分容器仍然都是将其作为默认编码,包括Apache,Tomcat,WebSphere等,而Spring Boot是内嵌Tomcat运行,所以默认编码也是ISO-8859-1,虽然复写了编码为UTF-8,但是并没有设置为force encoding,所以一些版本依然会乱码。

    因为默认编码问题在很多地方都存在,所以标准也是相互影响的。

    简单来看历史进程是这样的:

    1. 最开始是ASCII,今天也有大量遗留系统使用着
    2. 在WIndow流行时,默认编码是ANSI,也叫Windows-1252
    3. 后来就是ISO-8859-1,这是是随着HTML 2.0标准固定下来的
    4. 再到后来的UTF-8,HTML5的默认编码已经是UTF-8了

    参考

    http://www.w3schools.com/charsets/

    https://www.w3.org/International/articles/http-charset/index

    https://en.wikipedia.org/wiki/UTF

    https://en.wikipedia.org/wiki/UTF-8…

  • Spark快速获得CrossValidator的最佳模型参数

    Spark快速获得CrossValidator的最佳模型参数

    Spark提供了便利的Pipeline模型,可以轻松的创建自己的学习模型。

    但是大部分模型都是需要提供参数的,如果不提供就是默认参数,那么怎么选择参数就是一个比较常见的问题。Spark提供在org.apache.spark.ml.tuning包下提供了模型选择器,可以替换参数然后比较模型输出。

    目前有CrossValidator和TrainValidationSplit两种,比如一个文本情感预测模型。

    Pipeline只有三步,第一步切词,第二部Hashing TF,第三部NB分类

    Pipeline pipeline = new Pipeline()
                    .setStages(new PipelineStage[]{tokenizer, hashingTF, naiveBayes});
    
    ParamMap[] paramMaps = new ParamGridBuilder()
                    .addGrid(hashingTF.numFeatures(), new int[]{10000, 100000, 500000, 1000000})
                    .build();
    CrossValidator cv = new CrossValidator()
                    .setEstimator(pipeline)
                    .setEvaluator(new BinaryClassificationEvaluator())
                    .setEstimatorParamMaps(paramMaps);

    其中Hashing TF的参数选择非常重要,我们这里就随便尝试几种,然后放在CrossValidator中去。

    最后我们会获得一个CrossValidatorModel类,这里有两种选择。

    第一种是自己手动获取其中的参数,因为bestModel的参数就是我们最后选择的参数

    Pipeline 
  • 使用ThrowOnFailure属性捕获Tomcat启动时的错误

    Tomcat是一个广泛使用的容器,不仅仅独立使用对外暴露服务,也可以用集成模式运行在其他程序内部或者支持测试。

    Tomcat的Connector是一个重要的部分,如果它启动失败,那么意味着容器无法正常对外暴露服务。

    在Tomcat中如果Connector启动失败,日志中会打印相关信息(两次),这种情况对于作为独立服务对外暴露的情况还好,查查日志解决问题。如果是作为集成模式的话就有点麻烦了。比如Spring Boot内嵌了Tomcat,为了在启动时给用户提供更好的体验,Spring Boot有一个错误分析器,也就是说当有错误发生的时候给出更友好的提示,而不是简单的打印日志。

    自己的代码当然好控制,但是内嵌的Tomcat就是一个问题,外部没法简单获得信息。

    Tomcat最近有一个更改解决了这个问题,在Connector中新增了一个throwOnFailure属性,当这个属性为真时,就会抛出LifecycleException错误。

    try {
    Connector c = new Connector("foo.Bar");
    c.setThrowOnFailure(throwOnFailure);
    c.start();
    }catch (LifecycleException ex){
      // 分析错误
    }

     

     

    参考:

    http://svn.apache.org/viewvc?view=revision&revision=1763769

    https://bz.apache.org/bugzilla/show_bug.cgi?id=60152…

  • 再谈Spring Boot中的乱码和编码问题

    再谈Spring Boot中的乱码和编码问题

    编码算不上一个大问题,即使你什么都不管,也有很大的可能你不会遇到任何问题,因为大部分框架都有默认的编码配置,有很多是UTF-8,那么遇到中文乱码的机会很低,所以很多人也忽视了。

    Spring系列产品大量运用在网站开发中,而Spring Boot是为了简化配置而出现的,理论上讲Spring Boot应该默认配置UTF-8为默认编码,但是网络上依然可以看到很多关于Spring Boot乱码的文章,大部分解决方案沿用Spring MVC的方案,自定义EncodingFilter。

    但是仔细查看Spring Boot的文档,可以看到默认的编码的确是UTF-8

    spring.http.encoding.charset=UTF-8 # Charset of HTTP requests and responses. Added to the "Content-Type" header if not set explicitly.
    spring.http.encoding.enabled=true # Enable http encoding support.

    而相关的配置会在HttpEncodingAutoConfiguration中使用

    @Bean
    	@ConditionalOnMissingBean(CharacterEncodingFilter.class)
    	public CharacterEncodingFilter characterEncodingFilter() {
    		CharacterEncodingFilter filter 
  • 在AWS Lambda中运行Spring Boot应用

    在AWS Lambda中运行Spring Boot应用

    AWS Lambda 是一种计算服务。首先将代码上传到 AWS Lambda ,它按使用时间收费,有自动伸缩等功能,也就是说你上传了代码,其他事情你就不用管了。

    从字面上看你上传的代码是一个函数,那么就需要一个触发器来调用你的函数。AWS提供了若干触发器,其中就有API Gateway。这意味着你可以暴露一个HTTP或者HTTPS的调用地址,然后执行对应的函数。

    因为AWS Lambda有自己的一些要求,所以很明显是无法直接运行Spring Boot应用的,需要修改一下入口才能实现对应的功能。

    首先在依赖中加入aws的依赖

    compile group: 'com.amazonaws', name: 'aws-java-sdk-core', version: '1.11.48'

    这个依赖中包含了我们必须实现的接口RequestHandler

    package com.amazonaws.services.lambda.runtime;
    
    import com.amazonaws.services.lambda.runtime.Context;
    
    /**
     * 
     * Lambda request handlers implement AWS Lambda Function application logic using plain old java 
  • 使用AWS Elastic Beanstalk发布spring boot应用

    Elastic Beanstalk是AWS提供的快速使用AWS的部署和管理应用程序。

    Elastic Beanstalk提供了很多常用语言的快速上手的模板,可以直接从中启动。以一般的Spring Boot应用为例,进入以后选择“Web 服务器”套餐,语言选择JAVA,默认语言版本为JAVA 8。

    然后选择上传代码。

    Elastic Beanstalk提供了两个自定义选项,一个是源码的编译,一个是环境的自定义。

    先来看看Buildfile。选择在服务器编译的原因有很多种,有些是真的必须要本地编译,有的是包实在太大,对于Spring Boot应用来说,50M以上的jar真的很常见,上传上去真的很麻烦。

    所以Buildfile中直接调用gradle打包即可

    build: gradle build -x test

    打包之后jar包会放在build/libs下面,这里就还需要指定在EC2上运行的命令,不然没法定位jar包位置,这个就用Procfile文件

    web: java -jar build/libs/your.jar
    

    Elastic Beanstalk默认会提供一个Nginx,然后默认端口是转发到5000。

    Procfile是可以写几行的,每一行的端口依次加100,比如第一个是5000,第二个就是5100。

    Elastic Beanstalk是支持直接选择免费使用套餐的,但是默认免费套餐用的t1,而不是t2可以自己改一下。

    当然,过了免费期的就随意了。…

  • AWS RDS无法访问的问题

    在AWS起了一个MariaDB的数据库,虽然设置了公开访问,但是不知道为什么总是连接不上。

    仔细检查一下才发现创建的时候一路Next,对于安全组规则选择了默认的一个,其中允许的IP不对,马上改一下,允许所有IP

    aws-group

  • 集中式认证服务

    CAS全称Central Authentication Service,中文名集中式认证服务。

    CAS是一种针对万维网的单点登录协议。它的目的是允许一个用户访问多个应用程序,而只需提供一次凭证(如用户名和密码)。它还允许web应用程序在没有获得用户的安全凭据(如密码)的情况下对用户进行身份验证。CAS即指协议,也指实现了该协议的软件包。

    CAS最早由Yale发起,目前有三个版本,即v1,v2,v3。

    相关定义

    Client

    终端用户或者是 WEB 浏览器

    Server

    统一认证服务所在的服务器

    Service

    终端用户或者 WEB 浏览器试图访问的应用

    Proxy

    作为代理的服务,用户通过该服务(代理)访问Back-end service(后端应用)

    Back-end service

    用户通过代理访问的应用,这个应用就被称为后端服务(Back-end service) 。它也被称作“target service”目标服务

    TGT

    Ticket Grangting Ticket 。TGT是CAS为用户签发的登录票据,拥有了TGT,用户就可以证明自己在CAS成功登录过。TGT封装了Cookie值以及此Cookie值对应的用户信息。当HTTP请求到来时,CAS以此Cookie值为key查询缓存中有无TGT ,如果有的话,则相信用户已登录过。

    ST

    Service Ticket 。ST是CAS为用户签发的访问某一service的票据。用户访问service时,service发现用户没有ST,则要求用户去CAS获取ST。用户向CAS发出获取ST的请求,CAS发现用户有TGT,则签发一个ST,返回给用户。用户拿着ST去访问service,service拿ST去CAS验证,验证通过后,允许用户

    TGC

    Ticket Grangting Cookies

  • Android和Intel HAXM的问题

    今天把本机的ionic升级到2,然后使用教程中的代码启动项目来测试一下环境。

    不知道出了什么问题,没有使用android启动了,报错为

    emulator: Requested console port 5584: Inferring adb port 5585.
    emulator: ERROR: x86_64 emulation currently requires hardware acceleration!
    Please ensure Intel HAXM is properly installed and usable.
    CPU acceleration status: HAXM must be updated (version 1.1.1 < 6.0.1).

    想想的确有印象装过一次,版本估计太老了。…

  • 自定义SpringBootCondition

    Spring Boot中一个很重要的特性就是自动配置,可以根据很多条件决定是否生成相应的bean或者其他操作。

    大部分情况下自动配置的条件是ConditionalOnMissingBean,也就是没有这个bean,那就用这个自动配置配置一个。

    有时候自动配置条件并不是那么直接,有时候还涉及到一些自己的逻辑,这个时候就可以自定义SpringBootCondition来处理复杂一些的情况。

    继承SpringBootCondition并将自己的逻辑实现在getMatchOutcome方法中。

    自定义的逻辑大部分有两种,第一种是自动配置针对一类情况,需要检测多个独立类的存在性,比如EmbeddedDatabaseCondition,就会自动检测所有可能的数据库驱动,包括H2,DERBY,HSQL

    @Override
    public ConditionOutcome getMatchOutcome( ConditionContext context,
    					 AnnotatedTypeMetadata metadata )
    {
    	if ( anyMatches( context, metadata, this.pooledCondition ) )
    	{
    		return(ConditionOutcome.noMatch( "supported DataSource class found" ) );
    	}
    	EmbeddedDatabaseType type = EmbeddedDatabaseConnection
    				    .get( context.getClassLoader() ).getType();