0%

前言

Json数据格式这两年发展的很快,其声称相对XML格式有很对好处:

  • 容易阅读;
  • 解析速度快;
  • 占用空间更少。

不过,JSON 和 XML两者纠结谁优谁劣,这里不做讨论,可以参见知乎上为什么XML这么笨重的数据结构仍在广泛应用?

最近在项目中,会有各种解析JSON文本的需求,使用第三方Jackson工具来解析时,又担心当增加会减少字段,会不会出现非预期的情况,因此,研究下jackson解析json数据格式的代码,很有需要。

Jackson使用工具类

通常,我们对json格式的数据,只会进行解析和封装两种,也就是json字符串--->java对象以及java对象---> json字符串

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
72
73
74
75
76
77
78
       
public class JsonUtils {
/**
* Logger for this class
*/
private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class);

private final static ObjectMapper objectMapper = new ObjectMapper();

static {
objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
objectMapper.configure(JsonParser.Feature.INTERN_FIELD_NAMES, true);
objectMapper.configure(JsonParser.Feature.CANONICALIZE_FIELD_NAMES, true);
objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}

private JsonUtils() {
}

public static String encode(Object obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonGenerationException e) {
logger.error("encode(Object)", e); //$NON-NLS-1$
} catch (JsonMappingException e) {
logger.error("encode(Object)", e); //$NON-NLS-1$
} catch (IOException e) {
logger.error("encode(Object)", e); //$NON-NLS-1$
}
return null;
}

/**
* 将json string反序列化成对象
*
* @param json
* @param valueType
* @return
*/
public static <T> T decode(String json, Class<T> valueType) {
try {
return objectMapper.readValue(json, valueType);
} catch (JsonParseException e) {
logger.error("decode(String, Class<T>)", e);
} catch (JsonMappingException e) {
logger.error("decode(String, Class<T>)", e);
} catch (IOException e) {
logger.error("decode(String, Class<T>)", e);
}
return null;
}

/**
* 将json array反序列化为对象
*
* @param json
* @param jsonTypeReference
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T decode(String json, TypeReference<T> typeReference) {
try {
return (T) objectMapper.readValue(json, typeReference);
} catch (JsonParseException e) {
logger.error("decode(String, JsonTypeReference<T>)", e);
} catch (JsonMappingException e) {
logger.error("decode(String, JsonTypeReference<T>)", e);
} catch (IOException e) {
logger.error("decode(String, JsonTypeReference<T>)", e);
}
return null;
}

}

Jackson配置属性

如果上面的工具类实例,在Jackson中存在一些属性配置,这些配置决定了最后在解析或者编码后数据视图。因此,在分析Jackson之前,先了解下,Jackson具有的一些配置含义。

阅读全文 »

前言

vim工具,对于一个程序猿来讲,是使用非常普遍的。以前在Ubuntu上安装ma6174大神提供的安装脚本,一键安装一些非常好用的插件,但是对于Mac来说,一直不能很好地执行一件安装。

这里,记录一下,使用大神提供的安装脚本出现问题的解决方法。

Vim一键安装脚本

ma6174大神提供的安装脚本,不能直接在Mac 上运行,直接copy到本地,脚本为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

#!/bin/bash

brew install vim ctags git astyle
sudo ARCHFLAGS=-Wno-error=unused-command-line-argument-hard-error-in-future easy_install twisted

sudo easy_install -ZU autopep8 twisted
sudo ln -s /usr/bin/ctags /usr/local/bin/ctags
mv -f ~/vim ~/vim_old
cd ~/ && git clone https://github.com/ma6174/vim.git
mv -f ~/.vim ~/.vim_old
mv -f ~/vim ~/.vim
mv -f ~/.vimrc ~/.vimrc_old
mv -f ~/.vim/.vimrc ~/
git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle
vim vim_mac -c "BundleInstall" -c "q" -c "q"
rm vim_mac
echo "安装完成"

Note:上面的脚本是直接从一键安装命令中的build脚本部分拷贝的,因为我的Mac无法直接执行一键安装命令。此外,Mac必须安装HomeBrew工具,关于该工具的安装使用,请参考 http://brew.sh/index_zh-cn.html

阅读全文 »

问题

在我们案例里,我们将实现一个数据模型和交互来支持Oauth v1.0a API。一般常常是基于MySQL或者其他的RDBMS实现,但是我们可以利用Redis的数据结构更高效的实现Oauth协议。

解决方法

我们不会去实现Oauth的API或者交互。这里我们仅仅感兴趣的是这种类型场景里所需要的数据。我们将在Redis里面存储五种类型的数据:

  • consumer keys
  • consumer secrets
  • request tokens
  • access tokens
  • nonces

所以我们的需求如下:通过一对keysecret标识的应用(客户)。这些客户根据他们的需求会有许多次的请求和访问token,并且每个用户/时间戳对是唯一的。

根据他们的要求和交互情况,这种类型的数据可以被存储在hashessetsstrings

讨论

初始设置

一开始,在客户发出一个请求之前,他们必须输入他们的数据。我们将这个数据和客户信息放入hash中。当他注册我们系统的时候,key是我们为特定的商户存储的数据之一:

阅读全文 »

问题

首先,你需要了解Redis的数据类型,这样才能够为特定的应用提供更好的Redis使用方式和性能。

解决方法

和大部分其他的NoSQL方案和key-value存储引擎不同,Redis包含一些内建的数据类型,允许开发者可以使用有意义的语义方式来构建他们的数据。在Redis内部操作指定类型的数据时,预定义的数据类型一般会比外部定义数据类型要操作更快。

讨论

在我们深入特定的数据类型之前,先来了解一些在设计Key数据结构的时候需要关注的事情:

  • 定义key空间时需要一致。由于一个key可以包含任意的字符,你可以使用分隔符去为自己的业务定义有意义的命名。例如: cache:project:319:tasks,每一个冒号就是一个命名分隔符。
  • 当定义自己的key时,尝试限制合适的大小。从存储中检索一个key是需要比较操作的,所以保证key长度足够的小是一个很好的建议。此外,更小的key长度还会节省内存的使用。
  • 即使key不能够特别的大,但是保持特别小的key并不会带来非常大的性能提升。这意味着,你设计自己的key时需要综合考虑key的易读性和正常的键长度。

因此,当键设计成c:p:319:t或者user 123是相当失败的,前面一个可读性很差,后面一个包含空格。另一方面,像cache:project:319:taskslastchatmessage464A1E96B2D217EBE87449FA8B70E6C7D112560Ckey都是很好的,因为他们都是有语义的词(最后一个是SHA1哈希值,虽然很难猜测他的语义,但是这对于存储了对应的对象,你就可以计算出hash值了)。

阅读全文 »

问题

许多的应用服务都需要存储关于使用,配置或者其他相关的信息的临时数据,这些数据结构并不适合存储在关系数据库中。
通常情况下,开发者会是MySQL或者其他RDBMS来存储这种数据。在这里,我们将使用Redis和它内建的数据结构,以一种更轻量级、更快速、更宽松的方式完成存储应用临时数据的功能。

解决方法

Redis本身的定位并不仅仅是key/value存储服务,同时也可以作为存储数据结构的服务器。这意味着,在传统的key/value存储功能之上,它还提供给你一些存储和操作应用数据的方式。
我们将使用这些数据结构和命令来存储应用示例数据:比如,我们在一些regular keys里面存储有用的计数器,在Redis hashes里面存储用户对象,以及使用sets实现朋友圈(像Google+)。

讨论

存储应用使用计数器

首先,让我们开始存储一些非常基础的事情:计数器。想象我们运营一个商业的社交网络,然后想要追踪profile/page的访问数据。我们可以在RDBMS的存储我们页数据的表里面增加一列,
但是希望我们的流量足够高以至于每次更新这一列会带来一些麻烦。因此,我们需要更快的工具来更新和查询,所以我们使用Redis来代替。

由于Redis命令的原子性,我们知道如果我们存储一个计数器的key,则我们可以使用命令,比如:INCR(或者INCRBY)和DECR(或者DECRBY),来增加增加或者减少它包含的值。所以,通过为我们的数据设计一个合适的命名保证我们的计数器单次操作成本微乎其微。

Redis系统内实际上并没有约定的方法来组织keys,但是许多人(包括作者)都喜欢使用冒号:来区分关键字从而创建keys,因此在这里也这样约定。为了存储我们的社交网络页面访问数据,我们可以有一个像visits:pageid:totals的命名,比如页面id为635,则命名为visits:635:totals。如果我们已经在一些地方存储访问数据,我们可以首先根据这些数据产生redis的keys,并且设置对应的值,比如:

    SET visits:1:totals 21389 
    SET visits:2:totals 1367894 
    (...)

当访问一个给定的页面,一个简单地INCR命令将更新Redis中的计数器:

    INCR visits:635:totals
    

然后我们可以获取任何页面在任何时候的访问次数,这只需要通过简单地GET命令:

    GET visits:635:totals
    

你也可以让你的命令更智能,比如你可以在人们查看页面的时候,显示当前该页面被访问的次数给他看。当然,你也可以计算他自己访问的次数,所以你甚至不需要执行最后的GET命令:你可以利用INCR命令返回值的特点,因为INCR命令会返回自增之后的计数值。一个简单地关于访问和计数器的伪代码如下所示:

    1. 访问者访问页面.
    2. 我们 INCR 相关页面的访问计数器 (比如:INCR visits:635:totals)        3. 我们获取INCR命令的返回值。
    4. 我们展示返回的值在用户页面上。

这种方式我们保证用户在查看页面的时候,常常可以看见实时计数值,以及他自己访问的计数–着所有都可以使用Redis命令。

阅读全文 »

前言

最近对于线上一些数据需要进行过滤导到本地来,或者对一些运营人员给的文本数据,需要在线上数据库跑出对应的结果出来,因此,需要通过一个脚本来执行。因为,现在服务器基本上会默认安装python,所以这里存一份脚本备用。

Python脚本

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

#!/usr/bin/python
#coding=utf-8
import os;
import MySQLdb;
import sys;
reload(sys)
sys.setdefaultencoding('utf-8')
file=open("hotelseq.txt")
outfile=open("customer.txt",'w+')
conn=MySQLdb.connect(host='127.0.0.1',user='root',passwd='123456',db='test',port=3306,charset="utf8")
cur=conn.cursor()
order_cur = conn.cursor()

while 1:
line=file.readline().strip()
print line
if not line:
break
count=cur.execute("select cus.customer_state,cus.name from crm_customer_hotel as hotel join crm_customer as cus on hotel.customer_serial_number=cus.serial_number where hotel.hotel_seq='%s'" % line)
result = cur.fetchone()
print result
if result:
outfile.write(str(result[0])+" "+result[1])
outfile.write('\n')
cur.close()
file.close()
outfile.close()


阅读全文 »

前言

Intelij IDEA一些快捷键和 Eclipse不同,所以对一些快捷键进行记录,备查。

Idea 快捷键

视图快捷键

1
2
3
4
5
6
7

快速查看方法注释文档 Ctrl + Q

快速查询类名 Ctrl + N

快速查询文件名 Ctrl + Shift + N

编辑快捷键

1
2
3
4
5

代码生成快捷键 Alt + Insert

自动跳转测试Test类 Alt + T

Sublime 快捷键

1
2
3
4
5
6
7
8
9
10
11

选择多行操作 Ctrl + Shift + L

选择单词操作,多次往下移 Ctrl + D

选择一行操作,重复选择下一行 Ctrl + L

注释当前行 Ctrl + /

从当前位置开始注释 Ctrl + Shift + /

阅读全文 »

说明:来自互联网,如有版权问题,请告知本人将其撤下。

来源:http://works.jinbuguo.com/linux/understand_package_install.html

前言

从源代码安装过软件的朋友一定对 ./configure && make && make install 安装三步曲非常熟悉了。然而究竟这个过程中的每一步幕后都发生了些什么呢?本文将带领你一探究竟。深入理解这个过程将有助于你在LFS的基础上玩出自己的花样来。不过需要说明的是本文对 Makefilemake 的讲解是相当近视和粗浅的,但是对于理解安装过程来说足够了。

概述

用一句话来解释这个过程就是:

根据源码包中 Makefile.in 文件的指示,configure 脚本检查当前的系统环境和配置选项,在当前目录中生成 Makefile 文件(还有其它本文无需关心的文件),然后 make 程序就按照当前目录中的 Makefile 文件的指示将源代码编译为二进制文件,最后将这些二进制文件移动(即安装)到指定的地方(仍然按照 Makefile 文件的指示)。

由此可见 Makefile 文件是幕后的核心。要深入理解安装过程,必须首先对 Makefile 文件有充分的了解。本文将首先讲述 Makefilemake ,然后再讲述 configure 脚本。并且在讲述这两部分内容时,提供了尽可能详细的、可以运用于实践的参考资料。

Makefile 与 make

用一句话来概括Makefilemake 的关系就是:

Makefile 包含了所有的规则和目标,而 make 则是为了完成目标而去解释 Makefiel 规则的工具。

阅读全文 »

前言

使用Ubuntu系统时,由于系统是默认安装的,所以机器名没有修改成一个合适的名字。在Ubuntu下通过命令sudo vim /etc/hostname来修改成自己想要的命令,然后注销用户,重新进入系统。

接着,就出现了一个很奇怪的问题,我的桌面上的chrome图标不能点击进入,一直都是无响应状态,但是其他浏览器,比如自带的Firefox就可以正常启动和使用。

Chrome启动失败解决方法

点击chrome图标不管用,并且看不到任何出错信息,无法定位问题出在哪里。只好,从终端使用google-chrome命令来启动chrome浏览器客户端了。于是,出现以下错误信息:

1
2
3
4
5
6
ketao@ketao-Latitude:~$ google-chrome

[5901:5901:0610/183033:ERROR:process_singleton_linux.cc(309)] 其他计算机 (ketao-Latitude-E5430-non-vPro) 的另一个 Google Chrome 进程 (7578) 好像正在使用此个人资料。Chrome 已锁定此个人资料以防止其受损。如果您确定其他进程目前未使用此个人资料,请为其解锁并重新启动 Chrome。

[5901:5901:0610/183033:ERROR:simple_message_box_views.cc(208)] Unable to show a dialog outside the UI thread message loop: Google Chrome - 其他计算机 (ketao-Latitude-E5430-non-vPro) 的另一个 Google Chrome 进程 (7578) 好像正在使用此个人资料。Chrome 已锁定此个人资料以防止其受损。如果您确定其他进程目前未使用此个人资料,请为其解锁并重新启动 Chrome。

阅读全文 »

前言

最近,系统从 windows切换到Ubuntu,一些开发软件需要重新安装和配置。但是,众所周知,windows上的开发软件客户端比ubuntu等linux系系统使用要便捷和傻瓜得多,所以切换到ubuntu有很多软件需要安装,但是这些软件需要进行代码编译,就在这里记录下。

subversion安装和配置

一般,如果对subversion的版本不限制,那些直接使用sudo apt-get install subversion命令就可以安装来,但是如果对版本有要求,比如由于svn的1.8版本在很多svn服务器端不被支持,所以需要安装低于1.8的svn客户端。这就需要我们在本地编译完了之后再安装。

2.1 subversion源码下载

点击进入下载页面:http://subversion.apache.org/download/#supported-releases , 选择当前最新的1.7的子版本下载;

或者,也可以直接在终端使用命令:wget http://apache.fayea.com/apache-mirror/subversion/subversion-1.7.17.tar.gz下载。

2.2 subversion 源码编译准备

Linux编译安装subversion需要事先准备很多的工作,安装很多相关的工具包,否则代码无法编译通过。因此,在安装 subversion之前,需要先做一些准备工作。

阅读全文 »