网页加载进度条


2017-08-25 10:01
zpq
57

Here’s an emerging UI pattern: a web page loading bar. Unsatisfied with progress indicators provided by the browser, some sites are implementing their own ones to show the load status of the next page. The progress bar appears as a thin line overlaying the content, sitting right underneath the browser toolbar, growing in width across the page as the next one loads.

Here is a screenshot of the bar on Medium (the thin green line highlighted at the top):

151505803345769.jpeg
And here is a very similar implementation on YouTube, red this time, with a subtle glow effect:

Tess4J OCR使用教程


2017-07-26 07:25
zpq
125

介绍

Tesseract-OCR支持中文识别,并且开源和提供全套的训练工具,是快速低成本开发的首选。而Tess4J则是Tesseract在Java PC上的应用。在英文和数字识别中性能还是不错的,但是在中文识别中,无论速度还是识别率还是较弱,建议有条件的话,针对场景进行训练,会获得较好结果,本文仅对目前Tess4J的用法进行介绍。

教程

  1. Tess4J官网下载源码包
    官网下载

  2. 创建Java项目并配置

网上不少文章会提到DLL,其实在最新的版本,如果源码包里面有dist路径,则只需要配置该jar包和lib中相关的jar即可。
注意点1:将dist/tess4j-3.4.0.jar 及 lib/*.jar加入项目
注意点2:tessdata一定要配置到根目录,否则需要在代码中指定dataPath

  1. 创建一个main
public static void main(String[] args) throws TesseractException {
        ITesseract instance = new Tesseract();
        //如果未将tessdata放在根目录下需要指定绝对路径
        //instance.setDatapath("the absolute path of tessdata");
        // 我们需要指定识别语种
        instance.setLanguage("chi_sim");
        // 指定识别图片
        File imgDir = new File("test_chinese_07.PNG");
        long startTime = System.currentTimeMillis();
        String ocrResult = instance.doOCR(imgDir);
        // 输出识别结果
        System.out.println("OCR Result: \n" + ocrResult + "\n 耗时:" + (System.currentTimeMillis() - startTime) + "ms");
    }
  1. 注意三处:
  • tessdata放在与src同级的根目录下,否则需要指定dataPath
  • 如果需要识别英文之外的语种,需要指定识别语种。
  • 其他语种下载地址:其他语种下载地址

微信支付宝支付注意事项


2017-07-09 03:07
zpq
95

微信支付

Q 商品名称为中文时返回签名失败
A 在签名是需要将字符串转成ISO8859-1格式

//DigestUtils 是第三方commons-codec库
String sign = DigestUtils.md5Hex(signstr.toString().getBytes("ISO8859-1")).toUpperCase();

Q 创建完订单进行扫码支付时,中文商品名称显示乱码
A 微信中用的编码是ISO8859-1 所以需要将字符串转为ISO8859-1格式

String body = new String (goodname.getBytes("UTF-8"),"ISO-8859-1")

Q 如何获取微信成功支付的回调内容
A 回调的内容是xml字符串,我们需要手动解析

// HttpServletRequest request #spring boot 
BufferedReader reader = request.getReader();
StringBuffer inputString = new StringBuffer();
String line ;
while (( line = reader.readLine()) != null) {
	inputString.append(line);
}
String xmlstr = inputString.toString();

支付宝支付

Q 如何正确的签名
A 支付宝签名要比微信的容易的多,而且出错概率较低,签名方式分为RSARSA2,两种方式分别都需要商户自己生成 公钥和私钥,长度必须是2048 私钥保存在本地,公钥需要上传到 商户中心 -- 开发者中心,上传时需要去掉头尾部字符串,并且去掉换行,上传时请分清楚打算用哪个加密,别RSA加密,却上传到RSA2上面.

Q 进行扫码支付时,商品中文是乱码
A 注意提交的参数charset是什么格式,如格式正确,在请求订单是header 部分需要声明字符编码

HttpPost post = new HttpPost(url);
httpPost.setHeader("Content-Type","application/x-www-form-urlencoded");
httpPost.setEntity( new UrlEncodedFormEntity(dataList,"GBK"));

Q 支付成功回调
A 支付宝默认开通 TRADE_SUCCESSWAIT_BUYER_PAY 支付通知,TRADE_CLOSEDTRADE_FINISHED 需要申请开通,回调的内容数据也很好的获取.

// HttpServletRequest request
request.getParameter()

Q 商品名称英文时签名成功,中文时签名失败
A 该问题应该是提交数据时格式编码有误,小伙伴试试这样。在签名时,把签名的字符串转成GBK编码,form 提交时 也用GBK提交
支付宝 判断字符编码格式主要依据于头部Content-Type属性 如"Content-Type :application/x-www-form-urlencoded;charset=utf-8那么字符编码就是utf-8跟公共参数里的charset没有什么关系,这里推荐使用Okhttp包。
微信则需要把中文字符串转成ISO-8859-1编码,然后再进行签名。

如何正确的使用Google Cloud 计算引擎


2017-06-20 02:34
zpq
290

必备条件

  1. 能翻墙
  2. 需要一张外币信用卡 类似VISA
  3. Google账户

注册Google账户登录进去,然后绑定 VISA 卡 绑定的时候会收取1美元验证银行卡 只要验证通过后会退还。

进入 Google Cloud 菜单栏 -> 结算 -> 概览

如果是第一次使用会赠送300美元 有效期一年

laravel 5.4 redis 报错 'Predis\Response\ServerException' with message 'ERR unknown command 'EVAL''


2017-06-15 09:33
zpq
861

在laravel 5.2 迁移到 5.4 出现错误

这个错误不是框架错误 是 redis 版本 过低导致的 !!

redis eval 命令必须在版本 >= 2.6.0

之前安装redis的时候是用yum命令安装的。

安装的版本是2.4.10 找不到高版本的yum安装方式

没办法只能编译安装

编译安装官网也有,这里顺便也复制下来

wget http://download.redis.io/releases/redis-3.2.9.tar.gz
tar xzf redis-3.2.9.tar.gz
cd redis-3.2.9
make
src/redis-server
src/redis-cli

redis 默认是前台运行的 后台运行需要修改配置文件redis.conf
大约在 128 行

# By default Redis does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
daemonize no

no 改成 yes 保存 然后执行命令

./redis-server [/path/to/redis.conf]

laravel 5.4 报错SQLSTATE[42000] Syntax error or access violation 1055 'xxx' isn't in GROUP BY


2017-06-09 04:30
zpq
182

查询mysql 1055错误码发现问题为在mysql的配置中如果设置了sql_mode包含ONLY_FULL_GROUP_BY值得话,在进行查询时需要将select的字段都包含在group by 中。
即 select x,y from xxx group by x,y
否则就会报错

但是查看自己的配置my.cnf发现在sql_mode中并没有ONLY_FULL_GROUP_BY这个值

然后去查看Laravel的配置文件,config/database.php,查找mysql的配置,

'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', 'localhost'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => env('DB_PREFIX',''),
            'strict' => true,
            'engine' => null,
        ],

发现有个strict项,默认为true,上网也没有查找到相关解释,根据字面意思猜测可能为是否开启严格模式,将其修改为false,再次测试发现问题解决,可以输出正确结果
源代码解释
vendor\laravel\framework\src\Illuminate\Database\Connectors\MySqlConnector.php 约144行

protected function setModes(PDO $connection, array $config)
    {
        if (isset($config['modes'])) {
            $this->setCustomModes($connection, $config);
        } elseif (isset($config['strict'])) {
            if ($config['strict']) {		//这边有个判断如果是true则执行strictMode()方法所以要改为false
                $connection->prepare($this->strictMode())->execute();
            } else {
                $connection->prepare("set session sql_mode='NO_ENGINE_SUBSTITUTION'")->execute();
            }
        }
    }
protected function strictMode()
    {
        return "set session sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'";
    }

也可以编辑 /etc/my.cnf 文件
在**[mysqld]**追加

~~```
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"


~~重启mysql即可。~~

关闭X-Powered-By 信息(隐藏PHP版本信息)


2017-06-02 06:28
zpq
93


会暴露服务器运行的是php

修改 php.ini 文件 设置 expose_php = Off

官方给出的说明

Decides whether PHP may expose the fact that it is installed on the server
(e.g. by adding its signature to the Web server header). It is no security
threat in any way, but it makes it possible to determine whether you use PHP
on your server or not.

决定服务器上是否暴露安装有PHP,
(例如:把这些信息加到Web服务器头响应)。这是不安全的。
但能确定你的服务器时候运行着PHP。
意思就是打开的话可以告诉其他人这台服务器可以运行PHP,但不一定安全,可以关掉

微信支付报错“支付签名验证失败”


2017-06-01 14:06
zpq
147

微信支付有几个地方需要注意的

  • sign 签名时需要在末尾增加key参数 key 参数在商户后台进行设置 sign签名验证
  • wx.config 签名验证工具 url 参数必须是当前js运行所在的url(包括参数) 如果签名失败可能跟支付的授权目录有关
  • 微信创建统一订单时返回的数据格式中只有prepay_id参数有用,其他返回的参数无用
  • wx.chooseWXpay 在调起微信支付时需要二次签名(sign签名),其中有个地方需要注意(巨坑)。具体二次签名如下
$appid = 'appid';              //appid
$randstr = '123123213213';     //随机字符串
$time = '123456789';           //时间戳
$key = 'keyyyyyyyy';           //商户后台设置的key
$prepayid = 'wx2017060115493564b5a926a10145685802';//假设统一订单返回的prepayid
$prepayid = 'prepay_id='.$prepayid;//这里要组装(我是坑)
        $signstr = "appId={$appid}&nonceStr={$randstr}&package={$prepayid}&signType=MD5&timeStamp={$time}&key={$key}";
//生成需要签名的字符串为
//appId=appid&nonceStr=123123213213&package=prepay_id=wx2017060115493564b5a926a10145685802&signType=MD5&timeStamp=123456789&key=keyyyyyyyy";
$paysign = strtoupper(md5($signstr));
//data 为返回为前台数据
$data = [
    'nonceStr' => $randstr,
    'timestamp' => $time,
    'signType' => 'MD5',
    'paySign' => $paysign,
    'package' => $prepayid,
];
  • wx.chooseWXpay 中有个参数timestamp 不是timeStamp 需要签名的时间戳都是timeStamp js里的都是小写的。

laravel 生成 sitemap


2017-05-03 14:41
zpq
153

什么是 Sitemap?

Sitemap 可方便管理员通知搜索引擎他们网站上有哪些可供抓取的网页。最简单的 Sitepmap 形式,就是 XML 文件,在其中列出网站中的网址以及关于每个网址的其他元数据(上次更新的时间、更改的频率以及相对于网站上其他网址的重要程度为何等),以便搜索引擎可以更加智能地抓取网站。
网络抓取工具通常会通过网站内部和其他网站上的链接查找网页。Sitemap 会提供此数据以便允许支持 Sitemap 的抓取工具抓取 Sitemap 提供的所有网址,并了解使用相关元数据的网址。使用 Sitemap 协议并不能保证网页会包含在搜索引擎中,但可向网络抓取工具提供一些提示以便它们更有效地抓取网站。

Sitemaps XML 格式

本文件说明 Sitemap 通讯协定的 XML 配置。
Sitemap 通讯协定格式是由 XML 标记所组成。Sitemap 中的所有资料值都必须是实体逸出。档案本身必须使用 UTF-8 编码。
Sitemap 必须:

  • 以起始 标记做为开头,并以结束 标记做为结尾。
  • 指定 内的名称领域 (通讯协定标准)。
  • 让每个 URL 中包含一个 项目做为母层 XML 标记。
  • 在每个 母层标记包含一个 子层项目。

其他所有标记均为选用的。是否支援这些选用的标记须视搜寻引擎而定。详细资讯请参阅各搜寻引擎的说明文件。
另外,Sitemap 中所有的 URL 必须来自单一主机,例如 www.example.com 或 store.example.com。

XML Sitemap 范例

下列范例显示仅包含一个 URL 并使用所有选用标记的 Sitemap。选用标记以斜体表示。

SpringMVC请求乱码解决方案


2017-04-21 09:27
zpq
24

先在web.xml设置字符编码utf-8

<filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

如果无法解决接收参数乱码

设置Tomcat配置 URIEconding="UTF-8"
编辑文件 /conf/server.xml

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="UTF-8" />

chrome滚动条样式修改


2017-04-20 01:40
zpq
236

对于chrome浏览器,它提供了修改滚动条样式的接口,开发者只需要加上几句css脚本,就可轻松实现滚动条样式的修改.

先说一下滚动条的参数:

::-webkit-scrollbar 滚动条整体部分,可以设置宽度啥的
::-webkit-scrollbar-button 滚动条两端的按钮
::-webkit-scrollbar-track  外层轨道
::-webkit-scrollbar-track-piece  内层滚动槽
::-webkit-scrollbar-thumb 滚动的滑块
::-webkit-scrollbar-corner 边角
::-webkit-resizer 定义右下角拖动块的样式
/* 设置滚动条的样式 */
::-webkit-scrollbar {
    width: 10px;
}
/* 滚动槽 */
::-webkit-scrollbar-track {
    -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
    border-radius: 10px;
}
/* 滚动条滑块 */
::-webkit-scrollbar-thumb {
    border-radius: 10px;
    background: #bbb;
    -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
}
::-webkit-scrollbar-thumb:window-inactive {
    background: rgba(255,0,0,0.4);
}

CSS 鼠标手指样式整理


2017-04-19 12:15
zpq
47

通过设置style属性来控制鼠标指针样式

style="cursor:*"
<a href="#" style="cursor:pointer">CSS鼠标手型效果</a>
<a href="#" style="cursor:crosshair">CSS鼠标十字型 效果</a>
<a href="#" style="cursor:help">CSS鼠标问号效果</a>
text		是移动到文本上的那种效果
wait		是等待的那种效果
default	 是默认效果
e-resize	是向右的箭头
ne-resize	是向右上的箭头
n-resize	是向上的箭头
nw-resize	是向左上的箭头
w-resize	是向左的箭头
sw-resize	是左下的箭头
s-resize	是向下的箭头
se-resize	是向右下的箭头
auto		是由系统自动给出效果

默认端口对应服务


2017-04-11 07:02
zpq
1387

计算机之间依照互联网传输层TCP/IP协议不同的协议通信,都有不同的对应端口。所以,利用短信(datagram)的UDP,所采用的端口号码不一定和采用TCP的端口号码一样。以下为两种通信协议的端口列表链接:

[TOC]

端口状态颜色图例

使用状态叙述颜色
官方应用与端口组合记录在IANA的端口分配列表中
非官方应用与端口组合不在IANA的端口分配列表中
多重使用已知多个应用程序使用这个port

自己搭建一个动态域名服务DDNS


2017-03-31 03:21
zpq
761

DDNS

DDNS(Dynamic Domain Name Server)是动态域名服务的缩写。

DDNS是将用户的动态IP地址映射到一个固定的域名解析服务上,用户每次连接网络的时候客户端程序就会通过信息传递把该主机的动态IP地址传送给位于服务商主机上的服务器程序,服务器程序负责提供DNS服务并实现动态域名解析。

需求对象

家庭/公司内部服务需要对外公开,但却没有固定IP的用户。

服务搭建条件

  1. 有自己的域名
  2. 有操作域名SDK(这里我用的是阿里云的万网)
  3. 内部服务器(不经常关机就行)
  4. 开发能力

服务运行流程