Spring设计安全的Restful接口

设计安全的Restful接口:无用户交互状态的接口安全设计。我们需要实现UR拦截请求拦截,接口接入授权验证和请求验重。本文中不涉及任何用户校验。

设计原理

1.UR拦截请求拦截:通过URL进行拦截过滤;

2.接入授权验证:验证请求头Token;

3.请求验重:验证请求序列Sequence;

接口设计文档请参考:WMS系统对外开放接口设计文档-V.1.0.docx

注:文档禁用于商业用途!

安全过滤器

  1. package com.wlyd.fmcgwms.util.security;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5.   
  6. import javax.servlet.Filter;  
  7. import javax.servlet.FilterChain;  
  8. import javax.servlet.FilterConfig;  
  9. import javax.servlet.ServletException;  
  10. import javax.servlet.ServletRequest;  
  11. import javax.servlet.ServletResponse;  
  12. import javax.servlet.http.HttpServletRequest;  
  13. import javax.servlet.http.HttpServletResponse;  
  14.   
  15. import com.alibaba.fastjson.JSONObject;  
  16. import com.wlyd.fmcgwms.util.Log;  
  17. import com.wlyd.fmcgwms.util.SAASTokenManager;  
  18. import com.wlyd.fmcgwms.util.StaticProperty;  
  19. import com.wlyd.fmcgwms.util.api.RSAUtils;  
  20. import com.wlyd.fmcgwms.util.ehcache.EhcacheUtil;  
  21. import com.wlyd.fmcgwms.util.sysinit.InitSysProperties;  
  22. /** 
  23.  * 接口安全过滤器 
  24.  *  
  25.  * @package com.wlyd.fmcgwms.util.security.SecurityFilter 
  26.  * @date   2017年3月15日  下午1:57:18 
  27.  * @author pengjunlin 
  28.  * @comment    
  29.  * @update 
  30.  */  
  31. public class SecurityFilter implements Filter {  
  32.       
  33.     private static String API_ISENABLE ;// WMS是否开通对外接口  
  34.       
  35.     private static String API_PALTFORM;// WMS开放的平台编码  
  36.       
  37.     private static String API_MEMBERCODE;//WMS开放的服务商编码  
  38.       
  39.     private static String publicKey;// 公钥  
  40.       
  41.     private static String privateKey;// 私钥  
  42.       
  43.   
  44.     @Override  
  45.     public void destroy() {  
  46.         // TODO Auto-generated method stub  
  47.     }  
  48.       
  49.     /** 
  50.      * 验证配置是否规范 
  51.      *  
  52.      * @MethodName: isConfiged  
  53.      * @Description:  
  54.      * @param platformCode 
  55.      * @param memberCode 
  56.      * @return 
  57.      * @throws 
  58.      */  
  59.     private boolean isConfiged(String platformCode,String memberCode){  
  60.         if(API_ISENABLE==null||!API_ISENABLE.equals("true")){  
  61.             return false;  
  62.         }  
  63.         if(API_PALTFORM==null||platformCode==null||!platformCode.equals(API_PALTFORM)){  
  64.             return false;  
  65.         }  
  66.         if (API_MEMBERCODE==null||memberCode == null||! memberCode.equals(API_MEMBERCODE)) {  
  67.             return false;  
  68.         }  
  69.         return true;  
  70.     }  
  71.       
  72.     /** 
  73.      * 验证token是否有效 
  74.      *  
  75.      * @MethodName: validateToken  
  76.      * @Description:  
  77.      * @param token 
  78.      * @return 
  79.      * @throws 
  80.      */  
  81.     private boolean validateToken(String token){  
  82.         if(token==null||token.equals("")){  
  83.             return false;  
  84.         }  
  85.         String params[]=SAASTokenManager.decryptToken(privateKey, token, "&");  
  86.         if(params==null||params.length<3){  
  87.             return false;  
  88.         }  
  89.         long now=System.currentTimeMillis();  
  90.         // Token超时验证20s  
  91.         long seconds=(now-Long.valueOf(params[2]))/1000;  
  92.         if(!API_PALTFORM.equals(params[0])||!API_MEMBERCODE.equals(params[1])||seconds>20){  
  93.             return false;  
  94.         }  
  95.         return true;  
  96.     }  
  97.       
  98.     /** 
  99.      * 验证请求是否重复 
  100.      *  
  101.      * @MethodName: validateSequece  
  102.      * @Description:  
  103.      * @param sequence 
  104.      * @return 
  105.      * @throws 
  106.      */  
  107.     public boolean validateSequece(String sequence){  
  108.         if(sequence==null||sequence.equals("")){  
  109.             return false;  
  110.         }  
  111.         String requestSequence=(String) EhcacheUtil.get(StaticProperty.REQUESTCACHE, sequence);  
  112.         // 请求序列相同验证失败  
  113.         if(requestSequence!=null&&sequence.equals(requestSequence)){  
  114.             return false;  
  115.         }  
  116.         return true;  
  117.     }  
  118.   
  119.     @Override  
  120.     public void doFilter(ServletRequest request, ServletResponse response,  
  121.             FilterChain chain) throws IOException, ServletException {  
  122.         PrintWriter out = null;  
  123.         HttpServletRequest req = (HttpServletRequest) request;  
  124.         HttpServletResponse res = (HttpServletResponse) response;  
  125.         String platformCode = req.getHeader("PlatformCode");  
  126.         String memberCode = req.getHeader("MemberCode");  
  127.         String token = req.getHeader("Token");  
  128.         String sequence = req.getHeader("Sequence");  
  129.         //String path = req.getServletPath();  
  130.         try {  
  131.             byte [] bytes=SAASTokenManager.generateBytesToken(publicKey, platformCode, memberCode,"&");  
  132.             token = RSAUtils.bytesToString(bytes);  
  133.         } catch (Exception e1) {  
  134.             e1.printStackTrace();  
  135.         }  
  136.           
  137.         // 验证接口是否配置正确   
  138.         if(!isConfiged(platformCode, memberCode)){  
  139.             JSONObject json = new JSONObject();  
  140.             json.put("IsSuccess""false");  
  141.             json.put("OperationDesc""API parameters are not configed right! ");  
  142.             json.put("ResultCode", ResultCode.OPEN_API_CONFIG_ERROR);  
  143.             try {  
  144.                 out = res.getWriter();  
  145.                 out.write(json.toJSONString());  
  146.             } catch (Exception e) {  
  147.                 e.printStackTrace();  
  148.             }  
  149.             return;  
  150.         }  
  151.           
  152.         // 验证Token是否合法  
  153.         if(!validateToken(token)){  
  154.             JSONObject json = new JSONObject();  
  155.             json.put("IsSuccess""false");  
  156.             json.put("OperationDesc""Unauthorized:Token is invalid!");  
  157.             json.put("ResultCode", ResultCode.OPEN_API_TOKEN_INVALID);  
  158.             try {  
  159.                 out = res.getWriter();  
  160.                 out.write(json.toJSONString());  
  161.             } catch (Exception e) {  
  162.                 e.printStackTrace();  
  163.             }  
  164.             return;  
  165.         }  
  166.           
  167.         // 验证Sequence是否合法  
  168.         if(!validateSequece(sequence)){  
  169.             JSONObject json = new JSONObject();  
  170.             json.put("IsSuccess""false");  
  171.             json.put("OperationDesc""Refused:request API too frequently!");  
  172.             json.put("ResultCode", ResultCode.OPEN_API_REQUEST_REQUENTLY);  
  173.             try {  
  174.                 out = res.getWriter();  
  175.                 out.write(json.toJSONString());  
  176.             } catch (Exception e) {  
  177.                 e.printStackTrace();  
  178.             }  
  179.             return;  
  180.         }  
  181.   
  182.         chain.doFilter(request, response);  
  183.   
  184.     }  
  185.   
  186.     @Override  
  187.     public void init(FilterConfig arg0) throws ServletException {  
  188.         Log.getLogger(getClass()).info(">>>SecurityFilter invoke init method。。。。。。。。。START!");   
  189.         API_ISENABLE = InitSysProperties.getLowerCaseFromEhcache(StaticProperty.WMS_OPEN_API_ISENABLE);  
  190.         API_PALTFORM = InitSysProperties.getUpperCaseFromEhcache(StaticProperty.WMS_OPEN_API_PLATFORM);  
  191.         API_MEMBERCODE = InitSysProperties.getUpperCaseFromEhcache(StaticProperty.WMS_OPEN_API_MEMBERCODE);  
  192.         publicKey=EhcacheUtil.get(StaticProperty.WMS_OPEN_API_RSA_PUBLIC_KEY).toString();  
  193.         privateKey=EhcacheUtil.get(StaticProperty.WMS_OPEN_API_RSA_PRIVATE_KEY).toString();  
  194.         Log.getLogger(getClass()).info(">>>SecurityFilter invoke init method。。。。。。。。。SUCCESS!");   
  195.     }  
  196.   
  197. }  
package com.wlyd.fmcgwms.util.security;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
import com.wlyd.fmcgwms.util.Log;
import com.wlyd.fmcgwms.util.SAASTokenManager;
import com.wlyd.fmcgwms.util.StaticProperty;
import com.wlyd.fmcgwms.util.api.RSAUtils;
import com.wlyd.fmcgwms.util.ehcache.EhcacheUtil;
import com.wlyd.fmcgwms.util.sysinit.InitSysProperties;
/**
 * 接口安全过滤器
 * 
 * @package com.wlyd.fmcgwms.util.security.SecurityFilter
 * @date   2017年3月15日  下午1:57:18
 * @author pengjunlin
 * @comment   
 * @update
 */
public class SecurityFilter implements Filter {
	
	private static String API_ISENABLE ;// WMS是否开通对外接口
	
	private static String API_PALTFORM;// WMS开放的平台编码
	
	private static String API_MEMBERCODE;//WMS开放的服务商编码
	
	private static String publicKey;// 公钥
	
	private static String privateKey;// 私钥
	

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
	}
	
	/**
	 * 验证配置是否规范
	 * 
	 * @MethodName: isConfiged 
	 * @Description: 
	 * @param platformCode
	 * @param memberCode
	 * @return
	 * @throws
	 */
	private boolean isConfiged(String platformCode,String memberCode){
        if(API_ISENABLE==null||!API_ISENABLE.equals("true")){
			return false;
		}
        if(API_PALTFORM==null||platformCode==null||!platformCode.equals(API_PALTFORM)){
        	return false;
        }
		if (API_MEMBERCODE==null||memberCode == null||! memberCode.equals(API_MEMBERCODE)) {
			return false;
		}
		return true;
	}
	
	/**
	 * 验证token是否有效
	 * 
	 * @MethodName: validateToken 
	 * @Description: 
	 * @param token
	 * @return
	 * @throws
	 */
	private boolean validateToken(String token){
		if(token==null||token.equals("")){
			return false;
		}
		String params[]=SAASTokenManager.decryptToken(privateKey, token, "&");
		if(params==null||params.length<3){
			return false;
		}
		long now=System.currentTimeMillis();
		// Token超时验证20s
		long seconds=(now-Long.valueOf(params[2]))/1000;
		if(!API_PALTFORM.equals(params[0])||!API_MEMBERCODE.equals(params[1])||seconds>20){
			return false;
		}
		return true;
	}
	
	/**
	 * 验证请求是否重复
	 * 
	 * @MethodName: validateSequece 
	 * @Description: 
	 * @param sequence
	 * @return
	 * @throws
	 */
	public boolean validateSequece(String sequence){
		if(sequence==null||sequence.equals("")){
			return false;
		}
		String requestSequence=(String) EhcacheUtil.get(StaticProperty.REQUESTCACHE, sequence);
		// 请求序列相同验证失败
		if(requestSequence!=null&&sequence.equals(requestSequence)){
			return false;
		}
		return true;
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		PrintWriter out = null;
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse res = (HttpServletResponse) response;
		String platformCode = req.getHeader("PlatformCode");
		String memberCode = req.getHeader("MemberCode");
		String token = req.getHeader("Token");
		String sequence = req.getHeader("Sequence");
		//String path = req.getServletPath();
		try {
			byte [] bytes=SAASTokenManager.generateBytesToken(publicKey, platformCode, memberCode,"&");
			token = RSAUtils.bytesToString(bytes);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		
		// 验证接口是否配置正确 
		if(!isConfiged(platformCode, memberCode)){
			JSONObject json = new JSONObject();
			json.put("IsSuccess", "false");
			json.put("OperationDesc", "API parameters are not configed right! ");
			json.put("ResultCode", ResultCode.OPEN_API_CONFIG_ERROR);
			try {
				out = res.getWriter();
				out.write(json.toJSONString());
			} catch (Exception e) {
				e.printStackTrace();
			}
			return;
		}
		
		// 验证Token是否合法
		if(!validateToken(token)){
			JSONObject json = new JSONObject();
			json.put("IsSuccess", "false");
			json.put("OperationDesc", "Unauthorized:Token is invalid!");
			json.put("ResultCode", ResultCode.OPEN_API_TOKEN_INVALID);
			try {
				out = res.getWriter();
				out.write(json.toJSONString());
			} catch (Exception e) {
				e.printStackTrace();
			}
			return;
		}
		
		// 验证Sequence是否合法
		if(!validateSequece(sequence)){
			JSONObject json = new JSONObject();
			json.put("IsSuccess", "false");
			json.put("OperationDesc", "Refused:request API too frequently!");
			json.put("ResultCode", ResultCode.OPEN_API_REQUEST_REQUENTLY);
			try {
				out = res.getWriter();
				out.write(json.toJSONString());
			} catch (Exception e) {
				e.printStackTrace();
			}
			return;
		}

		chain.doFilter(request, response);

	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		Log.getLogger(getClass()).info(">>>SecurityFilter invoke init method。。。。。。。。。START!"); 
		API_ISENABLE = InitSysProperties.getLowerCaseFromEhcache(StaticProperty.WMS_OPEN_API_ISENABLE);
		API_PALTFORM = InitSysProperties.getUpperCaseFromEhcache(StaticProperty.WMS_OPEN_API_PLATFORM);
		API_MEMBERCODE = InitSysProperties.getUpperCaseFromEhcache(StaticProperty.WMS_OPEN_API_MEMBERCODE);
		publicKey=EhcacheUtil.get(StaticProperty.WMS_OPEN_API_RSA_PUBLIC_KEY).toString();
		privateKey=EhcacheUtil.get(StaticProperty.WMS_OPEN_API_RSA_PRIVATE_KEY).toString();
		Log.getLogger(getClass()).info(">>>SecurityFilter invoke init method。。。。。。。。。SUCCESS!"); 
	}

}

注:需要通过RSA工具生成密钥对(公钥&私钥)。

web.xml配置过滤器

  1. <filter>  
  2.         <filter-name>SecurityFilter</filter-name>  
  3.         <filter-class>com.wlyd.fmcgwms.util.security.SecurityFilter</filter-class>  
  4.     </filter>  
  5.     <filter-mapping>  
  6.         <filter-name>SecurityFilter</filter-name>  
  7.         <url-pattern>/openapi/*</url-pattern>  
  8.     </filter-mapping>  
<filter>
		<filter-name>SecurityFilter</filter-name>
		<filter-class>com.wlyd.fmcgwms.util.security.SecurityFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>SecurityFilter</filter-name>
		<url-pattern>/openapi/*</url-pattern>
	</filter-mapping>

控制层openapi接口

  1. package com.wlyd.fmcgwms.controller.security;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5. import org.springframework.stereotype.Controller;  
  6. import org.springframework.web.bind.annotation.RequestMapping;  
  7. import org.springframework.web.bind.annotation.ResponseBody;  
  8. import com.wlyd.fmcgwms.controller.BaseController;  
  9. import com.wlyd.fmcgwms.util.Tools;  
  10. /** 
  11.  * 开放API控制层 
  12.  *  
  13.  * @package com.wlyd.fmcgwms.controller.platform.OpenAPIController 
  14.  * @date   2017年3月14日  下午4:52:12 
  15.  * @author pengjunlin 
  16.  * @comment    
  17.  * @update 
  18.  */  
  19. @Controller  
  20. @RequestMapping("/openapi")  
  21. public class OpenAPIController extends BaseController{  
  22.       
  23.     /** 
  24.      * 未授权 
  25.      *  
  26.      * @MethodName: unauthenticated  
  27.      * @Description:  
  28.      * @return 
  29.      * @throws 
  30.      */  
  31.     @RequestMapping("/unauthenticated")  
  32.     @ResponseBody  
  33.     public String unauthenticated(){  
  34.         Map<String,Object> map=new HashMap<String, Object>();  
  35.         map.put("IsSuccess""false");  
  36.         map.put("OperationDesc""Unauthenticated:Please contact to WMS developers!");  
  37.         return Tools.toJson(map);  
  38.     }  
  39.       
  40.     /** 
  41.      * 授权成功 
  42.      *  
  43.      * @MethodName: success  
  44.      * @Description:  
  45.      * @return 
  46.      * @throws 
  47.      */  
  48.     @RequestMapping("/success")  
  49.     @ResponseBody  
  50.     public String success(){  
  51.         Map<String,Object> map=new HashMap<String, Object>();  
  52.         map.put("IsSuccess""true");  
  53.         map.put("OperationDesc""Authenticated!");  
  54.         return Tools.toJson(map);  
  55.     }  
  56.   
  57. }  
package com.wlyd.fmcgwms.controller.security;

import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.wlyd.fmcgwms.controller.BaseController;
import com.wlyd.fmcgwms.util.Tools;
/**
 * 开放API控制层
 * 
 * @package com.wlyd.fmcgwms.controller.platform.OpenAPIController
 * @date   2017年3月14日  下午4:52:12
 * @author pengjunlin
 * @comment   
 * @update
 */
@Controller
@RequestMapping("/openapi")
public class OpenAPIController extends BaseController{
	
	/**
	 * 未授权
	 * 
	 * @MethodName: unauthenticated 
	 * @Description: 
	 * @return
	 * @throws
	 */
	@RequestMapping("/unauthenticated")
	@ResponseBody
	public String unauthenticated(){
		Map<String,Object> map=new HashMap<String, Object>();
		map.put("IsSuccess", "false");
		map.put("OperationDesc", "Unauthenticated:Please contact to WMS developers!");
		return Tools.toJson(map);
	}
	
	/**
	 * 授权成功
	 * 
	 * @MethodName: success 
	 * @Description: 
	 * @return
	 * @throws
	 */
	@RequestMapping("/success")
	@ResponseBody
	public String success(){
		Map<String,Object> map=new HashMap<String, Object>();
		map.put("IsSuccess", "true");
		map.put("OperationDesc", "Authenticated!");
		return Tools.toJson(map);
	}

}

没有其它的方法。

RSA加密工具

  1. package com.wlyd.fmcgwms.util.api;  
  2.   
  3. import java.io.ByteArrayOutputStream;  
  4. import java.security.Key;  
  5. import java.security.KeyFactory;  
  6. import java.security.KeyPair;  
  7. import java.security.KeyPairGenerator;  
  8. import java.security.PrivateKey;  
  9. import java.security.PublicKey;  
  10. import java.security.Signature;  
  11. import java.security.interfaces.RSAPrivateKey;  
  12. import java.security.interfaces.RSAPublicKey;  
  13. import java.security.spec.PKCS8EncodedKeySpec;  
  14. import java.security.spec.X509EncodedKeySpec;  
  15. import java.util.HashMap;  
  16. import java.util.Map;  
  17.   
  18. import javax.crypto.Cipher;  
  19.   
  20. /** 
  21.  * <p> 
  22.  * RSA公钥/私钥/签名工具包 
  23.  * </p> 
  24.  * <p> 
  25.  * 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman) 
  26.  * </p> 
  27.  * <p> 
  28.  * 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式<br/> 
  29.  * 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/> 
  30.  * 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全 
  31.  * </p> 
  32.  *  
  33.  * @author IceWee 
  34.  * @date 2012-4-26 
  35.  * @version 1.0 
  36.  */  
  37. public class RSAUtils {  
  38.   
  39.     /** 
  40.      * 加密算法RSA 
  41.      */  
  42.     public static final String KEY_ALGORITHM = "RSA";  
  43.   
  44.     /** 
  45.      * 签名算法 
  46.      */  
  47.     public static final String SIGNATURE_ALGORITHM = "MD5withRSA";  
  48.   
  49.     /** 
  50.      * 获取公钥的key 
  51.      */  
  52.     private static final String PUBLIC_KEY = "RSAPublicKey";  
  53.   
  54.     /** 
  55.      * 获取私钥的key 
  56.      */  
  57.     private static final String PRIVATE_KEY = "RSAPrivateKey";  
  58.   
  59.     /** 
  60.      * RSA最大加密明文大小 
  61.      */  
  62.     private static final int MAX_ENCRYPT_BLOCK = 117;  
  63.   
  64.     /** 
  65.      * RSA最大解密密文大小 
  66.      */  
  67.     private static final int MAX_DECRYPT_BLOCK = 128;  
  68.   
  69.     /** 
  70.      * <p> 
  71.      * 生成密钥对(公钥和私钥) 
  72.      * </p> 
  73.      *  
  74.      * @return 
  75.      * @throws Exception 
  76.      */  
  77.     public static Map<String, Object> genKeyPair() throws Exception {  
  78.         KeyPairGenerator keyPairGen = KeyPairGenerator  
  79.                 .getInstance(KEY_ALGORITHM);  
  80.         keyPairGen.initialize(1024);  
  81.         KeyPair keyPair = keyPairGen.generateKeyPair();  
  82.         RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  
  83.         RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();  
  84.         Map<String, Object> keyMap = new HashMap<String, Object>(2);  
  85.         keyMap.put(PUBLIC_KEY, publicKey);  
  86.         keyMap.put(PRIVATE_KEY, privateKey);  
  87.         return keyMap;  
  88.     }  
  89.   
  90.     /** 
  91.      * <p> 
  92.      * 用私钥对信息生成数字签名 
  93.      * </p> 
  94.      *  
  95.      * @param data 
  96.      *            已加密数据 
  97.      * @param privateKey 
  98.      *            私钥(BASE64编码) 
  99.      *  
  100.      * @return 
  101.      * @throws Exception 
  102.      */  
  103.     public static String sign(byte[] data, String privateKey) throws Exception {  
  104.         byte[] keyBytes = Base64Utils.decode(privateKey);  
  105.         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);  
  106.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  
  107.         PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);  
  108.         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);  
  109.         signature.initSign(privateK);  
  110.         signature.update(data);  
  111.         return Base64Utils.encode(signature.sign());  
  112.     }  
  113.   
  114.     /** 
  115.      * <p> 
  116.      * 校验数字签名 
  117.      * </p> 
  118.      *  
  119.      * @param data 
  120.      *            已加密数据 
  121.      * @param publicKey 
  122.      *            公钥(BASE64编码) 
  123.      * @param sign 
  124.      *            数字签名 
  125.      *  
  126.      * @return 
  127.      * @throws Exception 
  128.      *  
  129.      */  
  130.     public static boolean verify(byte[] data, String publicKey, String sign)  
  131.             throws Exception {  
  132.         byte[] keyBytes = Base64Utils.decode(publicKey);  
  133.         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);  
  134.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  
  135.         PublicKey publicK = keyFactory.generatePublic(keySpec);  
  136.         Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);  
  137.         signature.initVerify(publicK);  
  138.         signature.update(data);  
  139.         return signature.verify(Base64Utils.decode(sign));  
  140.     }  
  141.   
  142.     /** 
  143.      * <P> 
  144.      * 私钥解密 
  145.      * </p> 
  146.      *  
  147.      * @param encryptedData 
  148.      *            已加密数据 
  149.      * @param privateKey 
  150.      *            私钥(BASE64编码) 
  151.      * @return 
  152.      * @throws Exception 
  153.      */  
  154.     public static byte[] decryptByPrivateKey(byte[] encryptedData,  
  155.             String privateKey) throws Exception {  
  156.         byte[] keyBytes = Base64Utils.decode(privateKey);  
  157.         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);  
  158.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  
  159.         Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);  
  160.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
  161.         cipher.init(Cipher.DECRYPT_MODE, privateK);  
  162.         int inputLen = encryptedData.length;  
  163.         ByteArrayOutputStream out = new ByteArrayOutputStream();  
  164.         int offSet = 0;  
  165.         byte[] cache;  
  166.         int i = 0;  
  167.         // 对数据分段解密  
  168.         while (inputLen - offSet > 0) {  
  169.             if (inputLen - offSet > MAX_DECRYPT_BLOCK) {  
  170.                 cache = cipher  
  171.                         .doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);  
  172.             } else {  
  173.                 cache = cipher  
  174.                         .doFinal(encryptedData, offSet, inputLen - offSet);  
  175.             }  
  176.             out.write(cache, 0, cache.length);  
  177.             i++;  
  178.             offSet = i * MAX_DECRYPT_BLOCK;  
  179.         }  
  180.         byte[] decryptedData = out.toByteArray();  
  181.         out.close();  
  182.         return decryptedData;  
  183.     }  
  184.   
  185.     /** 
  186.      * <p> 
  187.      * 公钥解密 
  188.      * </p> 
  189.      *  
  190.      * @param encryptedData 
  191.      *            已加密数据 
  192.      * @param publicKey 
  193.      *            公钥(BASE64编码) 
  194.      * @return 
  195.      * @throws Exception 
  196.      */  
  197.     public static byte[] decryptByPublicKey(byte[] encryptedData,  
  198.             String publicKey) throws Exception {  
  199.         byte[] keyBytes = Base64Utils.decode(publicKey);  
  200.         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);  
  201.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  
  202.         Key publicK = keyFactory.generatePublic(x509KeySpec);  
  203.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
  204.         cipher.init(Cipher.DECRYPT_MODE, publicK);  
  205.         int inputLen = encryptedData.length;  
  206.         ByteArrayOutputStream out = new ByteArrayOutputStream();  
  207.         int offSet = 0;  
  208.         byte[] cache;  
  209.         int i = 0;  
  210.         // 对数据分段解密  
  211.         while (inputLen - offSet > 0) {  
  212.             if (inputLen - offSet > MAX_DECRYPT_BLOCK) {  
  213.                 cache = cipher  
  214.                         .doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);  
  215.             } else {  
  216.                 cache = cipher  
  217.                         .doFinal(encryptedData, offSet, inputLen - offSet);  
  218.             }  
  219.             out.write(cache, 0, cache.length);  
  220.             i++;  
  221.             offSet = i * MAX_DECRYPT_BLOCK;  
  222.         }  
  223.         byte[] decryptedData = out.toByteArray();  
  224.         out.close();  
  225.         return decryptedData;  
  226.     }  
  227.   
  228.     /** 
  229.      * <p> 
  230.      * 公钥加密 
  231.      * </p> 
  232.      *  
  233.      * @param data 
  234.      *            源数据 
  235.      * @param publicKey 
  236.      *            公钥(BASE64编码) 
  237.      * @return 
  238.      * @throws Exception 
  239.      */  
  240.     public static byte[] encryptByPublicKey(byte[] data, String publicKey)  
  241.             throws Exception {  
  242.         byte[] keyBytes = Base64Utils.decode(publicKey);  
  243.         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);  
  244.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  
  245.         Key publicK = keyFactory.generatePublic(x509KeySpec);  
  246.         // 对数据加密  
  247.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
  248.         cipher.init(Cipher.ENCRYPT_MODE, publicK);  
  249.         int inputLen = data.length;  
  250.         ByteArrayOutputStream out = new ByteArrayOutputStream();  
  251.         int offSet = 0;  
  252.         byte[] cache;  
  253.         int i = 0;  
  254.         // 对数据分段加密  
  255.         while (inputLen - offSet > 0) {  
  256.             if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {  
  257.                 cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);  
  258.             } else {  
  259.                 cache = cipher.doFinal(data, offSet, inputLen - offSet);  
  260.             }  
  261.             out.write(cache, 0, cache.length);  
  262.             i++;  
  263.             offSet = i * MAX_ENCRYPT_BLOCK;  
  264.         }  
  265.         byte[] encryptedData = out.toByteArray();  
  266.         out.close();  
  267.         return encryptedData;  
  268.     }  
  269.   
  270.     /** 
  271.      * <p> 
  272.      * 私钥加密 
  273.      * </p> 
  274.      *  
  275.      * @param data 
  276.      *            源数据 
  277.      * @param privateKey 
  278.      *            私钥(BASE64编码) 
  279.      * @return 
  280.      * @throws Exception 
  281.      */  
  282.     public static byte[] encryptByPrivateKey(byte[] data, String privateKey)  
  283.             throws Exception {  
  284.         byte[] keyBytes = Base64Utils.decode(privateKey);  
  285.         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);  
  286.         KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  
  287.         Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);  
  288.         Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  
  289.         cipher.init(Cipher.ENCRYPT_MODE, privateK);  
  290.         int inputLen = data.length;  
  291.         ByteArrayOutputStream out = new ByteArrayOutputStream();  
  292.         int offSet = 0;  
  293.         byte[] cache;  
  294.         int i = 0;  
  295.         // 对数据分段加密  
  296.         while (inputLen - offSet > 0) {  
  297.             if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {  
  298.                 cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);  
  299.             } else {  
  300.                 cache = cipher.doFinal(data, offSet, inputLen - offSet);  
  301.             }  
  302.             out.write(cache, 0, cache.length);  
  303.             i++;  
  304.             offSet = i * MAX_ENCRYPT_BLOCK;  
  305.         }  
  306.         byte[] encryptedData = out.toByteArray();  
  307.         out.close();  
  308.         return encryptedData;  
  309.     }  
  310.   
  311.     /** 
  312.      * <p> 
  313.      * 获取私钥 
  314.      * </p> 
  315.      *  
  316.      * @param keyMap 
  317.      *            密钥对 
  318.      * @return 
  319.      * @throws Exception 
  320.      */  
  321.     public static String getPrivateKey(Map<String, Object> keyMap)  
  322.             throws Exception {  
  323.         Key key = (Key) keyMap.get(PRIVATE_KEY);  
  324.         return Base64Utils.encode(key.getEncoded());  
  325.     }  
  326.   
  327.     /** 
  328.      * <p> 
  329.      * 获取公钥 
  330.      * </p> 
  331.      *  
  332.      * @param keyMap 
  333.      *            密钥对 
  334.      * @return 
  335.      * @throws Exception 
  336.      */  
  337.     public static String getPublicKey(Map<String, Object> keyMap)  
  338.             throws Exception {  
  339.         Key key = (Key) keyMap.get(PUBLIC_KEY);  
  340.         return Base64Utils.encode(key.getEncoded());  
  341.     }  
  342.       
  343.     /** 
  344.      * 将加密后的字节数组转换为对象 
  345.      *  
  346.      * @MethodName: bytesToString  
  347.      * @Description:  
  348.      * @param encrytpByte 
  349.      * @return 
  350.      * @throws 
  351.      */  
  352.     public static String bytesToString(byte[] encrytpByte) {  
  353.          String result = "";  
  354.          for (Byte bytes : encrytpByte) {  
  355.              result += bytes.toString() + " ";  
  356.          }  
  357.          return result;  
  358.      }  
  359.       
  360.     /** 
  361.      * 公钥加密 
  362.      *  
  363.      * @MethodName: encrypt  
  364.      * @Description:  
  365.      * @param publicKey 
  366.      * @param obj 
  367.      * @return 
  368.      * @throws 
  369.      */  
  370.     public static byte[] encrypt(RSAPublicKey publicKey, byte[] obj) {  
  371.          if (publicKey != null) {  
  372.              try {  
  373.                  Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);  
  374.                  cipher.init(Cipher.ENCRYPT_MODE, publicKey);  
  375.                  return cipher.doFinal(obj);  
  376.              } catch (Exception e) {  
  377.                  e.printStackTrace();  
  378.              }  
  379.          }  
  380.          return null;  
  381.      }  
  382.       
  383.     /** 
  384.      * 私钥加密 
  385.      *  
  386.      * @MethodName: decrypt  
  387.      * @Description:  
  388.      * @param privateKey 
  389.      * @param obj 
  390.      * @return 
  391.      * @throws 
  392.      */  
  393.     public static byte[] decrypt(RSAPrivateKey privateKey, byte[] obj) {  
  394.          if (privateKey != null) {  
  395.              try {  
  396.                  Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);  
  397.                  cipher.init(Cipher.DECRYPT_MODE, privateKey);  
  398.                  return cipher.doFinal(obj);  
  399.              } catch (Exception e) {  
  400.                  e.printStackTrace();  
  401.              }  
  402.          }  
  403.          return null;  
  404.      }  
  405.   
  406. }  
package com.wlyd.fmcgwms.util.api;

import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

/**
 * <p>
 * RSA公钥/私钥/签名工具包
 * </p>
 * <p>
 * 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman)
 * </p>
 * <p>
 * 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式<br/>
 * 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/>
 * 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全
 * </p>
 * 
 * @author IceWee
 * @date 2012-4-26
 * @version 1.0
 */
public class RSAUtils {

	/**
	 * 加密算法RSA
	 */
	public static final String KEY_ALGORITHM = "RSA";

	/**
	 * 签名算法
	 */
	public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

	/**
	 * 获取公钥的key
	 */
	private static final String PUBLIC_KEY = "RSAPublicKey";

	/**
	 * 获取私钥的key
	 */
	private static final String PRIVATE_KEY = "RSAPrivateKey";

	/**
	 * RSA最大加密明文大小
	 */
	private static final int MAX_ENCRYPT_BLOCK = 117;

	/**
	 * RSA最大解密密文大小
	 */
	private static final int MAX_DECRYPT_BLOCK = 128;

	/**
	 * <p>
	 * 生成密钥对(公钥和私钥)
	 * </p>
	 * 
	 * @return
	 * @throws Exception
	 */
	public static Map<String, Object> genKeyPair() throws Exception {
		KeyPairGenerator keyPairGen = KeyPairGenerator
				.getInstance(KEY_ALGORITHM);
		keyPairGen.initialize(1024);
		KeyPair keyPair = keyPairGen.generateKeyPair();
		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
		Map<String, Object> keyMap = new HashMap<String, Object>(2);
		keyMap.put(PUBLIC_KEY, publicKey);
		keyMap.put(PRIVATE_KEY, privateKey);
		return keyMap;
	}

	/**
	 * <p>
	 * 用私钥对信息生成数字签名
	 * </p>
	 * 
	 * @param data
	 *            已加密数据
	 * @param privateKey
	 *            私钥(BASE64编码)
	 * 
	 * @return
	 * @throws Exception
	 */
	public static String sign(byte[] data, String privateKey) throws Exception {
		byte[] keyBytes = Base64Utils.decode(privateKey);
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
		signature.initSign(privateK);
		signature.update(data);
		return Base64Utils.encode(signature.sign());
	}

	/**
	 * <p>
	 * 校验数字签名
	 * </p>
	 * 
	 * @param data
	 *            已加密数据
	 * @param publicKey
	 *            公钥(BASE64编码)
	 * @param sign
	 *            数字签名
	 * 
	 * @return
	 * @throws Exception
	 * 
	 */
	public static boolean verify(byte[] data, String publicKey, String sign)
			throws Exception {
		byte[] keyBytes = Base64Utils.decode(publicKey);
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		PublicKey publicK = keyFactory.generatePublic(keySpec);
		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
		signature.initVerify(publicK);
		signature.update(data);
		return signature.verify(Base64Utils.decode(sign));
	}

	/**
	 * <P>
	 * 私钥解密
	 * </p>
	 * 
	 * @param encryptedData
	 *            已加密数据
	 * @param privateKey
	 *            私钥(BASE64编码)
	 * @return
	 * @throws Exception
	 */
	public static byte[] decryptByPrivateKey(byte[] encryptedData,
			String privateKey) throws Exception {
		byte[] keyBytes = Base64Utils.decode(privateKey);
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, privateK);
		int inputLen = encryptedData.length;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] cache;
		int i = 0;
		// 对数据分段解密
		while (inputLen - offSet > 0) {
			if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
				cache = cipher
						.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
			} else {
				cache = cipher
						.doFinal(encryptedData, offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * MAX_DECRYPT_BLOCK;
		}
		byte[] decryptedData = out.toByteArray();
		out.close();
		return decryptedData;
	}

	/**
	 * <p>
	 * 公钥解密
	 * </p>
	 * 
	 * @param encryptedData
	 *            已加密数据
	 * @param publicKey
	 *            公钥(BASE64编码)
	 * @return
	 * @throws Exception
	 */
	public static byte[] decryptByPublicKey(byte[] encryptedData,
			String publicKey) throws Exception {
		byte[] keyBytes = Base64Utils.decode(publicKey);
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key publicK = keyFactory.generatePublic(x509KeySpec);
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, publicK);
		int inputLen = encryptedData.length;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] cache;
		int i = 0;
		// 对数据分段解密
		while (inputLen - offSet > 0) {
			if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
				cache = cipher
						.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
			} else {
				cache = cipher
						.doFinal(encryptedData, offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * MAX_DECRYPT_BLOCK;
		}
		byte[] decryptedData = out.toByteArray();
		out.close();
		return decryptedData;
	}

	/**
	 * <p>
	 * 公钥加密
	 * </p>
	 * 
	 * @param data
	 *            源数据
	 * @param publicKey
	 *            公钥(BASE64编码)
	 * @return
	 * @throws Exception
	 */
	public static byte[] encryptByPublicKey(byte[] data, String publicKey)
			throws Exception {
		byte[] keyBytes = Base64Utils.decode(publicKey);
		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key publicK = keyFactory.generatePublic(x509KeySpec);
		// 对数据加密
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, publicK);
		int inputLen = data.length;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] cache;
		int i = 0;
		// 对数据分段加密
		while (inputLen - offSet > 0) {
			if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
				cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
			} else {
				cache = cipher.doFinal(data, offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * MAX_ENCRYPT_BLOCK;
		}
		byte[] encryptedData = out.toByteArray();
		out.close();
		return encryptedData;
	}

	/**
	 * <p>
	 * 私钥加密
	 * </p>
	 * 
	 * @param data
	 *            源数据
	 * @param privateKey
	 *            私钥(BASE64编码)
	 * @return
	 * @throws Exception
	 */
	public static byte[] encryptByPrivateKey(byte[] data, String privateKey)
			throws Exception {
		byte[] keyBytes = Base64Utils.decode(privateKey);
		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
		Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, privateK);
		int inputLen = data.length;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] cache;
		int i = 0;
		// 对数据分段加密
		while (inputLen - offSet > 0) {
			if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
				cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
			} else {
				cache = cipher.doFinal(data, offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * MAX_ENCRYPT_BLOCK;
		}
		byte[] encryptedData = out.toByteArray();
		out.close();
		return encryptedData;
	}

	/**
	 * <p>
	 * 获取私钥
	 * </p>
	 * 
	 * @param keyMap
	 *            密钥对
	 * @return
	 * @throws Exception
	 */
	public static String getPrivateKey(Map<String, Object> keyMap)
			throws Exception {
		Key key = (Key) keyMap.get(PRIVATE_KEY);
		return Base64Utils.encode(key.getEncoded());
	}

	/**
	 * <p>
	 * 获取公钥
	 * </p>
	 * 
	 * @param keyMap
	 *            密钥对
	 * @return
	 * @throws Exception
	 */
	public static String getPublicKey(Map<String, Object> keyMap)
			throws Exception {
		Key key = (Key) keyMap.get(PUBLIC_KEY);
		return Base64Utils.encode(key.getEncoded());
	}
	
	/**
	 * 将加密后的字节数组转换为对象
	 * 
	 * @MethodName: bytesToString 
	 * @Description: 
	 * @param encrytpByte
	 * @return
	 * @throws
	 */
	public static String bytesToString(byte[] encrytpByte) {
	     String result = "";
	     for (Byte bytes : encrytpByte) {
	         result += bytes.toString() + " ";
	     }
	     return result;
	 }
	
	/**
	 * 公钥加密
	 * 
	 * @MethodName: encrypt 
	 * @Description: 
	 * @param publicKey
	 * @param obj
	 * @return
	 * @throws
	 */
	public static byte[] encrypt(RSAPublicKey publicKey, byte[] obj) {
	     if (publicKey != null) {
	         try {
	             Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
	             cipher.init(Cipher.ENCRYPT_MODE, publicKey);
	             return cipher.doFinal(obj);
	         } catch (Exception e) {
	             e.printStackTrace();
	         }
	     }
	     return null;
	 }
	
	/**
	 * 私钥加密
	 * 
	 * @MethodName: decrypt 
	 * @Description: 
	 * @param privateKey
	 * @param obj
	 * @return
	 * @throws
	 */
	public static byte[] decrypt(RSAPrivateKey privateKey, byte[] obj) {
	     if (privateKey != null) {
	         try {
	             Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
	             cipher.init(Cipher.DECRYPT_MODE, privateKey);
	             return cipher.doFinal(obj);
	         } catch (Exception e) {
	             e.printStackTrace();
	         }
	     }
	     return null;
	 }

}

Token管理工具

  1. package com.wlyd.fmcgwms.util;  
  2.   
  3. import java.sql.Timestamp;  
  4. import java.util.Date;  
  5. import java.util.Map;  
  6. import java.util.concurrent.ConcurrentHashMap;  
  7.   
  8. import com.wlyd.fmcgwms.persistence.beans.api.AccessToken;  
  9. import com.wlyd.fmcgwms.util.api.Base64Utils;  
  10. import com.wlyd.fmcgwms.util.api.RSAUtils;  
  11. import com.wlyd.fmcgwms.util.ehcache.EhcacheUtil;  
  12. import com.wlyd.fmcgwms.util.sysinit.InitSysProperties;  
  13.   
  14. /** 
  15.  * SAAS Token管理工具 
  16.  *  
  17.  * @packge com.wlyd.wmscloud.util.SAASTokenManager 
  18.  * @date 2016年5月6日 上午10:20:01 
  19.  * @author pengjunlin 
  20.  * @comment 
  21.  * @update 
  22.  */  
  23. public class SAASTokenManager {  
  24.       
  25.   
  26.     /** 
  27.      * Token存储对象,保持100000个并发容量(K-useraccount@corCode,V-token) 
  28.      */  
  29.     private static final Map<String, Object> map = new ConcurrentHashMap<String, Object>(  
  30.             100000);  
  31.   
  32.     /** 
  33.      * 获取用户Token 
  34.      *  
  35.      * @MethodName: getToken 
  36.      * @Description: 
  37.      * @param key 
  38.      * @return 
  39.      * @throws 
  40.      */  
  41.     public static AccessToken getToken(String key) {  
  42.         if (map.containsKey(key)) {  
  43.             return (AccessToken) map.get(key);  
  44.         }  
  45.         return null;  
  46.     }  
  47.   
  48.     /** 
  49.      * 添加用户token 
  50.      *  
  51.      * @MethodName: putToken 
  52.      * @Description: 
  53.      * @param key 
  54.      *            useraccount@corCode 
  55.      * @param accessToken 
  56.      * @throws 
  57.      */  
  58.     public static void putToken(String key, AccessToken accessToken) {  
  59.         map.put(key, accessToken);  
  60.     }  
  61.   
  62.     /** 
  63.      * 移除token 
  64.      *  
  65.      * @MethodName: removeToken 
  66.      * @Description: 
  67.      * @param key 
  68.      *            useraccount@corCode 
  69.      * @throws 
  70.      */  
  71.     public static void removeToken(String key) {  
  72.         if (map.containsKey(key)) {  
  73.             map.remove(key);  
  74.         }  
  75.     }  
  76.   
  77.     /** 
  78.      * 验证Token是否过期 
  79.      *  
  80.      * @MethodName: isVlidateToken 
  81.      * @Description: 
  82.      * @param key 
  83.      *            useraccount@corCode 
  84.      * @return 
  85.      * @throws 
  86.      */  
  87.     public static boolean isVlidateToken(String key) {  
  88.         if (map.containsKey(key)) {  
  89.             AccessToken accessToken = (AccessToken) map.get(key);  
  90.             long currentTimestamp = new Date().getTime();  
  91.             // 有效时间两小时  
  92.             if (accessToken.getLongTime() - currentTimestamp > 2 * 3600 * 1000) {  
  93.                 return false;  
  94.             }  
  95.             return true;  
  96.         }  
  97.         return false;  
  98.     }  
  99.   
  100.     /** 
  101.      * 更新Token 
  102.      *  
  103.      * @MethodName: reputToken 
  104.      * @Description: 
  105.      * @param key 
  106.      *            useraccount@corCode 
  107.      * @param accessToken 
  108.      * @return 
  109.      * @throws 
  110.      */  
  111.     public static void reputToken(String key, AccessToken accessToken) {  
  112.         if (map.containsKey(key)) {  
  113.             putToken(key, accessToken);  
  114.         }  
  115.     }  
  116.   
  117.     /** 
  118.      * 更新Token 
  119.      *  
  120.      * @MethodName: reputToken 
  121.      * @Description: 
  122.      * @param key 
  123.      *            useraccount@corCode 
  124.      * @param tokenStr 
  125.      * @return 
  126.      * @throws 
  127.      */  
  128.     public static void reputToken(String key, String tokenStr) {  
  129.         if (map.containsKey(key)) {  
  130.             AccessToken accessToken = new AccessToken();  
  131.             accessToken.setToken(tokenStr);  
  132.             accessToken.setTimestamp(new Timestamp(new Date().getTime()));  
  133.             putToken(key, accessToken);  
  134.         }  
  135.     }  
  136.       
  137.     /** 
  138.      * 是否包含用户token 
  139.      * @MethodName: iscontainKey  
  140.      * @Description:  
  141.      * @param key 
  142.      *          useraccount@corCode 
  143.      * @return 
  144.      * @throws 
  145.      */  
  146.     public static boolean iscontainKey(String key){  
  147.         return map.containsKey(key);  
  148.     }  
  149.       
  150.     /** 
  151.      * 生成RSA加密 Token 
  152.      *  
  153.      * @MethodName: generateToken  
  154.      * @Description:  
  155.      * @param platformCode 
  156.      * @param tenantCode 
  157.      * @return 
  158.      * @throws 
  159.      */  
  160.     public static String generateToken(String publicKey,String platformCode,String tenantCode){  
  161.         String str=platformCode+"$"+tenantCode+"$"+new Date().getTime();  
  162.         try {  
  163.             byte [] bytes= RSAUtils.encryptByPublicKey(str.getBytes(),publicKey);  
  164.         //  return new String( bytes ,"UTF-8");  
  165.             return Base64Utils.encode(bytes);  
  166.         } catch (Exception e) {  
  167.             e.printStackTrace();   
  168.         }  
  169.         return null;  
  170.     }  
  171.       
  172.     /** 
  173.      * 生成RSA加密 Token 
  174.      *  
  175.      * @MethodName: generateBytesToken  
  176.      * @Description:  
  177.      * @param platformCode 
  178.      * @param tenantCode 
  179.      * @return 
  180.      * @throws 
  181.      */  
  182.     public static byte [] generateBytesToken(String publicKey,String platformCode,String tenantCode){  
  183.         byte [] bytes=new byte[0];  
  184.         String str=platformCode+"$"+tenantCode+"$"+new Date().getTime();  
  185.         try {  
  186.             bytes= RSAUtils.encryptByPublicKey(str.getBytes(),publicKey);  
  187.             return bytes;  
  188.         } catch (Exception e) {  
  189.             e.printStackTrace();   
  190.         }  
  191.         return null;  
  192.     }  
  193.       
  194.     /** 
  195.      * 生成RSA加密 Token 
  196.      *  
  197.      * @MethodName: generateBytesToken  
  198.      * @Description:  
  199.      * @param platformCode 
  200.      * @param tenantCode 
  201.      * @param regex 
  202.      * @return 
  203.      * @throws 
  204.      */  
  205.     public static byte [] generateBytesToken(String publicKey,String platformCode,String tenantCode,String regex){  
  206.         byte [] bytes=new byte[0];  
  207.         String str=platformCode+regex+tenantCode+regex+new Date().getTime();  
  208.         try {  
  209.             bytes= RSAUtils.encryptByPublicKey(str.getBytes(),publicKey);  
  210.             return bytes;  
  211.         } catch (Exception e) {  
  212.             e.printStackTrace();   
  213.         }  
  214.         return null;  
  215.     }  
  216.       
  217.     /** 
  218.      * 模拟自动生成Token 
  219.      *  
  220.      * @MethodName: getToken  
  221.      * @Description:  
  222.      * @return 
  223.      * @throws 
  224.      */  
  225.     public  static String getToken(){  
  226.         // 开启线程同步库存数据到OMS  
  227.         /*Map<String, Object> keyMap=null; 
  228.         try { 
  229.             keyMap = RSAUtils.genKeyPair(); 
  230.         } catch (Exception e) { 
  231.             e.printStackTrace(); 
  232.         } 
  233.         String publicKey=null; 
  234.         try { 
  235.             publicKey = RSAUtils.getPublicKey(keyMap); 
  236.         } catch (Exception e) { 
  237.             e.printStackTrace(); 
  238.         } 
  239.         String privateKey=null; 
  240.         try { 
  241.             privateKey = RSAUtils.getPrivateKey(keyMap); 
  242.         } catch (Exception e) { 
  243.             e.printStackTrace(); 
  244.         }*/  
  245.         String token=null;  
  246.         try {  
  247.             String publicKey=EhcacheUtil.get("OMS_RSA_PUBLIC_KEY").toString();  
  248.             //String privateKey=EhcacheUtil.get("OMS_RSA_PRIVATE_KEY").toString();  
  249.             String platformCode = (String) EhcacheUtil.get("WAAS_PLATFORMCODE");  
  250.             String memberCode =  InitSysProperties.getUpperCaseFromEhcache(StaticProperty.WAAS_MEMBERCODE);  
  251.             token = SAASTokenManager.generateToken(publicKey, platformCode, memberCode);  
  252.             if(token!=null){  
  253.                 token.replaceAll("\\n""");  
  254.                 token.replaceAll("\\r""");  
  255.             }  
  256.         } catch (Exception e) {   
  257.             Log.getLogger(SAASTokenManager.class).error("Token Error:"+e.getMessage());  
  258.             e.printStackTrace();  
  259.         }  
  260.         return token;  
  261.     }  
  262.       
  263.     /** 
  264.      * 解密Token 
  265.      *  
  266.      * @MethodName: decryptToken  
  267.      * @Description:  
  268.      * @param privateKey 
  269.      * @param token 
  270.      * @param regex 
  271.      * @return 
  272.      * @throws 
  273.      */  
  274.     public static String [] decryptToken(String privateKey,String token,String regex){  
  275.         String params[]=new String[0];  
  276.         try {  
  277.             String[] strArr = token.split(" ");  
  278.               
  279.             int len = strArr.length;  
  280.               
  281.             // 转回bytes  
  282.             byte[] clone = new byte[len];  
  283.                
  284.             for (int i = 0; i < len; i++) {  
  285.                  clone[i] = Byte.parseByte(strArr[i]);  
  286.             }  
  287.             String decryptedToken=new String(RSAUtils.decryptByPrivateKey(clone, privateKey));  
  288.             params=decryptedToken.split(regex);  
  289.         } catch (Exception e) {  
  290.             e.printStackTrace();  
  291.         }  
  292.         return params;  
  293.     }  
  294.   
  295.     /** 
  296.      * @throws Exception  
  297.      * 测试函数入口 
  298.      *  
  299.      * @MethodName: main 
  300.      * @Description: 
  301.      * @param args 
  302.      * @throws 
  303.      */  
  304.     public static void main(String[] args) throws Exception {  
  305.         System.out.println(Md5.getMD5Str("123456"));  
  306.         String key = "wmsadmin@10000";   
  307.         AccessToken accessToken = new AccessToken();  
  308.         accessToken.setToken("token==xxjisifdihfifdds");  
  309.         accessToken.setTimestamp(new Timestamp(new Date().getTime()));  
  310.         putToken(key, accessToken);  
  311.         AccessToken accessToken2 = getToken(key);  
  312.         System.out.println("token:" + accessToken2.getToken());  
  313.         System.out.println("isValidate:" + isVlidateToken(key));  
  314.           
  315.         Map<String, Object> keyMap=RSAUtils.genKeyPair();  
  316.         String publicKey=RSAUtils.getPublicKey(keyMap);  
  317.         String privateKey=RSAUtils.getPrivateKey(keyMap);  
  318.   
  319.         System.out.println("publicKey:\n"+publicKey);  
  320.         System.out.println("privateKey:\n"+privateKey);  
  321.   
  322.         String token=generateToken(publicKey,"1234""10000");  
  323.           
  324.         byte [] bitesToken=RSAUtils.encryptByPublicKey(("1234$10000$"+new Date().getTime()).getBytes(), publicKey);  
  325.           
  326.         System.out.println("RSA Token:"+token);  
  327.           
  328.         System.out.println("RSA bites Token加密:"+new String(bitesToken,"UTF-8"));   
  329.           
  330.         System.out.println("RSA bites Token解密:"+new String(RSAUtils.decryptByPrivateKey(bitesToken, privateKey)));   
  331.           
  332.         System.out.println("加密:"+new String(RSAUtils.encryptByPublicKey("this is data".getBytes(), publicKey),"UTF-8"));  
  333.         System.out.println("明文:"+new String(RSAUtils.decryptByPrivateKey(RSAUtils.encryptByPublicKey("this is data".getBytes(), publicKey), privateKey)));  
  334.     }  
  335.   
  336. }  
package com.wlyd.fmcgwms.util;

import java.sql.Timestamp;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.wlyd.fmcgwms.persistence.beans.api.AccessToken;
import com.wlyd.fmcgwms.util.api.Base64Utils;
import com.wlyd.fmcgwms.util.api.RSAUtils;
import com.wlyd.fmcgwms.util.ehcache.EhcacheUtil;
import com.wlyd.fmcgwms.util.sysinit.InitSysProperties;

/**
 * SAAS Token管理工具
 * 
 * @packge com.wlyd.wmscloud.util.SAASTokenManager
 * @date 2016年5月6日 上午10:20:01
 * @author pengjunlin
 * @comment
 * @update
 */
public class SAASTokenManager {
	

	/**
	 * Token存储对象,保持100000个并发容量(K-useraccount@corCode,V-token)
	 */
	private static final Map<String, Object> map = new ConcurrentHashMap<String, Object>(
			100000);

	/**
	 * 获取用户Token
	 * 
	 * @MethodName: getToken
	 * @Description:
	 * @param key
	 * @return
	 * @throws
	 */
	public static AccessToken getToken(String key) {
		if (map.containsKey(key)) {
			return (AccessToken) map.get(key);
		}
		return null;
	}

	/**
	 * 添加用户token
	 * 
	 * @MethodName: putToken
	 * @Description:
	 * @param key
	 *            useraccount@corCode
	 * @param accessToken
	 * @throws
	 */
	public static void putToken(String key, AccessToken accessToken) {
		map.put(key, accessToken);
	}

	/**
	 * 移除token
	 * 
	 * @MethodName: removeToken
	 * @Description:
	 * @param key
	 *            useraccount@corCode
	 * @throws
	 */
	public static void removeToken(String key) {
		if (map.containsKey(key)) {
			map.remove(key);
		}
	}

	/**
	 * 验证Token是否过期
	 * 
	 * @MethodName: isVlidateToken
	 * @Description:
	 * @param key
	 *            useraccount@corCode
	 * @return
	 * @throws
	 */
	public static boolean isVlidateToken(String key) {
		if (map.containsKey(key)) {
			AccessToken accessToken = (AccessToken) map.get(key);
			long currentTimestamp = new Date().getTime();
			// 有效时间两小时
			if (accessToken.getLongTime() - currentTimestamp > 2 * 3600 * 1000) {
				return false;
			}
			return true;
		}
		return false;
	}

	/**
	 * 更新Token
	 * 
	 * @MethodName: reputToken
	 * @Description:
	 * @param key
	 *            useraccount@corCode
	 * @param accessToken
	 * @return
	 * @throws
	 */
	public static void reputToken(String key, AccessToken accessToken) {
		if (map.containsKey(key)) {
			putToken(key, accessToken);
		}
	}

	/**
	 * 更新Token
	 * 
	 * @MethodName: reputToken
	 * @Description:
	 * @param key
	 *            useraccount@corCode
	 * @param tokenStr
	 * @return
	 * @throws
	 */
	public static void reputToken(String key, String tokenStr) {
		if (map.containsKey(key)) {
			AccessToken accessToken = new AccessToken();
			accessToken.setToken(tokenStr);
			accessToken.setTimestamp(new Timestamp(new Date().getTime()));
			putToken(key, accessToken);
		}
	}
	
	/**
	 * 是否包含用户token
	 * @MethodName: iscontainKey 
	 * @Description: 
	 * @param key
	 *          useraccount@corCode
	 * @return
	 * @throws
	 */
	public static boolean iscontainKey(String key){
		return map.containsKey(key);
	}
	
	/**
	 * 生成RSA加密 Token
	 * 
	 * @MethodName: generateToken 
	 * @Description: 
	 * @param platformCode
	 * @param tenantCode
	 * @return
	 * @throws
	 */
	public static String generateToken(String publicKey,String platformCode,String tenantCode){
		String str=platformCode+"$"+tenantCode+"$"+new Date().getTime();
		try {
			byte [] bytes= RSAUtils.encryptByPublicKey(str.getBytes(),publicKey);
		//	return new String( bytes ,"UTF-8");
			return Base64Utils.encode(bytes);
		} catch (Exception e) {
			e.printStackTrace(); 
		}
		return null;
	}
	
	/**
	 * 生成RSA加密 Token
	 * 
	 * @MethodName: generateBytesToken 
	 * @Description: 
	 * @param platformCode
	 * @param tenantCode
	 * @return
	 * @throws
	 */
	public static byte [] generateBytesToken(String publicKey,String platformCode,String tenantCode){
		byte [] bytes=new byte[0];
		String str=platformCode+"$"+tenantCode+"$"+new Date().getTime();
		try {
			bytes= RSAUtils.encryptByPublicKey(str.getBytes(),publicKey);
			return bytes;
		} catch (Exception e) {
			e.printStackTrace(); 
		}
		return null;
	}
	
	/**
	 * 生成RSA加密 Token
	 * 
	 * @MethodName: generateBytesToken 
	 * @Description: 
	 * @param platformCode
	 * @param tenantCode
	 * @param regex
	 * @return
	 * @throws
	 */
	public static byte [] generateBytesToken(String publicKey,String platformCode,String tenantCode,String regex){
		byte [] bytes=new byte[0];
		String str=platformCode+regex+tenantCode+regex+new Date().getTime();
		try {
			bytes= RSAUtils.encryptByPublicKey(str.getBytes(),publicKey);
			return bytes;
		} catch (Exception e) {
			e.printStackTrace(); 
		}
		return null;
	}
	
	/**
	 * 模拟自动生成Token
	 * 
	 * @MethodName: getToken 
	 * @Description: 
	 * @return
	 * @throws
	 */
	public  static String getToken(){
		// 开启线程同步库存数据到OMS
		/*Map<String, Object> keyMap=null;
		try {
			keyMap = RSAUtils.genKeyPair();
		} catch (Exception e) {
			e.printStackTrace();
		}
		String publicKey=null;
		try {
			publicKey = RSAUtils.getPublicKey(keyMap);
		} catch (Exception e) {
			e.printStackTrace();
		}
		String privateKey=null;
		try {
			privateKey = RSAUtils.getPrivateKey(keyMap);
		} catch (Exception e) {
			e.printStackTrace();
		}*/
		String token=null;
		try {
			String publicKey=EhcacheUtil.get("OMS_RSA_PUBLIC_KEY").toString();
			//String privateKey=EhcacheUtil.get("OMS_RSA_PRIVATE_KEY").toString();
			String platformCode = (String) EhcacheUtil.get("WAAS_PLATFORMCODE");
			String memberCode =  InitSysProperties.getUpperCaseFromEhcache(StaticProperty.WAAS_MEMBERCODE);
			token = SAASTokenManager.generateToken(publicKey, platformCode, memberCode);
			if(token!=null){
				token.replaceAll("\\n", "");
				token.replaceAll("\\r", "");
			}
		} catch (Exception e) { 
			Log.getLogger(SAASTokenManager.class).error("Token Error:"+e.getMessage());
			e.printStackTrace();
		}
		return token;
	}
	
	/**
	 * 解密Token
	 * 
	 * @MethodName: decryptToken 
	 * @Description: 
	 * @param privateKey
	 * @param token
	 * @param regex
	 * @return
	 * @throws
	 */
	public static String [] decryptToken(String privateKey,String token,String regex){
		String params[]=new String[0];
		try {
			String[] strArr = token.split(" ");
	        
	        int len = strArr.length;
	        
	        // 转回bytes
	        byte[] clone = new byte[len];
	         
	        for (int i = 0; i < len; i++) {
	             clone[i] = Byte.parseByte(strArr[i]);
	        }
	        String decryptedToken=new String(RSAUtils.decryptByPrivateKey(clone, privateKey));
			params=decryptedToken.split(regex);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return params;
	}

	/**
	 * @throws Exception 
	 * 测试函数入口
	 * 
	 * @MethodName: main
	 * @Description:
	 * @param args
	 * @throws
	 */
	public static void main(String[] args) throws Exception {
		System.out.println(Md5.getMD5Str("123456"));
		String key = "wmsadmin@10000"; 
		AccessToken accessToken = new AccessToken();
		accessToken.setToken("token==xxjisifdihfifdds");
		accessToken.setTimestamp(new Timestamp(new Date().getTime()));
		putToken(key, accessToken);
		AccessToken accessToken2 = getToken(key);
		System.out.println("token:" + accessToken2.getToken());
		System.out.println("isValidate:" + isVlidateToken(key));
		
		Map<String, Object> keyMap=RSAUtils.genKeyPair();
		String publicKey=RSAUtils.getPublicKey(keyMap);
		String privateKey=RSAUtils.getPrivateKey(keyMap);

		System.out.println("publicKey:\n"+publicKey);
		System.out.println("privateKey:\n"+privateKey);

		String token=generateToken(publicKey,"1234", "10000");
		
		byte [] bitesToken=RSAUtils.encryptByPublicKey(("1234$10000$"+new Date().getTime()).getBytes(), publicKey);
		
		System.out.println("RSA Token:"+token);
		
		System.out.println("RSA bites Token加密:"+new String(bitesToken,"UTF-8")); 
		
		System.out.println("RSA bites Token解密:"+new String(RSAUtils.decryptByPrivateKey(bitesToken, privateKey))); 
		
		System.out.println("加密:"+new String(RSAUtils.encryptByPublicKey("this is data".getBytes(), publicKey),"UTF-8"));
		System.out.println("明文:"+new String(RSAUtils.decryptByPrivateKey(RSAUtils.encryptByPublicKey("this is data".getBytes(), publicKey), privateKey)));
	}

}

本文中所述的token我并没有保存下来,而是客户端每次来了都进行验证。

Ehcache缓存请求30s验重

缓存方案你也可以用Redis来做,这里因为项目使用的是Ehcache故将就之。
ehcahe配置:ehcache.xml

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!-- 分布式缓存对象同步  采用RMI方式  官方还提供其他同步方式  此处略 -->  
  3. <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.          xsi:noNamespaceSchemaLocation="ehcache.xsd"  
  5.          updateCheck="true" monitoring="autodetect"  
  6.          dynamicConfig="true">  
  7.   
  8.     <!-- <diskStore path="java.io.tmpdir" /> -->  
  9.     <!--1. 指定除自身之外的网络群体中其他提供同步的主机列表,用“|”分开不同的主机 -->  
  10.     <!-- <cacheManagerPeerProviderFactory  
  11.         class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"  
  12.         properties="peerDiscovery=manual,rmiUrls=//10.100.0.60:40004/metaCache" /> -->  
  13.   
  14.     <!--2. 配宿主主机配置监听程序,来发现其他主机发来的同步请求 -->  
  15.     <!-- <cacheManagerPeerListenerFactory  
  16.         class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"  
  17.         properties="port=40004,socketTimeoutMillis=120000" />此处默认8000端口 -->  
  18.       
  19.     <!-- 默认缓存 -->  
  20.     <defaultCache   
  21.         maxElementsInMemory="10000"   
  22.         eternal="false"  
  23.         timeToIdleSeconds="1800"   
  24.         overflowToDisk="true"  
  25.         diskSpoolBufferSizeMB="30"   
  26.         maxElementsOnDisk="10000000"  
  27.         diskPersistent="false"   
  28.         diskExpiryThreadIntervalSeconds="120"  
  29.         memoryStoreEvictionPolicy="LRU">  
  30.     </defaultCache>  
  31.       
  32.     <!-- 缓存 -->  
  33.     <cache name="metaCache"   
  34.         maxElementsInMemory="1000"   
  35.         eternal="false"  
  36.         timeToIdleSeconds="0"   
  37.         overflowToDisk="false"  
  38.         diskSpoolBufferSizeMB="30"   
  39.         maxElementsOnDisk="10000000"  
  40.         diskPersistent="false"   
  41.         diskExpiryThreadIntervalSeconds="120"  
  42.         memoryStoreEvictionPolicy="LRU">  
  43.         <!-- <cacheEventListenerFactory  
  44.                 class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"  
  45.             properties="replicateAsynchronously=true,   
  46.                         replicatePuts=false,   
  47.                         replicateUpdates=true,  
  48.                         replicateUpdatesViaCopy=true,   
  49.                         replicateRemovals=true "/>  
  50.         <bootstrapCacheLoaderFactory  
  51.             class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"  
  52.             properties="bootstrapAsynchronously=false" /> -->  
  53.     </cache>  
  54.   
  55.     <cache name="REQUESTCACHE"   
  56.         maxElementsInMemory="100000"   
  57.         eternal="false"  
  58.         timeToIdleSeconds="30"   
  59.         timeToLiveSeconds="30"   
  60.         overflowToDisk="false"  
  61.         maxElementsOnDisk="0"   
  62.         diskPersistent="false"  
  63.         diskExpiryThreadIntervalSeconds="0"   
  64.         memoryStoreEvictionPolicy="LRU">  
  65.   
  66.     </cache>  
  67. </ehcache>  
<?xml version="1.0" encoding="UTF-8"?>
<!-- 分布式缓存对象同步  采用RMI方式  官方还提供其他同步方式  此处略 -->
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd"
         updateCheck="true" monitoring="autodetect"
         dynamicConfig="true">

 	<!-- <diskStore path="java.io.tmpdir" /> -->
	<!--1. 指定除自身之外的网络群体中其他提供同步的主机列表,用“|”分开不同的主机 -->
	<!-- <cacheManagerPeerProviderFactory
		class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
		properties="peerDiscovery=manual,rmiUrls=//10.100.0.60:40004/metaCache" /> -->

	<!--2. 配宿主主机配置监听程序,来发现其他主机发来的同步请求 -->
	<!-- <cacheManagerPeerListenerFactory
		class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
		properties="port=40004,socketTimeoutMillis=120000" />此处默认8000端口 -->
	
	<!-- 默认缓存 -->
	<defaultCache 
		maxElementsInMemory="10000" 
		eternal="false"
		timeToIdleSeconds="1800" 
		overflowToDisk="true"
		diskSpoolBufferSizeMB="30" 
		maxElementsOnDisk="10000000"
		diskPersistent="false" 
		diskExpiryThreadIntervalSeconds="120"
		memoryStoreEvictionPolicy="LRU">
	</defaultCache>
	
	<!-- 缓存 -->
	<cache name="metaCache" 
		maxElementsInMemory="1000" 
		eternal="false"
		timeToIdleSeconds="0" 
		overflowToDisk="false"
		diskSpoolBufferSizeMB="30" 
		maxElementsOnDisk="10000000"
		diskPersistent="false" 
		diskExpiryThreadIntervalSeconds="120"
		memoryStoreEvictionPolicy="LRU">
		<!-- <cacheEventListenerFactory
    			class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
 			properties="replicateAsynchronously=true, 
 						replicatePuts=false, 
 						replicateUpdates=true,
 						replicateUpdatesViaCopy=true, 
 						replicateRemovals=true "/>
		<bootstrapCacheLoaderFactory
			class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"
			properties="bootstrapAsynchronously=false" /> -->
	</cache>

	<cache name="REQUESTCACHE" 
		maxElementsInMemory="100000" 
		eternal="false"
		timeToIdleSeconds="30" 
		timeToLiveSeconds="30" 
		overflowToDisk="false"
		maxElementsOnDisk="0" 
		diskPersistent="false"
		diskExpiryThreadIntervalSeconds="0" 
		memoryStoreEvictionPolicy="LRU">

	</cache>
</ehcache>

Ehcache工具类:

  1. package com.wlyd.fmcgwms.util.ehcache;  
  2.   
  3. import net.sf.ehcache.Cache;  
  4. import net.sf.ehcache.CacheManager;  
  5. import net.sf.ehcache.Element;  
  6.   
  7. /** 
  8.  * ehcache 缓存工具类 
  9.  *  
  10.  * @packge com.wlyd.fmcgwms.util.ehcache.EhcacheUtil 
  11.  * @date 2016年4月28日 下午4:11:27 
  12.  * @author pengjunlin 
  13.  * @comment cacheName在ehcache.xml中配置 
  14.  * @update 添加注释,代码重构删除原有类com。wlyd.fmcgwms.util.ehcache.EhcacheUtilOverWrite 
  15.  */  
  16. public class EhcacheUtil {  
  17.   
  18.     public static CacheManager manager = CacheManager.create();// 缓存管理  
  19.   
  20.     public static String cacheName = "metaCache";// 缓存名称  
  21.   
  22.     /** 
  23.      * 获取缓存对象 
  24.      *  
  25.      * @MethodName: get 
  26.      * @Description: 
  27.      * @param key 
  28.      * @return 
  29.      * @throws 
  30.      */  
  31.     public static Object get(Object key) {  
  32.         Cache cache = manager.getCache(cacheName);  
  33.         if (cache != null) {  
  34.             Element element = cache.get(key);  
  35.             if (element != null) {  
  36.                 return element.getObjectValue();  
  37.             }  
  38.         }  
  39.         return null;  
  40.     }  
  41.   
  42.     /** 
  43.      * 获取缓存对象 
  44.      *  
  45.      * @MethodName: get 
  46.      * @Description: 
  47.      * @param cacheName 
  48.      * @param key 
  49.      * @return 
  50.      * @throws 
  51.      */  
  52.     public static Object get(String cacheName, Object key) {  
  53.         Cache cache = manager.getCache(cacheName);  
  54.         if (cache != null) {  
  55.             Element element = cache.get(key);  
  56.             if (element != null) {  
  57.                 return element.getObjectValue();  
  58.             }  
  59.         }  
  60.         return null;  
  61.     }  
  62.   
  63.     /** 
  64.      * 添加缓存对象 
  65.      *  
  66.      * @MethodName: put 
  67.      * @Description: 
  68.      * @param key 
  69.      * @param value 
  70.      * @throws 
  71.      */  
  72.     public static void put(Object key, Object value) {  
  73.         Cache cache = manager.getCache(cacheName);  
  74.         if (cache != null) {  
  75.             cache.put(new Element(key, value));  
  76.         }  
  77.     }  
  78.   
  79.     /** 
  80.      * 添加缓存对象 
  81.      *  
  82.      * @MethodName: put 
  83.      * @Description: 
  84.      * @param cacheName 
  85.      * @param key 
  86.      * @param value 
  87.      * @throws 
  88.      */  
  89.     public static void put(String cacheName, Object key, Object value) {  
  90.         Cache cache = manager.getCache(cacheName);  
  91.         if (cache != null) {  
  92.             cache.put(new Element(key, value));  
  93.         }  
  94.     }  
  95.   
  96.     /** 
  97.      * 移出缓存对象 
  98.      *  
  99.      * @MethodName: remove 
  100.      * @Description: 
  101.      * @param key 
  102.      * @return 
  103.      * @throws 
  104.      */  
  105.     public static boolean remove(Object key) {  
  106.         Cache cache = manager.getCache(cacheName);  
  107.         if (cache != null) {  
  108.             return cache.remove(key);  
  109.         }  
  110.         return false;  
  111.     }  
  112.   
  113.     /** 
  114.      * 移除缓存对象 
  115.      *  
  116.      * @MethodName: remove 
  117.      * @Description: 
  118.      * @param cacheName 
  119.      * @param key 
  120.      * @return 
  121.      * @throws 
  122.      */  
  123.     public static boolean remove(String cacheName, Object key) {  
  124.         Cache cache = manager.getCache(cacheName);  
  125.         if (cache != null) {  
  126.             return cache.remove(key);  
  127.         }  
  128.         return false;  
  129.     }  
  130. }  
package com.wlyd.fmcgwms.util.ehcache;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

/**
 * ehcache 缓存工具类
 * 
 * @packge com.wlyd.fmcgwms.util.ehcache.EhcacheUtil
 * @date 2016年4月28日 下午4:11:27
 * @author pengjunlin
 * @comment cacheName在ehcache.xml中配置
 * @update 添加注释,代码重构删除原有类com。wlyd.fmcgwms.util.ehcache.EhcacheUtilOverWrite
 */
public class EhcacheUtil {

	public static CacheManager manager = CacheManager.create();// 缓存管理

	public static String cacheName = "metaCache";// 缓存名称

	/**
	 * 获取缓存对象
	 * 
	 * @MethodName: get
	 * @Description:
	 * @param key
	 * @return
	 * @throws
	 */
	public static Object get(Object key) {
		Cache cache = manager.getCache(cacheName);
		if (cache != null) {
			Element element = cache.get(key);
			if (element != null) {
				return element.getObjectValue();
			}
		}
		return null;
	}

	/**
	 * 获取缓存对象
	 * 
	 * @MethodName: get
	 * @Description:
	 * @param cacheName
	 * @param key
	 * @return
	 * @throws
	 */
	public static Object get(String cacheName, Object key) {
		Cache cache = manager.getCache(cacheName);
		if (cache != null) {
			Element element = cache.get(key);
			if (element != null) {
				return element.getObjectValue();
			}
		}
		return null;
	}

	/**
	 * 添加缓存对象
	 * 
	 * @MethodName: put
	 * @Description:
	 * @param key
	 * @param value
	 * @throws
	 */
	public static void put(Object key, Object value) {
		Cache cache = manager.getCache(cacheName);
		if (cache != null) {
			cache.put(new Element(key, value));
		}
	}

	/**
	 * 添加缓存对象
	 * 
	 * @MethodName: put
	 * @Description:
	 * @param cacheName
	 * @param key
	 * @param value
	 * @throws
	 */
	public static void put(String cacheName, Object key, Object value) {
		Cache cache = manager.getCache(cacheName);
		if (cache != null) {
			cache.put(new Element(key, value));
		}
	}

	/**
	 * 移出缓存对象
	 * 
	 * @MethodName: remove
	 * @Description:
	 * @param key
	 * @return
	 * @throws
	 */
	public static boolean remove(Object key) {
		Cache cache = manager.getCache(cacheName);
		if (cache != null) {
			return cache.remove(key);
		}
		return false;
	}

	/**
	 * 移除缓存对象
	 * 
	 * @MethodName: remove
	 * @Description:
	 * @param cacheName
	 * @param key
	 * @return
	 * @throws
	 */
	public static boolean remove(String cacheName, Object key) {
		Cache cache = manager.getCache(cacheName);
		if (cache != null) {
			return cache.remove(key);
		}
		return false;
	}
}



测试方法:

  1. package fmcgwms;  
  2.   
  3.   
  4. import org.apache.http.client.methods.HttpGet;  
  5. import org.junit.Test;  
  6. import org.junit.runner.RunWith;  
  7. import org.springframework.test.context.ContextConfiguration;  
  8. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
  9. import com.alibaba.fastjson.JSONObject;  
  10. import com.wlyd.fmcgwms.util.Md5;  
  11. import com.wlyd.fmcgwms.util.SAASTokenManager;  
  12. import com.wlyd.fmcgwms.util.StaticProperty;  
  13. import com.wlyd.fmcgwms.util.api.APIHttpClient;  
  14. import com.wlyd.fmcgwms.util.api.RSAUtils;  
  15. import com.wlyd.fmcgwms.util.ehcache.EhcacheUtil;  
  16. /** 
  17.  * 开放接口对外模拟测试 
  18.  * @package fmcgwms.OpenApiTest 
  19.  * @date   2017年3月15日  下午5:51:03 
  20.  * @author pengjunlin 
  21.  * @comment    
  22.  * @update 
  23.  */  
  24. @RunWith(SpringJUnit4ClassRunner.class)  
  25. @ContextConfiguration(locations = "classpath:applicationContext.xml")  
  26. public class OpenApiTest {  
package fmcgwms;


import org.apache.http.client.methods.HttpGet;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.alibaba.fastjson.JSONObject;
import com.wlyd.fmcgwms.util.Md5;
import com.wlyd.fmcgwms.util.SAASTokenManager;
import com.wlyd.fmcgwms.util.StaticProperty;
import com.wlyd.fmcgwms.util.api.APIHttpClient;
import com.wlyd.fmcgwms.util.api.RSAUtils;
import com.wlyd.fmcgwms.util.ehcache.EhcacheUtil;
/**
 * 开放接口对外模拟测试
 * @package fmcgwms.OpenApiTest
 * @date   2017年3月15日  下午5:51:03
 * @author pengjunlin
 * @comment   
 * @update
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class OpenApiTest {
  1.       @Test  
  2. ublic void testEchcacheToTimeout(){  
  3.   
  4.   
  5. String requestSequence=Md5.getMD5Str("localhost&interface&opt_type&uniquecode");  
  6.   
  7. System.out.println(">>>>>原始MD5串:"+requestSequence);   
  8.   
  9. EhcacheUtil.put(StaticProperty.REQUESTCACHE, requestSequence, requestSequence);  
  10.   
  11. System.out.println(">>>>>缓存:"+EhcacheUtil.get(StaticProperty.REQUESTCACHE, requestSequence));   
  12.   
  13. try {  
  14.     Thread.sleep(31000);  
  15. catch (InterruptedException e) {  
  16.     e.printStackTrace();  
  17. }  
  18. System.out.println(">>>>>30s后缓存:"+EhcacheUtil.get(StaticProperty.REQUESTCACHE, requestSequence));   
  19.   
  20. try {  
  21.     Thread.sleep(3000);  
  22. catch (InterruptedException e) {  
  23.     e.printStackTrace();  
  24. }  
        @Test
	public void testEchcacheToTimeout(){
		
		
		String requestSequence=Md5.getMD5Str("localhost&interface&opt_type&uniquecode");
		
		System.out.println(">>>>>原始MD5串:"+requestSequence); 
		
		EhcacheUtil.put(StaticProperty.REQUESTCACHE, requestSequence, requestSequence);
		
		System.out.println(">>>>>缓存:"+EhcacheUtil.get(StaticProperty.REQUESTCACHE, requestSequence)); 
		
		try {
			Thread.sleep(31000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(">>>>>30s后缓存:"+EhcacheUtil.get(StaticProperty.REQUESTCACHE, requestSequence)); 
		
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		
	}


Ehcache的输出:

  1. >>>>>原始MD5串:cae76d65fc5c47875730ed35a262abb4  
  2. >>>>>缓存:cae76d65fc5c47875730ed35a262abb4  
  3. 2017-03-16 15:13:49,647 [net.sf.ehcache.CacheManager@2f1a74d1] INFO  [net.sf.ehcache.util.UpdateChecker] - This is the latest GA release.  
  4. 2017-03-16 15:14:00,016 [SpringJobSchedulerFactoryBean_Worker-1] ERROR [com.wlyd.fmcgwms.persistence.beans.platform.job.CycleFetchInterfaceInfoTaskJob] - >>>WMS-WAAS接口定时任务<<启动失败---fetch----:请设置WAAS_API_ISENABLE=true  
  5. 2017-03-16 15:14:00,016 [SpringJobSchedulerFactoryBean_Worker-2] ERROR [com.wlyd.fmcgwms.persistence.beans.platform.job.CycleSendInterfaceInfoTaskJob] - >>>WMS-WAAS定时任务<<启动失败----send---:请设置WAAS_API_ISENABLE=true  
  6. >>>>>30s后缓存:null  
>>>>>原始MD5串:cae76d65fc5c47875730ed35a262abb4
>>>>>缓存:cae76d65fc5c47875730ed35a262abb4
2017-03-16 15:13:49,647 [net.sf.ehcache.CacheManager@2f1a74d1] INFO  [net.sf.ehcache.util.UpdateChecker] - This is the latest GA release.
2017-03-16 15:14:00,016 [SpringJobSchedulerFactoryBean_Worker-1] ERROR [com.wlyd.fmcgwms.persistence.beans.platform.job.CycleFetchInterfaceInfoTaskJob] - >>>WMS-WAAS接口定时任务<<启动失败---fetch----:请设置WAAS_API_ISENABLE=true
2017-03-16 15:14:00,016 [SpringJobSchedulerFactoryBean_Worker-2] ERROR [com.wlyd.fmcgwms.persistence.beans.platform.job.CycleSendInterfaceInfoTaskJob] - >>>WMS-WAAS定时任务<<启动失败----send---:请设置WAAS_API_ISENABLE=true
>>>>>30s后缓存:null

转载自:http://blog.csdn.net/boonya/article/details/62423737

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值