Solo  当前访客:4 登录 注册

喧哗博客-http://blog.xuahua.com

繁华过后的沉寂--技术经验分享
浏览次数: 94,390    文章总数: 91    评论总数: 3

SVN update cache 有更新!

SVN update cache

当打开这个页面的时候,肯定很烦恼吧,,,每次保存,eclipse 右下角总是会出现 svn update cache。

想要干掉他,请按以下操作

1. 右键  TortiosSVN --> setting  点开

2,选中 Icon Overlays ,右侧  status cache 选择 none 

再想优化下

Exclude Paths 选择所有盘符加入,一行一个;如  c:\

Include Paths 选择源码目录加入 如: d:\source\*

 

 

微信接口开发系列之五微信支付服务器接收通知 有更新!

微信服务器 异步通知服务器接收通知

1,业务防止多次重复;

2,以此通知到账为准,实现到账业务逻辑实现。

注意事项:

 微信服务器 通知消息,以流形式接收消息;

  校验消息;

  解析消息按状态,实现对应业务处理。

接收消息关键代码:

response.setCharacterEncoding("utf-8");
			request.setCharacterEncoding("utf-8");
			//response.setContentType("text/xml");
			pw = response.getWriter();
			InputStream in = request.getInputStream();
			BufferedInputStream bis = new BufferedInputStream(in);
			byte[] bytes = new byte[2048];
			int len = -1;
			StringBuilder sb = new StringBuilder();
			while ((len = bis.read(bytes)) != -1) {
				sb.append(new String(bytes, 0, len));
			}
			bis.close();
			String result = sb.toString();


解析消息关键代码:

    

 Document doc = null;		
try {
			// 读取并解析XML文档
			// SAXReader就是一个管道,用一个流的方式,把xml文件读出来
			// SAXReader reader = new SAXReader(); //aa.xml表示你要解析的xml文档
			// Document document = reader.read(new File("aa.xml"));
			// 下面的是通过解析xml字符串的
			doc = DocumentHelper.parseText(xmlstring); // 将字符串转为XML
			Element root = doc.getRootElement(); // 获取根节点
			if(root.element("result_code")!=null){
				vo.setResult_code(trims(root.elementTextTrim("result_code")));
			}
}catch(Exception e){
 
}

微信接口开发系列之四模版消息

发送模版消息,必须从模版库取得匹配的模版template_id并模版内容以及发送给谁的openid

在开发环境中,可在 测试号管理 -- 测试号二维码 扫码添加测试微信号,并在右侧可见 此微信号即测试开发中的openid。此处openid仅用于测试与生产不同。

测试例子

 状态更新提醒模版  template_id => zdcmSDVbJ9SQvUVLeAeWF9XsoWBvE29QR42Tx9gcSaE

模版内容 

{{first.DATA}}
状态来源:{{keyword1.DATA}}
处理进度:{{keyword2.DATA}}
提交时间:{{keyword3.DATA}}
{{remark.DATA}}

代码实现如下

	/**
	 * 状态更新提醒  zdcmSDVbJ9SQvUVLeAeWF9XsoWBvE29QR42Tx9gcSaE

{{first.DATA}}
状态来源:{{keyword1.DATA}}
处理进度:{{keyword2.DATA}}
提交时间:{{keyword3.DATA}}
{{remark.DATA}}
	 */
	public static Map<String,Object> notifyEventChange(String openid,String templateid,String url,String title,String key1,String key2,String key3,String remark){
		Map<String,Object> data =  new HashMap<String,Object>();
		data.put("touser",openid);
		if(StringUtils.isBlank(templateid)){
			templateid = "zdcmSDVbJ9SQvUVLeAeWF9XsoWBvE29QR42Tx9gcSaE";
		}
		data.put("template_id",templateid);
		data.put("url",url);

		Map<String,Object> datasub  = new HashMap<String,Object>();
		
		Map<String,String> firstmap = new HashMap<String,String>();
		firstmap.put("value",title);
		 
		firstmap.put("color","#173177");
		datasub.put("first", JSON.toJSON(firstmap));
		
		Map<String,String> ordermap = new HashMap<String,String>();
		ordermap.put("value",key1);
		ordermap.put("color","#173177");
		datasub.put("keyword1", JSON.toJSON(ordermap));
		
		Map<String,String> statusmap = new HashMap<String,String>();
		statusmap.put("value",key2);
		statusmap.put("color","#173177");
		datasub.put("keyword2", JSON.toJSON(statusmap));
		
		Map<String,String> key3map = new HashMap<String,String>();
		key3map.put("value",key3);
		key3map.put("color","#173177");
		datasub.put("keyword3", JSON.toJSON(key3map));
		
		Map<String,String> remarkmap = new HashMap<String,String>();
		remarkmap.put("value",remark);
		remarkmap.put("color","#173177");
		
		datasub.put("remark",JSON.toJSON(remarkmap));
		data.put("data",JSON.toJSON(datasub));
		return data;
	} 

 

微信接口开发系列之三获取用户信息

关键信息: 微信服务器返回的微信公众号  有效7200秒的access_token 凭据

在有效的时间内,根据access_token,用户openid,获取用户授权的用户信息

关键代码:

// 获取微信用户信息
	public String getUserinfoByTokenOpenid(String accesstoken, String openid) {
		String url = PropertiesUtil.getValue("wx.userinfo");
		// String url =
		// "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
		url = url.replace("ACCESS_TOKEN", accesstoken);
		url = url.replace("OPENID", openid);
		String result = "";
		try {
			// 定义HttpClient
			HttpClient client = new HttpClient();
			// 实例化HTTP方法
			GetMethod request = new GetMethod(url);
			// 定义访问地址的链接状态
			int statusCode = client.executeMethod(request);
			// 客户端请求url数据
			// 请求成功状态-200
			if (statusCode == HttpStatus.SC_OK) {
				// 解决微信用户信息返回乱码的问题
				result = new String(request.getResponseBody(), "utf-8");
			} else {
				log.info("请求返回状态:" + statusCode);
			}
			if (log.isInfoEnabled()) {
				log.info("获取微信用户信息---------" + result);
			}
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}

微信接口开发系列之一配置 有更新!

本题主要从技术实现来讲讲微信开发。

微信开发之前,必须先申请微信订阅号/服务号/企业号,不管哪种类型都是微信针对不同专业,领域做的区分,在某些功能上有所限制。

一般在开发之前,都是开发模式,所以在获得了微信号之后,先申请微信测试号进行测试。

第一步:进入公众平台,在左侧菜单栏找到 开发 -- 开发者工具 在右侧选择 公众平台测试帐号 进入

第二步:在 测试号信息 可以看到 appID  和 appsecret 此为后续接口开发重要账号与密钥。

第三步:在 接口配置信息 中,填写以后需要对接微信入口校验以及接收消息接口的url访问地址以及校验参数token。

第四步: 设完配置信息以后,需要在服务器建立一个应用,并对外暴露一个网址即在第三步中填写的访问地址。本人对外的地址为 http://xxx.com/wx/index

主要用于微信服务器校验,接收微信消息通知。

校验主要参数四个: 

signature,timestamp,nonce,echostr
微信消息通知则是需要通过流的接收方式,代码如下


 

public class XMLUtil {
	
	public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
		Map<String, String> map = new HashMap<String, String>();
		InputStream inputStream = request.getInputStream();
		SAXReader reader = new SAXReader();
		Document document = reader.read(inputStream);
		Element root = document.getRootElement();
		List<Element> elementList = root.elements();
		for (Element e : elementList)
			map.put(e.getName(), e.getTextTrim());
		inputStream.close();
		inputStream = null;
		return map;
	}

 下面为完整的具体接口关键代码:

/**
 * 
 * 类名称:WeixinController.java 类描述: 微信公共平台开发
 * 
 * @author wyong 
 *  联系方式:343886028
 *  创建时间:2016年1月10日
 * @version 1.0
 */
@Controller
@RequestMapping("/wx")
public class WeixinController extends BaseAction {
	Logger logger = Logger.getLogger(getClass());

	
	@Autowired
	MsgService msgService;
	/**
	 * 微信接口总入口
	 * @param out
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping(value = "/index")
	public void index(@RequestParam(value = "signature", defaultValue = "") String signature, @RequestParam(value = "timestamp", defaultValue = "") String timestamp,
			@RequestParam(value = "nonce", defaultValue = "") String nonce, @RequestParam(value = "echostr", defaultValue = "") String echostr, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

			if (logger.isInfoEnabled()) {
				logger.info("signature=" + signature + "|timestamp=" + timestamp + "|nonce=" + nonce + "|echostr=" + echostr);
			}
			 
			PrintWriter out = response.getWriter();
			if (StringUtils.isNotBlank(signature) && StringUtils.isNotBlank(timestamp) &&StringUtils.isNotBlank(nonce)&& StringUtils.isNotBlank(echostr)) {/* 接口验证 */
				logger.info("========进入身份验证");
				List<String> list = new ArrayList<String>(3) {
					private static final long serialVersionUID = 2621444383666420433L;
					
					public String toString() { // 重写toString方法,得到三个参数的拼接字符串
						return this.get(0) + this.get(1) + this.get(2);
					}
				};
				list.add(PropertiesUtil.getValue("wx.WEIXIN")); // 读取Token(令牌)
				list.add(timestamp);
				list.add(nonce);
				Collections.sort(list); // 排序
				String tmpStr = new MySecurity().encode(list.toString(), MySecurity.SHA_1); // SHA-1加密
				if (signature.equals(tmpStr)) {
					out.write(echostr); // 请求验证成功,返回随机码
				} else {
					out.write("");
				}
				out.flush();
				out.close();
			} else {/* 消息处理 */
				System.out.println("========进入消息处理");
				Map<String, String> requestMap = XMLUtil.parseXml(request);
				log.error("====="+JSON.toJSON(requestMap));
				//事件推送,是否是发送消息后的事件推送。
				if(requestMap!=null && requestMap.get("MsgType")!=null && "event".equalsIgnoreCase(requestMap.get("MsgType"))){
					String msgid  = requestMap.get("MsgID");
					if(StringUtils.isNotBlank(msgid)){
						TMemNotify notify = msgService.findNotify(msgid);
						if(notify!=null){
							notify.setUpdatetime(new Date());
							notify.setReturnmsg(requestMap.get("Status"));
							msgService.updateObj(notify);
						}
					}
				}
				response.reset();
				log.error(JSON.toJSON(requestMap));
			}
	}

 

   

 

微信接口开发系列之二授权

授权  微信公众号用户显式授权

原理      用户关注公众号 或进入指定地址,前端JS-SDK 调用微信授权接口,用户显示确认授权后,微信会给予一个授权码code,通过授权码code 可以去微信服务器获取一个有效时长为7200秒的access-token;

此token具有很重要作用,且获取频率做了日限制100000次/天;测试号则只有2000次/天。

前端授权获取代码略。

服务器代码关键如下:

/**
	 * @param code
	 * @return 根据网页授权code 获取 openid,网页授权的access_token
	 */
	public String getUrlTokenBycode(String code) {
		// String url =
		// "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
		String url = PropertiesUtil.getValue("wx.accessTokenCode");

		// 微信正式公众号
		url = url.replace("APPID", PropertiesUtil.getValue("wx.appid"));
		url = url.replace("SECRET", PropertiesUtil.getValue("wx.appsecret"));
		url = url.replace("CODE", code);

		// 微信公众测试号
		// url = url.replace("APPID", "wxd39f718d218f90a1");
		// url = url.replace("SECRET", "71f7001a9c38fe13e5bb96bd8283f463");
		// url = url.replace("CODE", code);
		String result = "";
		try {
			result = Posturl.getRequest(url);
			if (log.isInfoEnabled()) {
				log.info("根据网页授权code,获取openid,网页授权access_token:---------" + result);
			}
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}

 

spring--secrutiy--控制到按钮 有更新!

使用spring security taglib: 
Java代码 
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %> 
... 
<security:authorize ifAnyGranted="ROLE_ADMIN"> 
<a href="user/input/id/${nuId}.html">编辑</a> 
</security:authorize>

一个查询SQL的优化-mysql

1,查询MYSQL

select max(createtime)
from t_mem_login_log
where id<(
SELECT MAX(id)
FROM t_mem_login_log
WHERE userid= 74
and flag= 1)
and userid= 74
and flag= 1

查询目的,查询当前用户当前登录的前一条最大的创建时间。比如

1 2 3 4 5 分别代表五条记录,5 为最大即最后一条插入数据,此时,需要取出比5小的最大记录4 。

 优化后的sql改写为

SELECT createtime
FROM `t_mem_login_log`
where userid= 74
and flag= 1
order by createtime desc
limit 1,1;

Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation '='

环境:mysql 数据库

字符集 utf8

建表sql

CREATE TABLE products (
    productID INT UNSIGNED NOT NULL AUTO_INCREMENT,
    title VARCHAR(104) NOT NULL,
    picturePath VARCHAR(104) NULL,
    pictureThumb VARCHAR(104) NULL,
    creationDate DATE NOT NULL,
    closeDate DATE NULL,
    deleteDate DATE NULL,
    varPath VARCHAR(104) NULL,
    isPublic TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
    PRIMARY KEY (productID)
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci;

现象,运行二表关联查询,报出异常错误如下

Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation '='

 

经过网上查找,解决方法。

ALTER TABLE products CHARACTER SET utf8 COLLATE utf8_general_ci;

以此为记 。。。

 

centos+编译安装+php5.6+php5.6源码环境 有更新!

一,安装前提

 

因为本人做java开发,对php环境配置不太懂,虽然网上也有yum 安装方式,但其中的配置关系完全不知。

而且因为本身已经在安装好的mysql数据库基础上再装php环境,会导致安装二套mysql,而出现问题(本人折腾快一天时间的体会)。

所以还是使用源码编译安装,过程需要花费不少,而且需要安装不少的插件。

 

二,安装php5.6

 链接 http://blog.xuahua.com/articles/2016/05/09/1462762124848.html 

2.1 安装php前的准备工作

   php 安装目录指定 /usr/local/php

  httpd 安装目录  /usr/local/httpd

  mysql 安装目录 /data/mysql

  mysql.sock 目录是通过mysql配置中指定生成在 /tmp/mysql.sock

 

2.2 源码下载 

源码下载目录 /data/soft
wget http://cn2.php.net/distributions/php-5.6.21.tar.gz

其他需要的插件下载,网上虽然也有,但是有些链接已经失效,下不到,我也是折腾好久才找到。
 
 
 

3,安装编译工具及库文件(使用yum命令安装)

yum install-y apr*autoconf automake bison bzip2 bzip2*cloog-ppl compat*cpp
yum install-y curl curl-devel fontconfig fontconfig-devel freetype freetype*
yum install-y freetype-devel gcc gcc-c++gtk+-devel gd gettext gettext-devel
yum install-y glibc kernel kernel-headers keyutils keyutils-libs-devel krb5-devel
yum install-y libcom_err-devel libpng libpng*libpng-devel libjpeg*libsepol-devel
yum install-y libselinux-devel libstdc++-devel libtool*libgomp libxml2 libxml2-devel libXpm*libX*
yum install-y libtiff libtiff*makempfr ncurses*ntp openssl nasm nasm*
yum install-y openssl-devel patchpcre-devel perl php-common php-gd
yum install-y policycoreutils ppl telnet t1lib t1lib*wget zlib-devel
 

三. 开始安装

1、安装yasm

1
2
3
4
5
6
7
8
9
cd/home
 
tar zxvf yasm-1.3.0.tar.gz
 
cdyasm-1.3.0
 
./configure
 
make&&makeinstall

 

2、安装libmcrypt

1
2
3
4
5
6
7
8
9
cd/home
 
tar zxvf libmcrypt-2.5.8.tar.gz
 
cdlibmcrypt-2.5.8
 
./configure
 
make&&makeinstall

 

3、安装libvpx

1
2
3
4
5
6
7
8
9
10
cd/home
 
xz-dlibvpx-v1.3.0.tar.xz
tar-xvf libvpx-v1.3.0.tar
 
cdlibvpx-v1.3.0
 
./configure--prefix=/usr/local/libvpx--enable-shared--enable-vp9
 
make&&makeinstall

 

4、安装tiff

1
2
3
4
5
6
7
8
9
cd/home
 
tar zxvf tiff-4.0.3.tar.gz
 
cdtiff-4.0.3
 
./configure--prefix=/usr/local/tiff--enable-shared
 
make&&makeinstall

 

5、安装libpng

1
2
3
4
5
6
7
8
9
10
11
cd/home
 
xz-dlibpng-1.6.16.tar.xz
 
tar-xvf libpng-1.6.16.tar
 
cdlibpng-1.6.16
 
./configure--prefix=/usr/local/libpng--enable-shared
 
make&&makeinstall

 

6、安装freetype

1
2
3
4
5
6
7
8
9
cd/home
 
tar zxvf freetype-2.5.4.tar.gz
 
cdfreetype-2.5.4
 
./configure--prefix=/usr/local/freetype--enable-shared--without-png
 
make&&makeinstall

 

7、安装jpeg

1
2
3
4
5
6
7
8
9
cd/home
 
tar zxvf jpegsrc.v9a.tar.gz
 
cdjpeg-9a
 
./configure--prefix=/usr/local/jpeg--enable-shared
 
make&&makeinstall

 

8、安装libgd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cd/home
 
tar zxvf libgd-2.1.0.tar.gz
 
cdlibgd-2.1.0
 
./configure\
--prefix=/usr/local/libgd\
--enable-shared\
--with-jpeg=/usr/local/jpeg\
--with-png=/usr/local/libpng\
--with-freetype=/usr/local/freetype\
--with-fontconfig=/usr/local/freetype\
--with-xpm=/usr/\
--with-tiff=/usr/local/tiff\
--with-vpx=/usr/local/libvpx
 
make&&makeinstall

 

9、安装t1lib

1
2
3
4
5
6
7
8
9
10
11
cd/home
 
tar zxvf t1lib-5.1.2.tar.gz
 
cdt1lib-5.1.2
 
./configure--prefix=/usr/local/t1lib--enable-shared
 
makewithout_doc
 
makeinstall

 

10、安装php

注意:如果系统是64位,请执行以下两条命令,否则安装php会出错(32位系统不需要执行)

1
2
3
4
5
6
7
8
9
10
11
\cp-frp/usr/lib64/libltdl.so*/usr/lib/
 
\cp-frp/usr/lib64/libXpm.so*/usr/lib/
 
cd/home
 
tar-zvxf php-5.6.5.tar.gz
 
cdphp-5.6.5
 
export LD_LIBRARY_PATH=/usr/local/libgd/lib

 

# 核对每一项安装的路径配置 本人这里的–with-mysql-sock=/tmp/mysqld.sock 有的为 –with-mysql-sock=/tmp/mysql.sock

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
./configure \
--prefix=/usr/local/php \
--with-config-file-path=/usr/local/php/etc \
--with-mysql=/data/mysql \
--with-mysqli=/data/mysql/bin/mysql_config \
--with-mysql-sock=/tmp/mysql.sock \
--with-pdo-mysql=/data/mysql \
--with-gd \
--with-png-dir=/usr/local/libpng \
--with-jpeg-dir=/usr/local/jpeg \
--with-freetype-dir=/usr/local/freetype \
--with-xpm-dir=/usr/ \
--with-vpx-dir=/usr/local/libvpx/ \
--with-zlib-dir=/usr/local/zlib \
--with-t1lib=/usr/local/t1lib \
--with-iconv \
--enable-libxml \
--enable-xml \
--enable-bcmath \
--enable-shmop \
--enable-sysvsem \
--enable-inline-optimization \
--enable-opcache \
--enable-mbregex \
--enable-fpm \
--enable-mbstring \
--enable-ftp \
--enable-gd-native-ttf \
--with-openssl \
--enable-pcntl \
--enable-sockets \
--with-xmlrpc \
--enable-zip \
--enable-soap \
--without-pear \
--disable-phar \
--with-gettext \
--enable-session \
--with-mcrypt \
--with-curl \
--enable-ctype \
--with-apxs2=/usr/local/httpd/bin/apxs 
 
 
 
make&&makeinstall
 

上面标志为红的,编译的时候要注意,另外在make 之后还是要运行下 make test 看下是否有error。

四,配置

1 配置 php.ini
cp  php.ini-production /usr/local/php/etc/php.ini#复制php配置文件到安装目录
 
rm -rf /etc/php.ini#删除系统自带配置文件
 
ln -/usr/local/php/etc/php.ini  /etc/php.ini    #添加软链接到 /etc目录
 
cp  /usr/local/php/etc/php-fpm.conf.default  /usr/local/php/etc/php-fpm.conf  #拷贝模板文件为php-fpm配置文件
 
ln -/usr/local/php/etc/php-fpm.conf  /etc/php-fpm.conf  #添加软连接到 /etc目录
 
  2 配置php-fpm 
 
vi  /usr/local/php/etc/php-fpm.conf  #编辑
 
user=www #设置php-fpm运行账号为www
 
group=www #设置php-fpm运行组为www
 
pid=run/php-fpm.pid #取消前面的分号
 
:wq!#保存退出
 
  设定开机启动
 
cp   sapi/fpm/init.d.php-fpm /etc/rc.d/init.d/php-fpm  #拷贝php-fpm到启动目录
 
chmod +/etc/rc.d/init.d/php-fpm   #添加执行权限
 
chkconfig php-fpm on#设置开机启动
 
 
3 pdo扩展配置

链接地址  http://blog.xuahua.com/articles/2016/05/09/1462762206356.html


centos+php5.6+pdo扩展

centos+php5.6+pdo扩展

 

链接 : http://blog.xuahua.com/articles/2016/05/09/1462762206356.html

假设php目录为/usr/local/php
mysql目录为/usr/local/mysql
1. 进入PHP源码包ext/pdo目录


cd ext/pdo

2. 执行/usr/local/php/bin/phpize[假设PHP的安装目录为/usr/local/php]


/usr/local/php/bin/phpize

3. 配置扩展pdo


./configure --with-php-config=/usr/local/php/bin/php-config --enable-pdo=shared

4. 编译 && 安装pdo


make && make install

成功则出现
Installing shared extensions: /usr/local/php//lib/php/extensions/no-debug-non-zts-20060613/
Installing header files: /usr/local/php//include/php/
Installing PDO headers: /usr/local/php//include/php/ext/pdo/
说明在/usr/local/php//lib/php/extensions/no-debug-non-zts-20060613/目录下生成了pdo.so文件

5. 在PHP源码包中进入pdo_mysql


cd ext/pdo_mysql

6. /usr/local/php/bin/phpize

/usr/local/php/bin/phpize

7. 配置pdo_mysql[假设Mysql的安装目录为/usr/local/mysql]

1
./configure --with-php-config=/usr/local/php/bin/php-config --with-pdo-mysql=/usr/local/mysql
8. 编译 安装pdo_mysql

make && make install

centos7-安装-apache运行环境-httpd

 

下载编译安装apache 2.4.20

 链接 http://blog.xuahua.com//articles/2016/05/09/1462761030425.html

1,apache 的安装

安装apache之前,可能需要安装apr,如果没有,就按下面的方式安装即可。

1.1 安装 apr

wget http://mirror.bit.edu.cn/apache//apr/apr-1.5.2.tar.gz 下载apr

./configure  --prefix=/usr/local/apr

make

make  install

 

wget  http://mirror.bit.edu.cn/apache//apr/apr-util-1.5.4.tar.gz

./configure  --prefix=/usr/local/apr-util  --with-apr=/usr/local/apr

make

make install

 

1.2 下载安装httpd

 

  yum install gcc

wget http://mirror.bit.edu.cn/apache//httpd/httpd-2.4.20.tar.gz
tar -jxvf httpd-2.4.20.tar.gz
cd httpd-2.4.20

 ./configure --prefix=/usr/local/httpd --enable-track-vars --enable-cgi --with-config-file-path=/usr/local/httpd/conf  --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util 

make 

make install

1.3 添加对php的支持

AddType application/x-httpd-php .php

    AddType application/x-httpd-php-source .php5
找到:
    <IfModule dir_module>
    DirectoryIndex index.html
    </IfModule>
    添加:
    <IfModule dir_module>
    DirectoryIndex index.html index.php
    </IfModule>   

2.4 运行启动 httpd

/usr/local/httpd/sbin/httpd restart

 

如果80 端口被占用,起不来,可以通过修改 

vim /usr/local/httpd/conf/http-config 

  链接 http://blog.xuahua.com//articles/2016/05/09/1462761030425.html

麻将胡牌算法研究 有更新!

转自 http://blog.sina.com.cn/s/blog_7213e0310101dq3w.html

麻将通常有13张牌,在打的时候随着吃,碰越来越少。总数应该维持在3*n + 1n=0~4,比如1张,4张,7张或10张。胡牌时,加一张(可能是自摸或吃碰来的一张)组成n个顺子或暗刻,外加一个麻将对。

这里要研究的要点是:

1. 给出3n + 2张牌如何判断是否已经胡牌,所有的胡牌可能组合;

2. 如果给出3n+1张牌如何判断是否已经挺牌,挺哪些牌。

这两个问题其实主要是第一个问题,也就是如何判断3n +2 张牌是否胡牌的问题。后者可以简单地通过实验加34种麻将牌之一看是否胡牌来判断是否挺牌,以及挺哪些牌。

 

如何判断3n +2张牌是否胡牌

麻将牌包括:

1~9

1~9

1~9

东西南北中发白

34种牌,34×4=136张牌。

给每张牌设一个编号

1~9     -------à 0 ~8

1~9     ------à 9~17

1~9     ------à 18~26

东西南北中发白    -----à 27~33

 

1 牌的存储

设一个宏,就是牌的种类

#define MAX_TILE_INDEX 34

所摸的牌就可以存在一个长度为34的数组中

int tiles[MAX_TILE_INDEX];

数组的每个成员最大值为4,因为每张牌的总数为4,就算摸到暗杠也不过是4. 所有数组成员加起来应该是3n + 2

 

2 结果的存储

每个胡牌必定是若干顺子/暗刻,外加一个麻将对,用一个简单的结构或类大概就是:

{

         int nSequence[4][3];

         int nPair[2];  //或直接nPair,不用数组就可以表示麻将对了

}

 

给定的3n + 2张牌普通只胡一种情况,但特殊情况也可能有多种胡法,比如4个一万,4个两万,43万,2个四万

胡牌至少可以:

i. 41万,2万和3万的顺子,外加4万的麻将对;

ii. 11万,2万和3万的顺子,1万暗刻,2万暗刻,3万暗刻,以及4万麻将对。

这些结果都应该被存起来,胡牌应该以最大番数计算。

C++可以用一个vector模板来实现结果列表,java可以考虑用哈希表。

 

3. 胡牌判断算法

判断胡牌与否

判断胡牌与否的过程:

3.1. 首先判断总牌数是否为3n + 2,如果不是肯定不胡牌

3.2. 遍历所有牌,找到所有一种牌数量大于2的情况,也就是ntile[index] >= 2,然后把这两张牌(对子)去掉,记录到结果中的nPair。然后就剩下3n张牌了,再判断剩下的3n张牌是否能组成顺子或是暗刻,如果可以全部组成,那么这把牌就胡了,否则需要遍历一下把其他牌当对子的可能性。

关于第二步中如何判断3n 张牌可否组成顺子或暗刻

从第一张(种)牌开始往后检查,每张牌有5种可能, 0 1 234。如果是0,直接检查下一张(种);

i. 如果是1张或两张,要胡牌的话他(们)必须和后面两张组成顺子,如果不能组成顺子,肯定不胡。如果可以组成顺子,把顺子牌取出,存入临时结果,接着处理剩下的牌;

ii. 如果是3张,要胡牌有两种可能,一是3张当作一个暗刻,还有一种可能是这3张都与后面的牌组成顺子。这里有检查这两种情况。比如3个一万,3个两万和3个三万。既可以以三暗刻算,也可以按三个顺子算。这两种在最后算番的时候不一样。

iii. 如果是4张,胡牌的话必须要跟后面两张牌组成一个顺子,然后本张(种)就剩3种了,然后继续2.2的步骤就可以了。

整个检查过程可以用一个函数递归调用就可以了,每次处理一张,如果不能凑成顺子或暗刻的话就推出返回错误,如果函数处理时总牌数为0,则所有牌都已处理完了,返回成功,结果也已经存在结果里了,把结果加入结果列表。

4. 挺牌检查

挺牌时应该是3*n + 1张牌。遍历34种牌,加入3n +1 ,这时就是3n+2了,根据刚才的算法算是否胡牌,如果胡牌,刚加入的那张牌就是挺牌。

 

5. 测试过程与结果

1. 挺牌检查 选用了非常复杂的九莲宝灯,也就是3个一万(或条,饼),3个九万(或条饼),其他2万到8万(或条饼)。这种牌是挺从1万到9万,共9张挺牌。算法可以正确算出。

2. 胡牌检查 选用了4个一万,4个二万,4个三万,以及24万,算法正确列出了3种胡牌结果。

 

文件链接 http://blog.xuahua.com//articles/2016/04/12/1460455830963.html

java提高篇-导出execl(通用工具类) 有更新!

在web开发中,经常会遇到需要把数据导出到EXCEL中,并提供下载。

那么本文将提供一个通用的导出EXCEL的工具类。。。具体的实现或自定义的样式,可以自己定义。

请看下文代码

package com.xuahua.utils;

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.Colour;
import jxl.format.VerticalAlignment;
import jxl.write.Label;
import jxl.write.Number;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;

import org.apache.log4j.Logger;

/**
 * @author wyong 提供公用方法,来生成xls。 具体的数据对象由writeContent实现,标签页的头由getHeaders实现。
 * 
 */
public class ExportExcelUtils {

	protected Label label;
	protected Number number;

	protected WritableWorkbook wwb;
	protected WritableSheet ws;
	protected int rowIndex = 0;
	protected int MAXRECORD = 60000;// 每个工作空间最大记录条数。

	protected WritableCellFormat titleFormat1;
	protected WritableCellFormat headerFormat1;
	protected WritableCellFormat cellFormat1;
	protected WritableCellFormat dateCellFormat;

	private static final Logger logger = Logger
			.getLogger(ExportExcelUtils.class);

	public ExportExcelUtils() {
		try {
			headerFormat1 = initHeaderFormat();
			cellFormat1 = initCellFormat();
			dateCellFormat = initDateFormat();
			titleFormat1 = initTitleFormate();
		} catch (WriteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void xls(OutputStream os, String sheetName, List contentList)
			throws Exception {
		wwb = Workbook.createWorkbook(os);
		try {
			int maxsize = contentList.size();
			if (maxsize > MAXRECORD) {
				int s = maxsize % MAXRECORD == 0 ? maxsize / MAXRECORD
						: maxsize / MAXRECORD + 1;
				List tmpList = new ArrayList(MAXRECORD);
				for (int i = 0; i < s; i++) {
					rowIndex = 0;
					tmpList = contentList.subList(i * MAXRECORD, (i + 1)
							* MAXRECORD > maxsize ? maxsize : (i + 1)
							* MAXRECORD);
					ws = wwb.createSheet(sheetName + "-" + i, i);
					this.writeHeaders();
					this.writeContent(tmpList);
				}
			} else {
				ws = wwb.createSheet(sheetName, 0);
				this.writeHeaders();
				this.writeContent(contentList);
			}
		} finally {
			wwb.write();
			wwb.close();

			os.flush();
			os.close();
		}
	}

	/**
	 * @param objlist
	 *            需要写入xls文件中的对象。做过处理的一个标签页最多60000条。
	 * @throws Exception
	 */
	public void writeContent(List objlist) throws Exception {
		throw new Exception("u` must implements this method.");
	};

	/**
	 * xls文件中的标题头。
	 * 
	 * @return
	 * @throws Exception
	 */
	public List<Map<String, Object>> getHeaders() throws Exception {
		throw new Exception("u` must implements this method.");
	};

	// 写表头
	public void writeHeaders() throws Exception {
		List<Map<String, Object>> headers = this.getHeaders();

		for (int i = 0; i < headers.size(); i++) {
			Map<String, Object> map = headers.get(i);

			Label label = new Label(i, rowIndex, map.get("value").toString(),
					headerFormat1);
			ws.addCell(label);

		}
		rowIndex++;
	}

	/**
	 * 格式化日期单元格
	 * 
	 * @return
	 * @throws WriteException
	 */
	protected WritableCellFormat initDateFormat() throws WriteException {
		jxl.write.DateFormat df = new jxl.write.DateFormat("yyyy-MM-dd HH:mm:ss");
		WritableCellFormat dateCellFormat = new jxl.write.WritableCellFormat(df);
		dateCellFormat.setAlignment(Alignment.LEFT);
		dateCellFormat.setVerticalAlignment(VerticalAlignment.CENTRE);
		dateCellFormat.setBorder(Border.ALL, BorderLineStyle.THIN, Colour.BLACK);
		dateCellFormat.setAlignment(Alignment.CENTRE); //设置水平对齐
		dateCellFormat.setWrap(false); //设置自动换行
		return dateCellFormat;
	}

	/**
	 * 格式化单元格样式
	 * 
	 * @return
	 * @throws WriteException
	 */
	protected WritableCellFormat initCellFormat() throws WriteException {
		WritableFont cellFont1 = new WritableFont(WritableFont.TIMES, 12);
		WritableCellFormat cellFormat1 = new WritableCellFormat(cellFont1);
		cellFormat1.setAlignment(Alignment.LEFT);
		cellFormat1.setVerticalAlignment(VerticalAlignment.CENTRE);
		cellFormat1.setBorder(Border.ALL, BorderLineStyle.THIN, Colour.BLACK);
		cellFormat1.setAlignment(Alignment.CENTRE); //设置水平对齐
		cellFormat1.setWrap(false); //设置自动换行
		return cellFormat1;

	}

	/**
	 * @return 格式化headerformate
	 * @throws WriteException
	 */
	protected WritableCellFormat initHeaderFormat() throws WriteException {
		WritableFont headerFont1 = new WritableFont(WritableFont.TIMES, 14,
				WritableFont.BOLD);
		headerFont1.setColour(Colour.BLUE);
		WritableCellFormat headerFormat1 = new WritableCellFormat(headerFont1);
		headerFormat1.setAlignment(Alignment.CENTRE);
		headerFormat1.setVerticalAlignment(VerticalAlignment.CENTRE);
		headerFormat1.setBorder(Border.ALL, BorderLineStyle.THIN, Colour.BLACK);
		headerFormat1.setBackground(Colour.YELLOW);
		headerFormat1.setAlignment(Alignment.CENTRE); //设置水平对齐
		headerFormat1.setWrap(false); //设置自动换行
		return headerFormat1;
	}

	/**
	 * 格式化initTitleFormate1
	 * 
	 * @return
	 * @throws WriteException
	 */
	protected WritableCellFormat initTitleFormate() throws WriteException {
		WritableFont titleFont1 = new WritableFont(WritableFont.TIMES, 24,
				WritableFont.BOLD);
		titleFont1.setColour(Colour.BLUE);
		WritableCellFormat titleFormat1 = new WritableCellFormat(titleFont1);
		titleFormat1.setAlignment(Alignment.CENTRE);
		titleFormat1.setVerticalAlignment(VerticalAlignment.CENTRE);
		titleFormat1.setBorder(Border.ALL, BorderLineStyle.THIN, Colour.BLACK);
		titleFormat1.setBackground(Colour.YELLOW);
		titleFormat1.setAlignment(Alignment.CENTRE); //设置水平对齐
		titleFormat1.setWrap(false); //设置自动换行
		return titleFormat1;
	}
}

liunx提高篇-NODEJS 环境布署

 
1,nodejs安装
>解压缩 tar -xvf node-v4.2.4-liunx-x64.tar.gz
 设置全局:
 
1
2
ln -s /home/kun/mysofltware/node-v0.10.28-linux-x64/bin/node /usr/local/bin/node
ln -s /home/kun/mysofltware/node-v0.10.28-linux-x64/bin/npm /usr/local/bin/npm
 

(二)通过源码编译

    这种方式你下载的文件是Source code,我不太喜欢这种方式。。。主要是麻烦

 wget https://nodejs.org/dist/v4.2.4/node-v4.2.4-sunos-x64.tar.gz

1
2
3
4
5
6
7
8
9
10
11
#  tar xvf node-v0.10.28.tar.gz 
#  cd node-v0.10.28 
#  ./configure 
# make 
# make install 
# cp /usr/local/bin/node /usr/sbin/ 
 
查看当前安装的Node的版本 
# node -v 
 
v0.10.28

liunx基础篇- find 用法示例

转自http://www.cnblogs.com/wanqieddy/archive/2011/06/09/2076785.html

Linux中find常见用法示例

·find   path   -option   [   -print ]   [ -exec   -ok   command ]   {} \;

find命令的参数;

pathname: find命令所查找的目录路径。例如用.来表示当前目录,用/来表示系统根目录。
-print: find命令将匹配的文件输出到标准输出。
-exec: find命令对匹配的文件执行该参数所给出的shell命令。相应命令的形式为'command' { } \;,注意{ }和\;之间的空格。
-ok: 和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行。

#-print 将查找到的文件输出到标准输出
#-exec   command   {} \;      —–将查到的文件执行command操作,{} 和 \;之间有空格
#-ok 和-exec相同,只不过在操作前要询用户
 
例:find . -name .svn | xargs rm -rf

====================================================

-name   filename             #查找名为filename的文件
-perm                        #按执行权限来查找
-user    username             #按文件属主来查找
-group groupname            #按组来查找
-mtime   -n +n                #按文件更改时间来查找文件,-n指n天以内,+n指n天以前
-atime    -n +n               #按文件访问时间来查GIN: 0px">

-ctime    -n +n              #按文件创建时间来查找文件,-n指n天以内,+n指n天以前

-nogroup                     #查无有效属组的文件,即文件的属组在/etc/groups中不存在
-nouser                     #查无有效属主的文件,即文件的属主在/etc/passwd中不存
-newer   f1 !f2              找文件,-n指n天以内,+n指n天以前 
-ctime    -n +n               #按文件创建时间来查找文件,-n指n天以内,+n指n天以前 
-nogroup                     #查无有效属组的文件,即文件的属组在/etc/groups中不存在
-nouser                      #查无有效属主的文件,即文件的属主在/etc/passwd中不存
-newer   f1 !f2               #查更改时间比f1新但比f2旧的文件
-type    b/d/c/p/l/f         #查是块设备、目录、字符设备、管道、符号链接、普通文件
-size      n[c]               #查长度为n块[或n字节]的文件
-depth                       #使查找在进入子目录前先行查找完本目录
-fstype                     #查更改时间比f1新但比f2旧的文件
-type    b/d/c/p/l/f         #查是块设备、目录、字符设备、管道、符号链接、普通文件
-size      n[c]               #查长度为n块[或n字节]的文件
-depth                       #使查找在进入子目录前先行查找完本目录
-fstype                      #查位于某一类型文件系统中的文件,这些文件系统类型通常可 在/etc/fstab中找到
-mount                       #查文件时不跨越文件系统mount点
-follow                      #如果遇到符号链接文件,就跟踪链接所指的文件
-cpio                %;      #查位于某一类型文件系统中的文件,这些文件系统类型通常可 在/etc/fstab中找到
-mount                       #查文件时不跨越文件系统mount点
-follow                      #如果遇到符号链接文件,就跟踪链接所指的文件
-cpio                        #对匹配的文件使用cpio命令,将他们备份到磁带设备中
-prune                       #忽略某个目录

=====================================================
$find   ~   -name   "*.txt"   -print    #在$HOME中查.txt文件并显示
$find   .    -name   "*.txt"   -print
$find   .    -name   "[A-Z]*"   -print   #查以大写字母开头的文件
$find   /etc   -name   "host*"   -print #查以host开头的文件
$find   .   -name   "[a-z][a-z][0–9][0–9].txt"    -print   #查以两个小写字母和两个数字开头的txt文件
$find .   -perm   755   -print
$find   .   -perm -007   -exec ls -l {} \;   #查所有用户都可读写执行的文件同-perm 777
$find   . -type d   -print
$find   .   !   -type   d   -print 
$find   .   -type l   -print

$find   .   -size   +1000000c   -print        #查长度大于1Mb的文件
$find   .   -size   100c         -print       # 查长度为100c的文件
$find   .   -size   +10   -print              #查长度超过期作废10块的文件(1块=512字节)

$cd /
$find   etc   home   apps    -depth   -print   | cpio   -ivcdC65536   -o   /dev/rmt0
$find   /etc -name "passwd*"   -exec grep   "cnscn"   {}   \;   #看是否存在cnscn用户
$find . -name "yao*"   | xargs file
$find   . -name "yao*"   |   xargs   echo    "" > /tmp/core.log
$find   . -name "yao*"   | xargs   chmod   o-w

======================================================

find   -name april*                     在当前目录下查找以april开始的文件
find   -name   april*   fprint file        在当前目录下查找以april开始的文件,并把结果输出到file中
find   -name ap* -o -name may*   查找以ap或may开头的文件
find   /mnt   -name tom.txt   -ftype vfat   在/mnt下查找名称为tom.txt且文件系统类型vfat的文件
find   /mnt   -name t.txt ! -ftype vfat   在/mnt下查找名称为tom.txt且文件系统类型不为vfat的文件
find   /tmp   -name wa* -type l            在/tmp下查找名为wa开头且类型为符号链接的文件
find   /home   -mtime   -2                 在/home下查最近两天内改动过的文件
find /home    -atime -1                  查1天之内被存取过的文件
find /home -mmin    +60                  在/home下查60分钟前改动过的文件
find /home   -amin   +30                  查最近30分钟前被存取过的文件
find /home   -newer   tmp.txt             在/home下查更新时间比tmp.txt近的文件或目录
find /home   -anewer   tmp.txt            在/home下查存取时间比tmp.txt近的文件或目录
find   /home   -used   -2                  列出文件或目录被改动过之后,在2日内被存取过的文件或目录
find   /home   -user cnscn                列出/home目录内属于用户cnscn的文件或目录
find   /home   -uid   +501                  列出/home目录内用户的识别码大于501的文件或目录
find   /home   -group   cnscn              列出/home内组为cnscn的文件或目录
find   /home   -gid 501                   列出/home内组id为501的文件或目录
find   /home   -nouser                    列出/home内不属于本地用户的文件或目录
find   /home   -nogroup                   列出/home内不属于本地组的文件或目录
find   /home    -name tmp.txt    -maxdepth   4   列出/home内的tmp.txt 查时深度最多为3层
find   /home   -name tmp.txt   -mindepth   3   从第2层开始查
find   /home   -empty                     查找大小为0的文件或空目录
find   /home   -size   +512k                查大于512k的文件
find   /home   -size   -512k               查小于512k的文件
find   /home   -links   +2                查硬连接数大于2的文件或目录
find   /home   -perm   0700                查权限为700的文件或目录
find   /tmp   -name tmp.txt   -exec cat {} \;
find   /tmp   -name   tmp.txt   -ok   rm {} \;

find    /   -amin    -10     # 查找在系统中最后10分钟访问的文件
find    /   -atime   -2        # 查找在系统中最后48小时访问的文件
find    /   -empty             # 查找在系统中为空的文件或者文件夹
find    /   -group   cat        # 查找在系统中属于 groupcat的文件
find    /   -mmin   -5         # 查找在系统中最后5分钟里修改过的文件
find    /   -mtime   -1       #查找在系统中最后24小时里修改过的文件
find    /   -nouser           #查找在系统中属于作废用户的文件
find    /   -user    fred     #查找在系统中属于FRED这个用户的文件

 
查当前目录下的所有普通文件
# find . -type f -exec ls -l {} \; 
-rw-r–r–    1 root      root         34928 2003-02-25   ./conf/httpd.conf 
-rw-r–r–    1 root      root         12959 2003-02-25   ./conf/magic 
-rw-r–r–    1 root      root          180 2003-02-25   ./conf.d/README 
查当前目录下的所有普通文件,并在- e x e c选项中使用ls -l命令将它们列出

=================================================
在/ l o g s目录中查找更改时间在5日以前的文件并删除它们:
$ find logs -type f -mtime +5 -exec   -ok   rm {} \;

=================================================
查询当天修改过的文件
[root@book class]# find   ./   -mtime   -1   -type f   -exec   ls -l   {} \;

=================================================
查询文件并询问是否要显示
[root@book class]# find   ./   -mtime   -1   -type f   -ok   ls -l   {} \;  
< ls … ./classDB.inc.php > ? y
-rw-r–r–    1 cnscn    cnscn       13709   1月 12 12:22 ./classDB.inc.php
[root@book class]# find   ./   -mtime   -1   -type f   -ok   ls -l   {} \;  
< ls … ./classDB.inc.php > ? n
[root@book class]#

=================================================
查询并交给awk去处理
[root@book class]# who   |   awk   ’{print $1"\t"$2}’
cnscn    pts/0

=================================================
awk—grep—sed

[root@book class]# df   -k |   awk ‘{print $1}’ |   grep   -v   ’none’ |   sed   s"/\/dev\///g"
文件系统
sda2
sda1
[root@book class]# df   -k |   awk ‘{print $1}’ |   grep   -v   ’none’
文件系统
/dev/sda2
/dev/sda1

 
 
1)在/tmp中查找所有的*.h,并在这些文件中查找“SYSCALL_VECTOR",最后打印出所有包含"SYSCALL_VECTOR"的文件名

A) find   /tmp   -name   "*.h"   | xargs   -n50   grep SYSCALL_VECTOR
B) grep   SYSCALL_VECTOR   /tmp/*.h | cut    -d’:'   -f1| uniq > filename
C) find   /tmp   -name "*.h"   -exec grep "SYSCALL_VECTOR"   {}   \; -print

2)find / -name filename -exec rm -rf {} \;
    find / -name filename -ok rm -rf {} \;

3)比如要查找磁盘中大于3M的文件:
find . -size +3000k -exec ls -ld {} ;

4)将find出来的东西拷到另一个地方
find *.c -exec cp ‘{}’ /tmp ‘;’

如果有特殊文件,可以用cpio,也可以用这样的语法:
find dir -name filename -print | cpio -pdv newdir

6)查找2004-11-30 16:36:37时更改过的文件
# A=`find ./ -name "*php"` |   ls -l –full-time $A 2>/dev/null | grep "2004-11-30 16:36:37"

Linux-allLinux | No Comments »

find 实例

四月 18th, 2006

  要在/usr/linux中查找所有的*.h,并在这些文件中查找“SYSCALL_VECTOR",最后打印出所有包含"SYSCALL_VECTOR"的文件名,有以下几种方法实现
find /usr/linux -name "*.h" | xargs -n50 grep SYSCALL_VECTOR
grep SYSCALL_VECTOR /usr/linux/*.h | cut -d’:’ -f1 | uniq > filename
find /usr/linux -name "*.h" -exec grep "SYSCALL_VECTOR" {} \; -print

  我用find / -name filename| rm -rf,不成功,请问为什么不成功?
find / -name filename -exec rm -rf {} \;
find . -name filename |rm -rf试一下{} 表示你找出来的结果。
\; 则相当于“宪法”,没什么说头,就是这么规定的,在 -exec 后面需要一个表示该命令终结的的符号。可以在 man find 中找到答案。
要让rm识别find的结果,如下:
find / -name filename |xargs rm -rf
之所以find . -name filename |rm -rf不通过,是因为rm命令不接受从标准输入传过来的指令
查找含特定字符串的文件
例如查找当前目录下含有"the string you want find…"字符串的文件:
$find . -type f -exec grep “the string you want find…” {} ; -print

  从根目录开始查tmpfile,一旦查到马上删除
find / -name "tmpfile" -exec rm {} \;

  find 的perm问题
请问一下以下命令什么意思?关键是那个数字前的-,其他都还知道
find -name ".*" -perm -007
我知道
find -name ".*" -perm 755
这个是用来查找权限位为755的隐藏文件
噢,对了还有,我上边的命令都省略了find的pathname参数 find默认是查找当前工作目录的吗?
如果我用 -ok 替代 -exec, 那么还需要加上 {} \; 吗?
这个已经清楚,仍然需要,因为 -ok 只是 -exec 的提示模式,它只是多了一个确认操作的步骤,刚才没有读懂那几句E文的意思 呵呵 不好意思
-007是指查找所有用户都可读、写、执行的文件,要小心呀~~~
解释解释?
find -name ".*" -perm -007 和 find -name ".*" -perm 777 有区别吗?
-007是怎么来得呢?
不过有一个问题
我用 find . -perm -100 会列出当前目录 . , 这是为什么呢?

下面引用由explover在 2002/10/01 06:15am 发表的内容:
-007是指查找所有用户都可读、写、执行的文件,要小心呀~~~
-007是查找含其它用户(不同组,非属主)可读,写,执行的文件.并不一定要同组可读写,-是指最少权限为007.
下面引用由一颗小白菜在 2002/10/01 10:16am 发表的内容:
OK了, 呵呵
不过有一个问题
我用 find . -perm -100 会列出当前目录 . , 这是为什么呢?
这种方法不会准确的找出目录的. -100是指权限至少是属主可运行.
在unix系统下,你可以拥有对目录文件的执行权你才可以进入一个目录.这便是目录文件被列出的原因.
find . -perm -001 -print找到往往是目录文件.
我的意思当然不是使用这种方法来找目录,只不过不明白其中的 -100 意义了
那以此类推,是不是 -010是指权限至少是owner同组可执行的吗?也就是说其实这里的010和-是分开的,-表示一个至少的意思,而且010才是真正用来描述权限位的?
这样子就明白了 谢谢你噢

  将find出来的东西拷到另一个地方?
find *.c -exec cp ‘{}’ /tmp ‘;’
如果有特殊文件,可以用cpio,也可以用这样的语法:
find dir -name filename -print | cpio -pdv newdir

  找出磁盘中某个大小范围内的文件
比如要查找磁盘中大于3M的文件:
find . -size +3000k -exec ls -ld {} ;

  如何用find查找某一天更改的文件?
可以使用这一行命令来实现:
A=`find ~ -print` | ls -l –full-time $A 2>/dev/null | grep "Jun 27" | grep 1998

  使用find 命令查找某个时间段的shell怎么写。比如11点到12点的。thanks
创建一个脚本judgetime,内容如下:
ls -l $*|awk ‘{split($8,hour,":");if((hour[1]>23 || hour[1] < 1)&&hour[1]<24)print}’
到要查找的目录下,运行
find ./ -name "*" -exec judgetime {} \;
注意时间格式为24小时制。
thank you ,如果我要精确到分钟呢
touch -t 04241112 starttemp #精确到12分钟
touch -t 04241220 endtemp #截止到12点20
find [dir] -newer starttemp -a ! -newer endtemp -exec ls -l {} \;
newer?
那昨天12:10文件如何呢?
每天执行的时候,用当天的日期和时间戳替换一下不就行了吗?
我不知道他是不是把所有的11:00~12:00的都找出来,是不是只执行一次还是每天都执行?
这种情况俺猜想是自己的东西放在哪忘了,只记得当时是深夜了。
有道理!
不愧是斑竹!
不光知道怎么解决问题,还知道在什么情况下出现这类问题,佩服佩服!
问题又出现了。创建这个文件的时候。本来应该是时间的一栏现在写上了2002,而不是12:00.
等到12:00过了吧!

  删除指定日期的文件
find ./ -name 文件名 -exec rm -f {} \;
例:删除当前30天内没用过的文件,用如下命令:
find / -atime +30 -exec rm -f {} \;
我自己试着写了一小段SHELL,也用ll ,grep, rm 几个命令,用起来还差强人意。
对过滤出来的文件名列表中用了一个FOR语句,再执行rm 。现在我想把这段SHELL 扩展一下让它每天定时运行将 n 天前的文件删掉,有没有人能给我一些提示,谢谢!
还有个问题,对于前面那位朋友提到的"find / -atime +30 -exec rm -f {} \;
"方法,我很早就试过几次,不过好像都不太对,参数 -atime n 是查找n天前被访问过的文件,我不明白的是这里的时间参照点是什么,以及这个n天是怎么计算的。
问 题二、对于"ll |cut -f 1" 这个命令我是不是用错了,我只想取出 ll 中列出的文件名,但用cut -f 命令做不到 ,我只好换用 ll |cut -c 59- 这种方式得到我要的文件名,but it’s a pool idear !我也试过用awk ,好像也不对,看看大家可不可以给我一些小小的提醒,TKS SO MUCH
问题三、如何改变 I结点 的日期格式 我现在的系统显示的格式是:
-rw-r—– 1 msahz01 users 2253 2002年2月 2日 poheader.i
我想把这换成
-rw-rw-rw- 1 house users 2193 Apr 19 2001 hkdisp.p
如何才能做到这点?
awk 应该可以
ll | awk ‘{print $9}’
删除多少天之前的文件
find /yourpath -mtime +31 -exec rm {} \;
find /yourpath -mtime +366 -exec rm {} \;

find中, -ctime, -mtime及其-atime有何区别

请问 -ctime 和 -mtime 有什么关系 ?
如果父目录的 ctime 改变, 那它下面的文件的 ctime 就会自动都改了吗 ?
-ctime 和 -mtime ,-atime 这些信息是存在哪儿呢 ?

我用 -mtime -1 找到了新建或改的文件.
但怎样才能找到一天内 mv 来的文件呢( 它们的时间是原有的时间,早于一天 ) ?

用-newer选项啊。
你可以先touch一个你想要的时间的文件如下:
$ touch -t 08190800 test
$ ls -l test
-rw-r–r– 1 dba other 0 Aug 19 08:00 test
然后
$ find . -newer test -print
.
./.sh_history
$ ls -l .sh_history
-rw——- 1 dba other 154 Aug 20 17:39 .sh_history

用touch可以写出你想要的任何时间的文件,然后用-newer ,! -newer选项即可成功。

1.ctime含inode信息修改的时间.mtime只指文件内容建立或修改的时间.
2 不会.
3.这些信息应该是存在文件系统的超级块里.

我查了书 -ctime 是指 inode 的改变(或称文件的状态改变).
请问 inode 存了哪些信息 ?
做了些小测试,-mtime 改, -ctime 一定也改.
改文件名, -ctime 也会改.
谁能回答 i-node 存了哪些东西 ?

vi /usr/include/sys/inode.h

班主,我不能 access /usr/include/sys/inode.h .
摘书如下:
Directories contain directory entries. Each entry contains a file or subdirectory name and an index node reference number (i-node number). To increase speed and enhance use of disk space, the data in a file is stored at various locations in the computer’s memory. The i-node contains the addresses used to locate all the scattered blocks of data associated with a file. The i-node also records other information about the file including time of modification and access, access modes, number of links, file owner, and file type.
可我发现 -atime 改了, -ctime 还没改. why ?
( 我先 cat 一个 ASCII 文件,再用 -atime -1 有它用 -ctime -1 居然没有它.)
着岂不跟 inode 信息改变, ctime 就改矛盾吗?

我不同意你贴出来的那段文章,正如我提到的那样,atime,ctime,mtime是放到超级块里,在sco unix下是一种叫stat的结构.(stat_32),不同的系统文件系统可能不同.
sco 下inode的结构如下:

typedef struct inode
{
struct inode *i_forw; /* inode hash chain */
struct inode *i_back; /* ‘’ */
struct inode *av_forw; /* freelist chain */
struct inode *av_back; /* ‘’ */
int *i_fsptr; /* "typeless" pointer to fs dependent */
ino32_t i_number; /* i number, 1-to-1 with dev address */
ushort i_ftype; /* file type = IFDIR, IFREG, etc. */
short i_fstyp; /* File system type */
off_t i_size; /* size of file */
ushort i_uid; /* owner */
ushort i_gid; /* group of owner */
ushort i_flag;
ushort i_want; /* i_flag extension to avoid MP races */
ushort i_count; /* reference count */
short i_nlink; /* directory entries */
dev_t i_rdev; /* Raw device number */
#define i_namtype i_rdev /* i_ftype==IFNAM subtype */
dev_t i_dev; /* device where inode resides */
struct mount *i_mton;/* ptr to mount table entry that */
/* this directory is mounted on */
struct region *i_rp; /* ptr to shared region if any */
struct stdata *i_sp; /* ptr to associated stream */
struct iisem *isem; /* ptr to XENIX semaphores */
struct iisd *isd; /* ptr to XENIX shared data */
} i_un;
#define i_mnton i_un.i_mton /* i_ftype==IFDIR IMOUNT */
#define i_rptr i_un.i_rp /* i_ftype==IFREG || i_ftype==IFBLK */
#define i_sptr i_un.i_sp /* i_ftype==IFCHR || i_ftype==IFIFO */
#define i_sem i_un.isem /* i_ftype==IFNAM && i_namtype==IFSEM */
#define i_sd i_un.isd /* i_ftype==IFNAM && i_namtype==IFSHD */

struct fstypsw *i_fstypp; /* ptr to file system switch FSPTR */
long *i_filocks; /* pointer to filock (structure) list */
unsigned long i_mappages; /* number of pages currently cached */
unsigned long i_vcode; /* read-ahead block save (NFS) */
short i_wcnt; /* write open count or ITEXT count */
struct lockb i_cilock; /* tas to synchronize i_flag changes */
ushort i_rdlocks; /* count of non-exclusive lockers */
} inode_t;

所以,访问一个文件不能改变inode信息.
使用chown, chgrp, chmod命令可以很好的比较mtime和ctime
chown改变一个文件的属主,用ctime可以找到,用mtime便找不到.
试试看.

多谢斑竹! 我是在 Solaris 上面试的.我是对 -ctime 不明白.
试的结果如下:
修改文件,-mtime 改了, -ctime 也会改.
访问文件,-atime 改了, -ctime 没变.
chown, chgrp, chmod,mv, 都会使 -ctime 改变,但不影响 -atime 和 -mtime.
touch 可以改 -mtime and/or -atime,但 touch -a 只改访问时间时,-ctime也改了.
touch -m 改修改时间时,-ctime当然也改了.
好象还有别的很多东西可以令 -ctime 改变, 搞不清楚.
有什么方法可以显示 -mtime,atime,ctime 吗?
可以用 -ctime 来实现对目录的增量文件进行备份或 transfer 吗 ?
多谢!

没有什么工具显示,(可能是俺不知道)
把下面程序里的st_mtime换成st_ctime,或st_atime便可以得到你要的了.
#include
int
main (int argc, char **argv)
{
struct stat buf;
char date[80];
char fname[80];
printf("Enter filename (with full path) to check mtime : ");
scanf("%s",fname);
stat(fname, &buf);
printf ("mtime (in sec) of %s = %ld\n", fname, buf.st_mtime);
strcpy(date, ctime((time_t *)&(buf.st_mtime)));
printf ("mtime (in date) of %s = %s\n", fname, date);
}

至于文件备份,有什么不可以的么?

mtime ls -l 最近修改文件内容的时间
atime ls -lu 最近访问文件的时间
ctime ls -li 最近文件有所改变的状态 ,如文件修改,属性\属主 改变 ,节点 ,链接变化等 ,应该是不拘泥只是时间前后的改变

俺看了ls的帮助,以为只是按ctime或atime排序,显示的时间还是mtime.

仔细比较了一下,ayhan说的是对的.谢谢ayhan.

多谢 ahyan 提示 ! 我在 Solaris 上试过如下:
mtime 用 ls -l 看到
atime 用 ls -lu 看到
ctime 用 ls -lc 看到. (ls -li 只有 inode number)
摘书如下:
-c Uses time of last modification of the i-node (file
created, mode changed, and so forth) for sorting (-t)
or printing (-l or -n).
-u Uses time of last access instead of last modification
for sorting (with the -t option) or printing (with the
-l option).
-i For each file, prints the i-node number in the first
column of the report.

linux基础篇-sort 命令详解

转自 http://www.cnblogs.com/51linux/archive/2012/05/23/2515299.html

 

sort是在Linux里非常常用的一个命令,管排序的,集中精力,五分钟搞定sort,现在开始!

1 sort的工作原理

 

sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。

[rocrocket@rocrocket programming]$ cat seq.txt
banana
apple
pear
orange
[rocrocket@rocrocket programming]$ sort seq.txt
apple
banana
orange
pear

2 sort的-u选项

它的作用很简单,就是在输出行中去除重复行。

[rocrocket@rocrocket programming]$ cat seq.txt
banana
apple
pear
orange
pear
[rocrocket@rocrocket programming]$ sort seq.txt
apple
banana
orange
pear
pear
[rocrocket@rocrocket programming]$ sort -u seq.txt
apple
banana
orange
pear

pear由于重复被-u选项无情的删除了。

3 sort的-r选项

sort默认的排序方式是升序,如果想改成降序,就加个-r就搞定了。

[rocrocket@rocrocket programming]$ cat number.txt
1
3
5
2
4
[rocrocket@rocrocket programming]$ sort number.txt
1
2
3
4
5
[rocrocket@rocrocket programming]$ sort -r number.txt
5
4
3
2
1

4 sort的-o选项

由于sort默认是把结果输出到标准输出,所以需要用重定向才能将结果写入文件,形如sort filename > newfile。

但是,如果你想把排序结果输出到原文件中,用重定向可就不行了。

[rocrocket@rocrocket programming]$ sort -r number.txt > number.txt
[rocrocket@rocrocket programming]$ cat number.txt
[rocrocket@rocrocket programming]$
看,竟然将number清空了。

就在这个时候,-o选项出现了,它成功的解决了这个问题,让你放心的将结果写入原文件。这或许也是-o比重定向的唯一优势所在。

[rocrocket@rocrocket programming]$ cat number.txt
1
3
5
2
4
[rocrocket@rocrocket programming]$ sort -r number.txt -o number.txt
[rocrocket@rocrocket programming]$ cat number.txt
5
4
3
2
1

5 sort的-n选项

你有没有遇到过10比2小的情况。我反正遇到过。出现这种情况是由于排序程序将这些数字按字符来排序了,排序程序会先比较1和2,显然1小,所以就将10放在2前面喽。这也是sort的一贯作风。

我们如果想改变这种现状,就要使用-n选项,来告诉sort,“要以数值来排序”!

[rocrocket@rocrocket programming]$ cat number.txt
1
10
19
11
2
5
[rocrocket@rocrocket programming]$ sort number.txt
1
10
11
19
2
5
[rocrocket@rocrocket programming]$ sort -n number.txt
1
2
5
10
11
19

6 sort的-t选项和-k选项

如果有一个文件的内容是这样:

[rocrocket@rocrocket programming]$ cat facebook.txt
banana:30:5.5
apple:10:2.5
pear:90:2.3
orange:20:3.4

这个文件有三列,列与列之间用冒号隔开了,第一列表示水果类型,第二列表示水果数量,第三列表示水果价格。

那么我想以水果数量来排序,也就是以第二列来排序,如何利用sort实现?

幸好,sort提供了-t选项,后面可以设定间隔符。(是不是想起了cut和paste的-d选项,共鸣~~)

指定了间隔符之后,就可以用-k来指定列数了。

[rocrocket@rocrocket programming]$ sort -n -k 2 -t : facebook.txt
apple:10:2.5
orange:20:3.4
banana:30:5.5
pear:90:2.3

我们使用冒号作为间隔符,并针对第二列来进行数值升序排序,结果很令人满意。

7 其他的sort常用选项

-f会将小写字母都转换为大写字母来进行比较,亦即忽略大小写

-c会检查文件是否已排好序,如果乱序,则输出第一个乱序的行的相关信息,最后返回1

-C会检查文件是否已排好序,如果乱序,不输出内容,仅返回1

-M会以月份来排序,比如JAN小于FEB等等

-b会忽略每一行前面的所有空白部分,从第一个可见字符开始比较。

有时候学习脚本,你会发现sort命令后面跟了一堆类似-k1,2,或者-k1.2 -k3.4的东东,有些匪夷所思。今天,我们就来搞定它—-k选项!

1 准备素材

$ cat facebook.txt
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500

 

第一个域是公司名称,第二个域是公司人数,第三个域是员工平均工资。(除了公司名称,其他的别信,都瞎写的^_^)

2 我想让这个文件按公司的字母顺序排序,也就是按第一个域进行排序:(这个facebook.txt文件有三个域)

$ sort -t ‘ ‘ -k 1 facebook.txt
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500

看到了吧,就直接用-k 1设定就可以了。(其实此处并不严格,稍后你就会知道)

3 我想让facebook.txt按照公司人数排序

$ sort -n -t ‘ ‘ -k 2 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000

不用解释,我相信你能懂。

但是,此处出现了问题,那就是baidu和sohu的公司人数相同,都是100人,这个时候怎么办呢?按照默认规矩,是从第一个域开始进行升序排序,因此baidu排在了sohu前面。

4  我想让facebook.txt按照公司人数排序 ,人数相同的按照员工平均工资升序排序:

$ sort -n -t ‘ ‘ -k 2 -k 3 facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000

看,我们加了一个-k2 -k3就解决了问题。对滴,sort支持这种设定,就是说设定域排序的优先级,先以第2个域进行排序,如果相同,再以第3个域进行排序。(如果你愿意,可以一直这么写下去,设定很多个排序优先级)

5 我想让facebook.txt按照员工工资降序排序,如果员工人数相同的,则按照公司人数升序排序:(这个有点难度喽)

$ sort -n -t ‘ ‘ -k 3r -k 2 facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000

此处有使用了一些小技巧,你仔细看看,在-k 3后面偷偷加上了一个小写字母r。你想想,再结合我们上一篇文章,能得到答案么?揭晓:r和-r选项的作用是一样的,就是表示逆序。因为sort默认是按照升序排序的,所以此处需要加上r表示第三个域(员工平均工资)是按照降序排序。此处你还可以加上n,就表示对这个域进行排序时,要按照数值大小进行排序,举个例子吧:

$ sort -t ‘ ‘ -k 3nr -k 2n facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000

看,我们去掉了最前面的-n选项,而是将它加入到了每一个-k选项中了。

6 -k选项的具体语法格式

要继续往下深入的话,就不得不来点理论知识。你需要了解-k选项的语法格式,如下:

[ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]

这个语法格式可以被其中的逗号(“,”)分为两大部分,Start部分和End部分。

先给你灌输一个思想,那就是“如果不设定End部分,那么就认为End被设定为行尾”。这个概念很重要的,但往往你不会重视它。

Start部分也由三部分组成,其中的Modifier部分就是我们之前说过的类似n和r的选项部分。我们重点说说Start部分的FStart和C.Start。

C.Start也是可以省略的,省略的话就表示从本域的开头部分开始。之前例子中的-k 2和-k 3就是省略了C.Start的例子喽。

FStart.CStart,其中FStart就是表示使用的域,而CStart则表示在FStart域中从第几个字符开始算“排序首字符”。

同理,在End部分中,你可以设定FEnd.CEnd,如果你省略.CEnd,则表示结尾到“域尾”,即本域的最后一个字符。或者,如果你将CEnd设定为0(零),也是表示结尾到“域尾”。

7 突发奇想,从公司英文名称的第二个字母开始进行排序:

$ sort -t ‘ ‘ -k 1.2 facebook.txt
baidu 100 5000
sohu 100 4500
google 110 5000
guge 50 3000

看,我们使用了-k 1.2,这就表示对第一个域的第二个字符开始到本域的最后一个字符为止的字符串进行排序。你会发现baidu因为第二个字母是a而名列榜首。sohu和 google第二个字符都是o,但sohu的h在google的o前面,所以两者分别排在第二和第三。guge只能屈居第四了。

8 又突发奇想,,只针对公司英文名称的第二个字母进行排序,如果相同的按照员工工资进行降序排序:

$ sort -t ‘ ‘ -k 1.2,1.2 -k 3,3nr facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000

由于只对第二个字母进行排序,所以我们使用了-k 1.2,1.2的表示方式,表示我们“只”对第二个字母进行排序。(如果你问“我使用-k 1.2怎么不行?”,当然不行,因为你省略了End部分,这就意味着你将对从第二个字母起到本域最后一个字符为止的字符串进行排序)。对于员工工资进行排 序,我们也使用了-k 3,3,这是最准确的表述,表示我们“只”对本域进行排序,因为如果你省略了后面的3,就变成了我们“对第3个域开始到最后一个域位置的内容进行排序” 了。

9 在modifier部分还可以用到哪些选项?

可以用到b、d、f、i、n 或 r。

其中n和r你肯定已经很熟悉了。

b表示忽略本域的签到空白符号。

d表示对本域按照字典顺序排序(即,只考虑空白和字母)。

f表示对本域忽略大小写进行排序。

i表示忽略“不可打印字符”,只针对可打印字符进行排序。(有些ASCII就是不可打印字符,比如\a是报警,\b是退格,\n是换行,\r是回车等等)

10 思考思考关于-k和-u联合使用的例子:

$ cat facebook.txt
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500

这是最原始的facebook.txt文件。

$ sort -n -k 2 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000

$ sort -n -k 2 -u facebook.txt
guge 50 3000
baidu 100 5000
google 110 5000

当设定以公司员工域进行数值排序,然后加-u后,sohu一行就被删除了!原来-u只识别用-k设定的域,发现相同,就将后续相同的行都删除。

$ sort  -k 1 -u facebook.txt
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500

$ sort  -k 1.1,1.1 -u facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500

这个例子也同理,开头字符是g的guge就没有幸免于难。

$ sort -n -k 2 -k 3 -u facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000

咦!这里设置了两层排序优先级的情况下,使用-u就没有删除任何行。原来-u是会权衡所有-k选项,将都相同的才会删除,只要其中有一级不同都不会轻易删除的:)(不信,你可以自己加一行sina 100 4500试试看)

11 最诡异的排序:

$ sort -n -k 2.2,3.1 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000

以第二个域的第二个字符开始到第三个域的第一个字符结束的部分进行排序。

第一行,会提取0 3,第二行提取00 5,第三行提取00 4,第四行提取10 5。

又因为sort认为0小于00小于000小于0000….

因此0 3肯定是在第一个。10 5肯定是在最后一个。但为什么00 5却在00 4前面呢?(你可以自己做实验思考一下。)

答案揭晓:原来“跨域的设定是个假象”,sort只会比较第二个域的第二个字符到第二个域的最后一个字符的部分,而不会把第三个域的开头字符纳入比较范围。当发现00和00相同时,sort就会自动比较第一个域去了。当然baidu在sohu前面了。用一个范例即可证实:

$ sort -n -k 2.2,3.1 -k 1,1r facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000

12 有时候在sort命令后会看到+1 -2这些符号,这是什么东东?

关于这种语法,最新的sort是这么进行解释的:

On older systems, `sort’ supports an obsolete origin-zero syntax `+POS1 [-POS2]‘ for specifying sort keys.  POSIX 1003.1-2001 (*note Standards conformance::) does not allow this; use `-k’ instead.

原来,这种古老的表示方式已经被淘汰了,以后可以理直气壮的鄙视使用这种表示方法的脚本喽!

(为了防止古老脚本的存在,在这再说一下这种表示方法,加号表示Start部分,减号表示End部分。最最重要的一点是,这种方式方法是从0开始计数的,以前所说的第一个域,在此被表示为第0个域。以前的第2个字符,在此表示为第1个字符。明白?)

spring4.x+json+中文乱码解决

基本配置:
1,在配置文件web.xml中设置统一设置过滤字符串
        <filter>
              <filter-name>encodingFilter</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>encodingFilter</filter-name>
              <url-pattern>/*</url-pattern>
         </filter-mapping>
2,在applicationContent.xml中配置返回json编码
        <bean id="multipartResolver"
  class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
 <bean
  class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
  <property name="messageConverters">
   <list>
    <bean
     class="org.springframework.http.converter.StringHttpMessageConverter">
     <property name="supportedMediaTypes">
      <list>
       <value>text/plain;charset=UTF-8</value>
       <value>text/html;charset=UTF-8</value>
      </list>
     </property>
    </bean>
    <bean
     class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
     <property name="supportedMediaTypes">
      <list>
       <value>text/plain;charset=UTF-8</value>
       <value>application/json;charset=UTF-8</value>
      </list>
     </property>
    </bean>
   </list>
  </property>
 </bean>
 
3,在response返回流中,设置响应头编码格式,统一为 UTF-8
       response.setHeader("Content-type", "text/html;charset=UTF-8");
       response.setCharacterEncoding("UTF-8");
4,在tomcat中配置文件中server.xml中<connector>节点,添加 URIEncoding="UTF-8"
 
 
第一种解决方案:
        在@RequestMapping(value="/index" ,produces = "text/html;charset=UTF-8")
 在使用public Map<String,Object) index(){} 这样的方法时,一定要写这样的注解才可以保持中文不乱码。

但是这种写法每个都需要硬编码 ,可以使用第二种方案。
 
第二种解决方案:
<!-- spring4.x json中文乱码处理,这一句一定要放在context:compent-scan前面 -->
 <mvc:annotation-driven>
  <mvc:message-converters>
   <bean class="org.springframework.http.converter.StringHttpMessageConverter">
    <property name="supportedMediaTypes">
     <list>
      <value>text/plain;charset=UTF-8</value>
      <value>text/html;charset=UTF-8</value>
     </list>
    </property>
   </bean>
  </mvc:message-converters>
 </mvc:annotation-driven>

Access-Control-Allow-Origin donot allow-----liunx服务器-tomcat跨域允许访问

上传文件,有时候需要跨二级域名访问,因为安全策略,需要做一些策略的调整。比如tomcat或者Nginx又或者代码。

1,tomcat 目录 conf/web.xml中,

最前面添加。
<filter>
        <filter-name>CorsFilter</filter-name>
        <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
        <init-param>
            <param-name>cors.allowed.methods</param-name>
            <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
        </init-param>
        <init-param>
            <param-name>cors.allowed.headers</param-name>
            <param-value>Access-Control-Allow-Origin,Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
        </init-param>
        <async-supported>true</async-supported>
    </filter>
    <filter-mapping>
        <filter-name>CorsFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
 
2,nginx 支持跨域访问
     2.1 在nginx.conf 
        http{
             add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Headers X-Requested-With;
            add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
        }
    2.1 在子域名访问域名下
    
     location / {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Credentials' 'true';
            add_header 'Access-Control-Allow-Methods' 'POST,GET';
                proxy_pass http://file.bdbvip.com;
                proxy_redirect     off;
                proxy_set_header   Host             $host;
                proxy_set_header   X-Real-IP        $remote_addr;
                proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
 
       }
3,代码头部申明

//response.setHeader("Access-Control-Allow-Origin", "blog.xuahua.com,cus.xuahua.com"); 仅允许指定的二级域名可以跨域
response.setHeader("Access-Control-Allow-Origin", "*"); //允许所有的
response.setHeader("Access-Control-Allow-Methods","POST"); //指定请求方法
response.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With,Content-Type,Accept");

liunx基础篇-文本对齐(vim技巧)

1,在vim文本编辑器中,

esc 退出编辑模式-->gg 快速定位至文本开头 --> 按下v键,进入虚拟编辑-->shift+g 全选文本 --> 按下 = ;文本对齐。

 

公告

喧哗博客--繁华过后的沉寂--技术经验分享^-^
Copyright (c) 2009-2019, b3log.org & hacpai.com