不知为什么 原来的PKCS7Padding总报错加jce什么的jar也都不好使换jdk也不行 只好用这个PKCS5Padding编码了

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
package com.util;
import java.security.SecureRandom;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class DESMessageEncryptor {
public String decryptMessage(String encryptedText,String decryptKey) {
// TODO Auto-generated method stub
try {
byte[] password = decryptKey.getBytes();
// System.out.println(new BASE64Encoder().encode(password));
Security.addProvider(new com.sun.crypto.provider.SunJCE());
DESKeySpec keySpec = new DESKeySpec(password);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(keySpec);
byte[] iv = new sun.misc.BASE64Decoder()
.decodeBuffer("t4JPbY+rXgk=");
javax.crypto.spec.IvParameterSpec ips = new javax.crypto.spec.IvParameterSpec(
iv);
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, ips);
// System.out.println("IV1: ");
// System.out.println(new BASE64Encoder().encode(cipher.getIV()));
return new String(cipher.doFinal(new BASE64Decoder().decodeBuffer(encryptedText)));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public String encryptMessage(String plainText,String encryptKey) {
// TODO Auto-generated method stub
try {
byte[] password = encryptKey.getBytes();
// System.out.println(new BASE64Encoder().encode(password));
Security.addProvider(new com.sun.crypto.provider.SunJCE());
DESKeySpec keySpec = new DESKeySpec(password);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(keySpec);
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
byte[] iv = new sun.misc.BASE64Decoder()
.decodeBuffer("t4JPbY+rXgk=");
javax.crypto.spec.IvParameterSpec ips = new javax.crypto.spec.IvParameterSpec(
iv);
cipher.init(Cipher.ENCRYPT_MODE, key, ips);
// System.out.println("IV0: ");
// System.out.println(new BASE64Encoder().encode(cipher.getIV()));
byte[] cipherText = cipher.doFinal(plainText.getBytes());
return new BASE64Encoder().encode(cipherText);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

调用函数第二个参数是key

1
2
3
4
5
DESMessageEncryptor des=new DESMessageEncryptor(); String
ename=des.encryptMessage("18500238217","47f8d411");
System.out.println(ename);
System.out.println(des.decryptMessage(ename,"47f8d411"));

还有一个BASE64.java

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package com.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class BASE64 {
private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
.toCharArray();
/**
* data[]锟斤拷锟叫憋拷锟斤拷
*
* @param data
* @return
*/
public static String encode(byte[] data) {
int start = 0;
int len = data.length;
StringBuffer buf = new StringBuffer(data.length * 3 / 2);
int end = len - 3;
int i = start;
int n = 0;
while (i <= end) {
int d = (((data[i]) & 0x0ff) << 16)
| (((data[i + 1]) & 0x0ff) << 8)
| ((data[i + 2]) & 0x0ff);
buf.append(legalChars[(d >> 18) & 63]);
buf.append(legalChars[(d >> 12) & 63]);
buf.append(legalChars[(d >> 6) & 63]);
buf.append(legalChars[d & 63]);
i += 3;
if (n++ >= 14) {
n = 0;
buf.append(" ");
}
}
if (i == start + len - 2) {
int d = (((data[i]) & 0x0ff) << 16)
| (((data[i + 1]) & 255) << 8);
buf.append(legalChars[(d >> 18) & 63]);
buf.append(legalChars[(d >> 12) & 63]);
buf.append(legalChars[(d >> 6) & 63]);
buf.append("=");
} else if (i == start + len - 1) {
int d = ((data[i]) & 0x0ff) << 16;
buf.append(legalChars[(d >> 18) & 63]);
buf.append(legalChars[(d >> 12) & 63]);
buf.append("==");
}
return buf.toString();
}
private static int decode(char c) {
if (c >= 'A' && c <= 'Z')
return (c) - 65;
else if (c >= 'a' && c <= 'z')
return (c) - 97 + 26;
else if (c >= '0' && c <= '9')
return (c) - 48 + 26 + 26;
else
switch (c) {
case '+':
return 62;
case '/':
return 63;
case '=':
return 0;
default:
throw new RuntimeException("unexpected code: " + c);
}
}
/**
* Decodes the given Base64 encoded String to a new byte array. The byte
* array holding the decoded data is returned.
*/
public static byte[] decode(String s) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
decode(s, bos);
} catch (IOException e) {
throw new RuntimeException();
}
byte[] decodedBytes = bos.toByteArray();
try {
bos.close();
bos = null;
} catch (IOException ex) {
System.err.println("Error while decoding BASE64: " + ex.toString());
}
return decodedBytes;
}
private static void decode(String s, OutputStream os) throws IOException {
int i = 0;
int len = s.length();
while (true) {
while (i < len && s.charAt(i) <= ' ')
i++;
if (i == len)
break;
int tri = (decode(s.charAt(i)) << 18)
+ (decode(s.charAt(i + 1)) << 12)
+ (decode(s.charAt(i + 2)) << 6)
+ (decode(s.charAt(i + 3)));
os.write((tri >> 16) & 255);
if (s.charAt(i + 2) == '=')
break;
os.write((tri >> 8) & 255);
if (s.charAt(i + 3) == '=')
break;
os.write(tri & 255);
i += 4;
}
}
}

git常用命令

生成不同的key

ssh-keygen -t rsa -f ~/.ssh/id_rsa.zxs -C "Key for zxs"```
1
2
3
4
5
```ps git push -f ```强制提交覆盖
查看控制文件内容
```ps git config --list

创建全局

config --global user.emal 287424494@qq.com
1
git config --global user.name "zxs"

查看分支:

git branch```
1
2
创建分支:```ps git branch <name>

切换分支:

git checkout ```
1
2
创建+切换分支:```ps git checkout -b <name>

合并某分支到当前分支:

git merge ```
1
2
删除分支:```ps git branch -d <name>

分支有冲突时手动改冲突文件 git status可以查看 然后提交 完事

bug分支
当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场

新feature,最好新建一个分支;

如果要丢弃一个没有被合并过的分支,可以通过git branch -D 强行删除。

先git pull再push

设置本地dev和远程origin/dev的链接

$ git branch --set-upstream dev origin/dev```
1
2
3
查看当前库状态
```ps $ git status

$ git diff HEAD -- readme.txt``` 有什么不同
1
2
3
4
5
版本回退
```ps $git log
commit ea34578d5496d7dd233c827ed32a8cd576c5ee85
Author: Michael Liao <askxuefeng@gmail.com>

上一版本

$ git reset --hard HEAD^
1
$ git reset --hard 3628164

记录每一次命令

$ git reflog```
1
2
3
4
5
6
7
8
场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file。
场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。
删除
```ps git rm test.txt

或者

git checkout -- test.txt```
1
2
3
4
5
6
7
8
9
10
11
[远程操作]
显示配置了哪些远程服务器: ```ps $ git remote ```
显示配置了哪些远程服务器,同时显示URL: ```ps $ git remote -v ```
显示远程 详细信息: ```ps $ git remote show origin

修改远程标识名字:

$ git remote rename pb paul```
1
2
删除远程配置: ```ps $ git remote rm paul

增加一个远程配置:

$ git remote add pb git://github.com/paulboone/ticgit.git```
1
2
3
获取: ```ps $ git fetch pb

或者: ps $ git fetch origin

注意:

1)该分支可以用 pb/master 访问

2)获取到本地之后,并未自动merge,也未改变本地任何东西。

推送: ps $ git push origin master (-u 是第一次推送分支所有内容)

注意,推送的条件:

1)从该远程克隆;

2)有写权限;

3)从上次克隆(或推送)至今没有更新,如果有更新,则你要先 fetch 然后再push。

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
<!-- quartz相关简单配置-->
<!-- 1 配置任务对象 Backup -->
<bean id="bu" class="com.util.Backup"></bean>
<!-- 2 配置任务调度 MethodInvokingJobDetailFactoryBean
setTargetObject(Object obj) 设置具体的任务对象
setTargetMethod(String method) 设置具体的任务方法
-->
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
p:targetObject-ref="bu"
p:targetMethod="backup"/>
<!-- 配置该任务执行的周期/时间 CronTriggerFactoryBean
setJobDetail(JobDetail jd)
setCronExpression(String expression)
通过定义一个表达式,设置执行的时间
七部分 : 秒分时月日期 月 周日期 年[可选]
0-59 0-59 0-23 (1-31)(1-12)(1-7) [1970-]
-->
<bean id="trigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"
p:jobDetail-ref="jobDetail"
p:cronExpression="0 0/2 * * * ?"/>
<!-- 配置任务计划 SchedulerFactoryBeantimer.scheduler(timertask , date)
setTriggers(Trigger[] triggers)
-->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="trigger"/>
</list>
</property>
</bean>

com.util.Backup 这个就是一个类 里面有一个方法backup

安装完配置文件在

/usr/local/nginx/conf

更详细的配置请参阅

http://blog.csdn.net/shirdrn/article/details/6845520

记得建个代理文件proxy.conf

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
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;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;

首先要查看nginx的status需要在编译nginx的时候加上–with-http_stub_status_module

然后在nginx.conf的server段中定义类似如下内容:

1
2
3
4
5
6
location /status {
stub_status on;
access_log off;
allow SOME.IP.ADD.RESS;
deny all;
}

访问http://ip.ad.dr.ess/status

退出nginux

kill –QUIT nginx主进程号

重启

kill –HUP nginx主进程号

日志切割

日志存放路径 logs_path=“/data1/log”

脚本:

1
2
3
4
5
mkdir –p $(logs_path)$(date –d “yesterday” +”%Y”)/$(date –d “yesterday” +”%m”)/
mv $(logs_path)access.log $(logs_path)$(date –d “yesterday” +”%Y”)/$(date –d “yesterday” +”%m”)/access_$(date –d “yesterday” +”%Y%m%d”).log
kill –USR1 ‘cat /usr/local/webserver/nginx/nginx.pid’

可以利用crontab来定时执行脚本先mv到2009.10.13.log在kil –USR1

crontab –e设置时间

1
00 00 *** /bin/bash /usr/local/webserver/nginx/sbin/cut_nginx_log.sh

在nginx集群内设置防盗链

1
2
3
4
5
6
7
8
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
valid_referers none blocked *.tappal.com tappal.com;
if ($invalid_referer) {
return 404;
}
expires 30d;
}

在java程序内
设置防盗链的filter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
String referer = req.getHeader("referer");
if(null != referer && referer.trim().startsWith("http://localhost:8080/baidu")){
System.out.println("正常页面请求");
chain.doFilter(req, resp);
}else{
System.out.println("盗链");
req.getRequestDispatcher("/html/error.html").forward(req, resp);
}
}

最核心的其实也就是这句

String referer = req.getHeader("referer");```
1
2
3
4
5
6
7
再来看看绕过防盗链的措施
使用iframe方法
```javascript
<script>window.sc="<img src='http://cdn.archdaily.net/wp-content/uploads/2011/06/1309476244-elicium-rai-01-528x351.jpg?"+Math.random()+"'>";</script>
<iframe id="imiframe" src="javascript:parent.sc" style="border:none; overflow: hidden;" scrolling="no" frameborder="0" onload="javascript:var x=document.getElementById('imiframe').contentWindow.document.images[0];this.width=x.width+10;this.height=x.height+10;"></iframe>

使用代码加入header里的refer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def getHttpFile(address,filename){
def f = new File(filename)
if(f.exists()){
return;
}
def file = new FileOutputStream(filename)
def out = new BufferedOutputStream(file)
println 'Download file: ' + filename
def url = new URL(address)
def urlConn = url.openConnection()
urlConn.setRequestProperty('Referer',xxxxxx') //xxx为要访问的目标网站
urlConn.connect()
out << urlConn.getInputStream()
println 'Download over: ' + filename
out.close()
}

都是从header里做手脚

利用aop统一缓存各层查询出来的数据,还有输出对象转JSON支持(@ResponseBody在要返回json串的方法上写这个注解)

先放主要的环绕通知java类

此处 需要规定所有要处理方法的参数(在下面application.xml里有说明)必须是一个序列化的实体类(implements Serializable ,不序列化 memcached不让你存哦)和一个HttpServletRequest request对象

memcached的key是访问的url地址+方法名 然后md5加密

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
79
80
81
82
83
84
85
86
package com.interceptor;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import net.rubyeye.xmemcached.MemcachedClient;
public class MemcachedInterceptor {
@Autowired
MemcachedClient memcachedClient;
public Object aronud(ProceedingJoinPoint call) throws Throwable {
Object[] args = call.getArgs();
HttpServletRequest request = null;
//通过分析aop监听参数分析出request等信息
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof HttpServletRequest) {
request = (HttpServletRequest) args[i];
}
}
StringBuffer url= request.getRequestURL();
String methodName=call.getSignature().getName();
String key=getMD5Str(url+methodName);
Object obj= memcachedClient.get(key);
if (obj==null) {
obj =new Object();
try {
obj = call.proceed();
if (obj != null) {
memcachedClient.set(key,5*60*1000,obj);
}
} catch (Throwable e) {
e.printStackTrace();
}
}
return obj;
}
/**
* MD5 加密
*/
private String getMD5Str(String str) {
MessageDigest messageDigest = null;
try {
messageDigest = MessageDigest.getInstance("MD5");
messageDigest.reset();
messageDigest.update(str.getBytes("UTF-8"));
} catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgorithmException caught!");
System.exit(-1);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
byte[] byteArray = messageDigest.digest();
StringBuffer md5StrBuff = new StringBuffer();
for (int i = 0; i < byteArray.length; i++) {
if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
else
md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
}
return md5StrBuff.toString();
}
}

在放上application.xml配置文件

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:property-placeholder location="classpath:jdbc.properties" />
<bean id="stringConverter" class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- 输出对象转JSON支持 -->
<bean id="jsonConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="stringConverter"/>
<ref bean="jsonConverter" />
</list>
</property>
</bean>
<!-- 扫描类包,将标注Spring注解的类自动转化Bean,同时完成Bean的注入 -->
<context:component-scan base-package="com.controller" />
<context:component-scan base-package="com.service" />
<context:component-scan base-package="com.dao" />
<!-- 配置数据源 destroy-method="close"-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass">
<value>${jdbc.driverClassName}</value>
</property>
<property name="jdbcUrl">
<value>${jdbc.url}</value>
</property>
<property name="user">
<value>${jdbc.username}</value>
</property>
<property name="password">
<value>${jdbc.password}</value>
</property>
<!--连接池中保留的最小连接数。 -->
<property name="minPoolSize">
<value>5</value>
</property>
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize">
<value>30</value>
</property>
<!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize">
<value>10</value>
</property>
<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime">
<value>60</value>
</property>
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement">
<value>5</value>
</property>
<!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements 属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。
如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0 -->
<property name="maxStatements">
<value>0</value>
</property>
<!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
<property name="idleConnectionTestPeriod">
<value>60</value>
</property>
<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="acquireRetryAttempts">
<value>30</value>
</property>
<!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试
获取连接失败后该数据源将申明已断开并永久关闭。Default: false -->
<property name="breakAfterAcquireFailure">
<value>true</value>
</property>
<!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的 时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable
等方法来提升连接测试的性能。Default: false -->
<property name="testConnectionOnCheckout">
<value>false</value>
</property>
<property name="automaticTestTable">
<value>true</value>
</property>
</bean>
<!-- 配置Jdbc模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource" />
<!-- 通过AOP配置提供事务增强,让controller包下所有Bean的所有方法拥有事务 -->
<aop:config proxy-target-class="true">
<aop:pointcut id="serviceMethod"
expression=" execution(* com.controller.*..*(..))" />
<aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<!-- 访问数据库前,查询MEMCACHED缓存服务器 -->
<bean id="memcachedInterceptor" class="com.interceptor.MemcachedInterceptor"></bean>
<aop:config>
<aop:aspect id="memcachedAspect" ref="memcachedInterceptor">
<aop:pointcut expression="execution(* select*(com.model.BuildingList,javax.servlet.http.HttpServletRequest)) and args(com.model.BuildingList,javax.servlet.http.HttpServletRequest)"
id="memcachedPointCut"/>
<aop:aroundpointcut-ref="memcachedPointCut" method="aronud"/>
</aop:aspect>
</aop:config>
<!-- 官方文档地址 http://code.google.com/p/xmemcached/wiki/Spring_Integration -->
<bean
id="memcachedClientBuilder"
class="net.rubyeye.xmemcached.XMemcachedClientBuilder"
p:connectionPoolSize="20"
p:failureMode="true">
<constructor-arg>
<list>
<bean class="java.net.InetSocketAddress">
<constructor-arg>
<value>192.168.0.121</value>
</constructor-arg>
<constructor-arg>
<value>11211</value>
</constructor-arg>
</bean>
</list>
</constructor-arg>
<constructor-arg>
<list>
<value>1</value>
</list>
</constructor-arg>
<property name="commandFactory">
<bean class="net.rubyeye.xmemcached.command.TextCommandFactory" />
</property>
<property name="sessionLocator">
<bean class="net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator" />
</property>
<property name="transcoder">
<bean class="net.rubyeye.xmemcached.transcoders.SerializingTranscoder" />
</property>
</bean>
<bean
id="memcachedClient"
factory-bean="memcachedClientBuilder"
factory-method="build"
destroy-method="shutdown" />
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
p:defaultEncoding="utf-8"/>
</beans>

在springmvc里可以这么在controller里写方法,这样就会被aop拦截 处理memcache

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@RequestMapping("/buildingList")
@ResponseBody
public Map selectBuildingList(BuildingList bl, HttpServletRequest request) {
Map<String, Object> mc = new HashMap<String, Object>();
mc.put("request", "buildingList");
String city = bl.getCity();
String area = bl.getArea();
String price_limit = bl.getPrice_limit();
String price_lower_limit = bl.getPrice_lower_limit();
String type = bl.getType();
String page = bl.getPage();
String count = bl.getCount();
String start_id = bl.getStart_id();
if (city == null || city.equals("")) {
mc.put("status", 101);
return mc;
}
Map<String, Object> map = buildingService.buildingList(city, area,
price_limit, price_lower_limit, type, page,
count, start_id);
mc.putAll(map);
return mc;
}

最后贴出实体类

package com.model;
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import java.io.Serializable;
public class BuildingList implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String city;
private String area;
private String price_limit;
private String price_lower_limit;
private String type;
private String page;
private String count;
private String start_id;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
public String getPrice_limit() {
return price_limit;
}
public void setPrice_limit(String price_limit) {
this.price_limit = price_limit;
}
public String getPrice_lower_limit() {
return price_lower_limit;
}
public void setPrice_lower_limit(String price_lower_limit) {
this.price_lower_limit = price_lower_limit;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getPage() {
return page;
}
public void setPage(String page) {
this.page = page;
}
public String getCount() {
return count;
}
public void setCount(String count) {
this.count = count;
}
public String getStart_id() {
return start_id;
}
public void setStart_id(String start_id) {
this.start_id = start_id;
}
//接受返回json的值
private int id;
private String building_name;
private String building_url;
private String average_price;
private String house_count_info;
private String building_address;
private String preferential_info;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getBuilding_name() {
return building_name;
}
public void setBuilding_name(String building_name) {
this.building_name = building_name;
}
public String getBuilding_url() {
return building_url;
}
public void setBuilding_url(String building_url) {
this.building_url = building_url;
}
public String getAverage_price() {
return average_price;
}
public void setAverage_price(String average_price) {
this.average_price = average_price;
}
public String getHouse_count_info() {
return house_count_info;
}
public void setHouse_count_info(String house_count_info) {
this.house_count_info = house_count_info;
}
public String getBuilding_address() {
return building_address;
}
public void setBuilding_address(String building_address) {
this.building_address = building_address;
}
public String getPreferential_info() {
return preferential_info;
}
public void setPreferential_info(String preferential_info) {
this.preferential_info = preferential_info;
}
}

好了 这样就可以跑起来啦别忘了

把jar包倒到程序里。。。。

摘要 照葫芦画瓢 从网上按部就班的实现了spring与redis的集成,这里分享下注意事项

首先需要安装redis

乌班图的安装 apt-get install redis-server

然后是修改 /etc/redis/redis.conf 文件 修改里面的 bind 127.0.0.1 改成你的外网ip这样 外网才能访问

然后/etc/init.d/redis-server restart

客户端与spring集成 需要一下jar包

http://yun.baidu.com/share/link?shareid=1006564976&uk=958682606

下载后配置applicationContext.xml spring的配置文件

加入(注意 sentinels的地址是你客户端的地址 不要与jedisConnFactory中的服务器端地址搞混)

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
class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
<property name="master">
<bean class="org.springframework.data.redis.connection.RedisNode">
<property name="name" value="mymaster"></property>
</bean>
</property>
<property name="sentinels">
<set>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg index="0" value="192.168.1.18" />
<constructor-arg index="1" value="7031" />
</bean>
<!--<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg index="0" value="10.6.1**.**6" />
<constructor-arg index="1" value="7031" />
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg index="0" value="10.6.1**.**1" />
<constructor-arg index="1" value="7031" />
</bean> -->
</set>
</property>
</bean>
<bean id="jedisConnFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="115.XX.XXX.XX"/>
<property name="port" value="6379"/>
<property name="usePool" value="false"/>
<constructor-arg ref="redisSentinelConfiguration"/>
</bean>
<bean id="RedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnFactory" />
</bean>

然后再程序中可以这样调用

@Autowired
1
2
3
4
5
6
7
8
9
10
11
private RedisTemplate<String, Object> redisTemplate;
@RequestMapping("/selecttest")
@ResponseBody
public String selecttest(HttpServletRequest request) {
redisTemplate.opsForValue().set("name", "周小帅");
System.out.println(redisTemplate.opsForValue().get("name"));
return redisTemplate.opsForValue().get("name");
}

感觉和memached的集成差不多 但是 听说redis的功能要强大的许多,,,继续研究中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public bool sendImg(){
string title = string.Format("这是一张图片");
string email = "*********@hotmail.com";
Bitmap bmp = new Bitmap("1.jpg");
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] arr = new byte[ms.Length];
ms.Position = 0;
ms.Read(arr, 0, (int)ms.Length);
ms.Close();
String strEncoded = Convert.ToBase64String(arr);
string body = "<Body style=\"margin: 10px\"><Div><Img src=\"data:image/png;base64," + strEncoded + "\"> </Img></Div></Body> ";
bool flag= EmailHelper.SendImgToEmail(email,title,body);
return flag;
}