怎么在maven项目中引用本地Java类库

去年实习的时候听说过maven,听说功能特别强大,后来就抽时间自学了一下,尤其感叹于其自动引入jar包的功能,真是太棒了,终于某种程度上把程序猿从classnotfoundexception中解脱出来了,也一定程度上解决了jar包冲突以及版本的问题,但在这几天玩微信开发的时候遇到了一个问题: 我的微信后台是托管到SAE上的,但SAE官方处于安全考虑,把XStream中sun.misc.Unsafe类禁用掉了,这就导致了一个问题XStream不能用了,CSDN知名博主刘峰老师发现了这个问题,于是柳峰老师修改了一下这个类库,其实很简单也即在XStream官方网站http://xstream.codehaus.org/上找到了xstream-1.3.1.jar对应的源码,导入到Eclipse,然后借助Eclipse强大的搜索功能,很快找到了使用sun.misc.Unsafe的类,我尝试将这些类删除或者修改它们的实现,避免使用sun.misc.Unsafe类,最终得到了一个新的jar包,将其命名为xstream-1.3.1-sae-liufeng.jar,用它替换以前项目中使用的xstream-1.3.1.jar,最终项目再次顺利地运行在SAE上,这个方法虽简单粗暴,但确实有效,但是也给我带来了一个问题,我的项目是maven搭建的,那么我怎么把这个jar引入到我的项目中呢? 经过查询资料原来我们可以把本地的jar文件安装到本地repository中,这就完美解决这个问题了,那么怎么把本地的jar文件安装到本地repository中呢?强大的maven当然给我们提供了这个方法: mvn install:install-file -Dfile=xstream-1.3.1-sae-liufeng.jar -DgroupId=cn.bridgeli -DartifactId=xstream-bridgeli -Dversion=1.3.1 -Dpackaging=jar -DgeneratePom=true 相信这条命令不用我解释了,看这篇文章的人一定可以自己看懂的。需要说明的是:执行完这条命令,我们本地的jar就被安装到本地库了文件夹的结构是:cnbridgelixstream-bridgeli1.3.1,即DgroupId + DartifactId + Dversion,文件的名字是:xstream-bridgeli-1.3.1.jar,即:DartifactId + Dversion + . + Dpackaging,然后只需要在我们的项目中引用就可以了,引用的代码: <dependency> <groupId>cn.bridgeli</groupId> <artifactId>xstream-bridgeli</artifactId> <version>1.3.1</version> </dependency> 其中groupId、artifactId、version分别于刚才的命令相对应。 参考:http://blog.csdn.net/youhaodeyi/article/details/1729116 注:我为什么没有采取方法参考资料中的方法二,原因有三: 这个jar并没有加入到本地库中,不利于我们对自己资料的管理 scope被设置成system并不被maven官方所推荐 据有网友说scope被设置成system,那么这个类库并不会被打到war中,这个我没有测试

October 14, 2014 · 1 min · 33 words · Bridge Li

长链接(URL)转短链接(URL)

现在微博越来越流行,大家有事没事都喜欢在微博上说两句,但由于140字的限制,给我们在分析一些长链接的时候,带来了诸多不便,好在微博有自动缩短URL的功能,那我们是否可以自己缩短一个URL呢?答案是肯定的,下面就给出利用百度的API缩短URL的简单例子 package cn.bridgeli.longurl2short; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; public class LongURL2Short { public static String httpRequest(String outputStr) { StringBuffer buffer = null; try { // 建立连接 URL url = new URL("http://dwz.cn/create.php"); HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection(); httpUrlConn.setDoInput(true); httpUrlConn.setDoOutput(true); httpUrlConn.setUseCaches(false); httpUrlConn.setRequestMethod("POST"); if (null != outputStr) { OutputStream outputStream = httpUrlConn.getOutputStream(); // 注意编码格式,防止中文乱码 outputStr = "url=" + outputStr; outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 获取输入流 InputStream inputStream = httpUrlConn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); // 读取返回结果 buffer = new StringBuffer(); String str = null; while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } // 释放资源 bufferedReader.close(); inputStreamReader.close(); inputStream.close(); httpUrlConn.disconnect(); } catch (Exception e) { e.printStackTrace(); } return buffer.toString(); } } package cn.bridgeli.longurl2short; import org.junit.Test; import com.google.gson.Gson; public class LongUrl2ShortTest { @Test public void testHttpRequest() { String str = LongURL2Short.httpRequest("http://mp.weixin.qq.com/wiki/index.php?title=%E9%95%BF%E9%93%BE%E6%8E%A5%E8%BD%AC%E7%9F%AD%E9%93%BE%E6%8E%A5%E6%8E%A5%E5%8F%A3"); Gson gson = new Gson(); ShortUrl shortUrl = gson.fromJson(str, ShortUrl.class); System.out.println(shortUrl.getTinyurl()); } } package cn.bridgeli.longurl2short; public class ShortUrl { private String tinyurl; public String getTinyurl() { return tinyurl; } public void setTinyurl(String tinyurl) { this.tinyurl = tinyurl; } } 注:httpRequest方法和前一篇文章 如何用https协议发起一个post请求 极其类似,本质是一样的,另外该方法经本人测试会有bug:当长URL是.cn时,转换不成功,目前原因还没找到,猜测是由于转化后的URL的后缀也是.cn的原因,具体在测试。 ...

October 9, 2014 · 1 min · 183 words · Bridge Li

Jsoup在简单防御XSS攻击和网络爬虫的简单应用

跨站攻击一直是web安全的一大问题,稍有不慎就会中招,各种防不胜防,今天在网上闲逛,发现一个第三方JAR不仅可以简单防御还可以爬取网页,所以写一篇小文以记之,也供有需要的人参考。 预防跨站攻击代码如下: @Test public void testJsoup() { String unsafe = "<p><a href=&#8217;http://example.com/&#8217; onclick=&#8217;stealCookies()&#8217;>Link,<alert>0</alert></a></p>"; String safe = Jsoup.clean(unsafe, Whitelist.basic()); System.out.println(safe); } 其中 unsafe 就是用户提交的数据,其中包含 onclick 和 alert 可能会有害,需要过滤,而 Whitelist.basic() 则是过滤规则,safe 就是过滤后的安全数据。 在网络爬虫方面,曾听北京尚学堂马士兵老师讲过一次正则表达式的简单应用:抓取网页上的邮箱地址,有很多人记不住,但有了这个第三方工具,则轻松很多,他可以根据一个URL直接去抓取,省了不少事,猜测内部也是用正则实现的。 网络爬虫代码如下: @Test public void testSpider() { String url = "http://www.rijiben.com/"; Document doc = null; try { doc = Jsoup.connect(url).get(); } catch (IOException e) { e.printStackTrace(); } if (null != doc) { Elements listrens = doc.getElementsByAttributeValue("class", "listren"); for (Element listren : listrens) { String text = listren.select("li").select("a").html(); System.out.println(text); } } else { System.err.println("网络出异常!"); } } 这是抓取日记本上面,历史上的今日的例子,老夫打算将来用到自己的微信公众号上面,怎么样,是不是很简单? ...

September 30, 2014 · 1 min · 90 words · Bridge Li

如何用https协议发起一个post请求

这两天研究了微信公众号的开发,发现微信做的太好了,前景太可怕了,如果按照这个趋势,那么将来手机上也许只装一个微信客户端也许就可以做任何事了,其中微信公众号开发自定义菜单时,微信要求用https协议post到微信服务器一个JSON字符串,这里面有两个难点:1. https协议,2. 如何post数据到微信服务器。刚好csdn博主柳峰,有一篇文章是讲解这个的,所以就拿来参考一下,具体代码如下: import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; public class MyX509TrustManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } } 这个是说,相信所有的安全证书,无论是不是安全机构颁发 public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) { JSONObject jsonObject = null; StringBuffer buffer = new StringBuffer(); try { // 创建SSLContext对象,并使用我们指定的信任管理器初始化 TrustManager[] tm = { new MyX509TrustManager() }; SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom()); // 从上述SSLContext对象中得到SSLSocketFactory对象 SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection(); httpUrlConn.setSSLSocketFactory(ssf); httpUrlConn.setDoOutput(true); httpUrlConn.setDoInput(true); httpUrlConn.setUseCaches(false); // 设置请求方式(GET/POST) httpUrlConn.setRequestMethod(requestMethod); if ("GET".equalsIgnoreCase(requestMethod)) { httpUrlConn.connect(); } // 当有数据需要提交时 if (null != outputStr) { OutputStream outputStream = httpUrlConn.getOutputStream(); // 注意编码格式,防止中文乱码 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 将返回的输入流转换成字符串 InputStream inputStream = httpUrlConn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); // 释放资源 inputStream.close(); inputStream = null; httpUrlConn.disconnect(); jsonObject = JSONObject.fromObject(buffer.toString()); } catch (ConnectException ce) { log.error("Weixin server connection timed out."); } catch (Exception e) { log.error("https request error:{}", e); } return jsonObject; } 这个就是通过https协议向某一个URL通过post或者get提交一个JSON字符串。另外在编程中还有一个常见的向某一个URL请求数据,代码如下: ...

September 29, 2014 · 2 min · 274 words · Bridge Li

如何配置一个一键启动的绿色Java web项目

我们知道部署J2EE项目,要首先安装JDK,配环境变量,在安装tomcat,然后MySQL数据库(当然也可以是其他任何你喜欢的数据库),把项目打一个war包放到tomcat的webapps包下面,启动tomcat就可以了,但在某些情况下,例如测试美工等,尤其是美工他们的电脑很多时候没必要安装这些乱七八糟的东西,那么我们是否可以不安装这些东西,而让让美工们的电脑跑项目呢?答案是可以的,我们只需要拷贝一个JDK、MySQL、tomcat到美工的电脑,再把项目拷到tomcat的webapps下,写一个bat的文件,让bat文件设置JDK目录、安装MySQL的服务,调用tomcat启动的命令就可以了,srartup.bat代码如下: set HOME=C:Layout set JAVA_HOME=%HOME%jdk set CLASSPATH=%JAVA_HOME%lib set CATALINA_HOME=%HOME%tomcat set CATALINA_BASE=%HOME%tomcat set MYSQL_HOME=%HOME%mysql set PATH=%PATH%;%JAVA_HOME%bin;%MYSQL_HOME%bin; taskkill /f /im explorer.exe start explorer.exe RunDll32.exe USER32.DLL,UpdatePerUserSystemParameters echo start lms_mysql on localhost mysqld &#8211;install lms_mysql &#8211;defaults-file=%MYSQL_HOME%my.ini net start lms_mysql echo start tomcat on localhost @Rem Run Tomcat&#8230; Call %CATALINA_HOME%binstartup.bat shutdown.bat @echo off echo stop lms_mysql net stop lms_mysql mysqld &#8211;remove lms_mysql echo on Call %CATALINA_HOME%binshutdown.bat

September 20, 2014 · 1 min · 61 words · Bridge Li

反射的简单应用:解决微信开发中if-else过多的问题

前一段时间,闲着无聊玩微信开发,遇到一个问题:当关注者向公众号发送消息,请求一些服务时,由于是文本消息,所以当公众号拿到消息内容时,必须判断消息以什么打头,即: String content = requestMap.get("Content").trim(); if ("?".equals(content) || "?".equals(content)) { respContent = "您好,我是生活小助手,请根据提示,回复内容选择服务:nn1 回复“天气”获取天气帮助n2 回复“歌曲”获取歌曲帮助n3 回复“公交”获取歌曲帮助n4 回复“火车”获取歌曲帮助"; } else if (content.startsWith("歌曲")) { //TODO } else if (content.startsWith("天气")) { //TODO } else if (content.startsWith("物流")) { //TODO } else if (content.startsWith("公交")) { //TODO } else if (content.startsWith("火车")) { //TODO } else { respContent = "亲,很抱歉,由于功能还不够完善,尚不能处理您回复的信息,请回复“?”显示主菜单,获取帮助,有此给您带来的不便,还请见谅!"; } 来判断何种服务,调用具体的接口来处理,当你的功能越来越完善时,会导致if-else越来越多,多的会自己都搞不清了,另外这个方法也会越来越大,显然不是非常符合面向对象的单一职责原则。那么有没用一个比较好的方法来解决这个问题呢?我曾经的项目经理Zack曾经说过,上天不会这么惩罚一个后期维护代码的人,所以答案是勘定有,今天老夫就给大家带来一个解决方法,需要说明的是:这不是老夫的原创,是老夫研究捷微源码的找到的方法,老夫在捷微方法的基础上做了一些修改,所以先感谢捷微,感谢捷微的开发人员。最后需要说明的是,这个方法也不是很完善,如果有人参考的话,老样子,请做具体修改,但逻辑老夫保证不会有错。 @Override public BaseMessage handleText(String content, String fromUsername, String toUsername) { String respContent = null; BaseMessage baseMessage = null; if ("?".equals(content) || "?".equals(content)) { respContent = "您好,我是生活小助手,请根据提示,回复内容选择服务:nn1 回复“天气”获取天气帮助n2 回复“歌曲”获取歌曲帮助n3 回复“公交”获取公交帮助n4 回复“火车”获取火车帮助"; } else { List<WeixinExpandconfigEntity> weixinExpandconfigEntities = new ArrayList<WeixinExpandconfigEntity>(); boolean isFind = false;// 是否找到关键字信息 for (WeixinExpandconfigEntity weixinExpandconfigEntity : weixinExpandconfigEntities) { // 如果已经找到关键字并处理业务,结束循环。 if (isFind) { break;// 如果找到结束循环 } String[] keys = weixinExpandconfigEntity.getKeyword().split(","); for (String k : keys) { if (content.indexOf(k) != -1) { String className = weixinExpandconfigEntity.getClassname(); String returnType = weixinExpandconfigEntity.getReturnType(); KeyService keyService = null; try { keyService = (KeyService) Class.forName(className).newInstance(); baseMessage = (BaseMessage) Class.forName(returnType).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } keyService.excute(baseMessage, content.substring(2)); isFind = true; break; } } } } if (baseMessage == null) { TextMessage textMessage = new TextMessage(); textMessage.setContent(respContent); baseMessage = textMessage; } baseMessage.setToUserName(fromUsername); baseMessage.setFromUserName(toUsername); baseMessage.setCreateTime(new Date().getTime()); baseMessage.setFuncFlag(0); return baseMessage; }

September 15, 2014 · 1 min · 201 words · Bridge Li

使用JDK自带的工具解析XML文档

XML和JSON字符串的解析,是Java程序猿的必备技能,关于XML和JSON如何解析,网上的例子可以说是一拉一大把,解析JSON的有什么GSON、json-lib等一大批做得非常好的第三方工具,解析XML的也有什么DOM4J、JDOM、SAX、DOM等等,今天大桥就给大家展示一下如何有JDK自己解析XML,废话不多说,代码如下: package cn.bridgeli.parsexmldemo.parsexml; import java.io.FileNotFoundException; import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class ParseXml { public void parserXml(String fileName) { try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document document = db.parse(fileName); NodeList rootNode = document.getChildNodes(); parseNode(rootNode.item(0)); } catch (FileNotFoundException e) { System.out.println(e.getMessage()); } catch (ParserConfigurationException e) { System.out.println(e.getMessage()); } catch (SAXException e) { System.out.println(e.getMessage()); } catch (IOException e) { System.out.println(e.getMessage()); } } public void parseNode(Node node) { if (node == null) { return; } // if not have child if (!node.hasChildNodes()) { NamedNodeMap attrs = node.getAttributes(); if (attrs != null) { for (int i = 0; i < attrs.getLength(); i++) { Attr attribute = (Attr) attrs.item(i); System.out.print("AttributeName===" + attribute.getName() + " AttributeValue===" + attribute.getValue()); } } String str = node.getTextContent().toString().replaceAll("n", "").replaceAll(" ", ""); if (!str.equals("")) { System.out.println("TextContent ===" + str); } } else { // get attributes NamedNodeMap attrs = node.getAttributes(); if (attrs != null) { for (int i = 0; i < attrs.getLength(); i++) { Attr attribute = (Attr) attrs.item(i); System.out.println("AttributeName===" + attribute.getName() + " AttributeValue===" + attribute.getValue()); } } // get child node NodeList nodes = node.getChildNodes(); for (int j = 0; j < nodes.getLength(); j++) { parseNode(nodes.item(j)); } } } } 具体可以参考: ...

September 14, 2014 · 2 min · 216 words · Bridge Li

Java在线支付(利用易宝支付的接口)

随着现在电商等平台如雨后春笋般的发展,在线支付越来越火,各种移动端的支付也是层出不穷,什么微信支付、微博支付等等,其实万变不离其宗,今天大桥就给大家讲解一个Java利用易宝支付在线支付的例子,当然首先要感谢一些传智播客的黎活明老师。 在线支付的第一步,也就是用户在线支付看到的第一个页面,这个页面里主要包含三项:订单号、金额、所选银行,这三个缺一不可。 <%@ page language="java" import="java.util.*" pageEncoding="GBK"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> &nbsp; <title>支付第一步,选择支付银行</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> </head> &nbsp; <body> <table width="960" border="0" align="center"> <tr> <td width="536" valign="top"> <form action="${pageContext.request.contextPath}/servlet/yeepay/PaymentRequestServlet" method="post" name="paymentform"> <table width="100%" border="0"> <tr> <td height="30" colspan="4"> <table width="100%" height="50" border="0" cellpadding="0" cellspacing="1" bgcolor="#A2E0FF"> <tr> <td align="center" bgcolor="#F7FEFF"> <h3>订单号: <INPUT TYPE="text" NAME="orderid"> 应付金额:¥<INPUT TYPE="text" NAME="amount" size="6">元 </h3> </td> </tr> </table> </td> </tr> <tr> <td colspan="4"></td> </tr> <tr> <td height="30" colspan="4" bgcolor="#F4F8FF"> <span class="STYLE3">请您选择在线支付银行</span> </td> </tr> <tr> <td width="26%" height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="CMBCHINA-NET">招商银行 </td> <td width="25%" height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="ICBC-NET">工商银行 </td> <td width="25%" height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="ABC-NET">农业银行 </td> <td width="24%" height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="CCB-NET">建设银行 </td> </tr> <tr> <td height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="CMBC-NET">中国民生银行总行 </td> <td height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="CEB-NET">光大银行 </td> <td height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="BOCO-NET">交通银行 </td> <td height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="SDB-NET">深圳发展银行 </td> </tr> <tr> <td height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="BCCB-NET">北京银行 </td> <td height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="CIB-NET">兴业银行 </td> <td height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="SPDB-NET">上海浦东发展银行 </td> <td><INPUT TYPE="radio" NAME="pd_FrpId" value="ECITIC-NET">中信银行 </td> </tr> <tr> <td colspan="4"></td> </tr> <tr> <td colspan="4" align="center"> <input type="submit" value=" 确认支付 "/> </td> </tr> </table> </form> </td> <td colspan="2" valign="top"> <div class="divts"> <table width="400" border="0" align="center" cellpadding="5" cellspacing="0"> </table> </div> <div id="blankmessage"></div> </td> </tr> <tr> <td></td> <td width="290"></td> <td width="120"></td> </tr> </table> </body> </html> 取得前台提交的三个参数,并封装易宝支付所需的其他参数,并把这些参数放到Request对象中。 package cn.bridgeli.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.bridgeli.utils.ConfigInfo; import cn.bridgeli.utils.PanymentUtil; /** * 发起支付请求 */ public class PaymentRequestServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("GBK"); String orderid = request.getParameter("orderid");//订单号 String amount = request.getParameter("amount");//支付金额 String pd_FrpId = request.getParameter("pd_FrpId");//选择的支付银行 String p1_MerId = ConfigInfo.getValue("p1_MerId"); String keyValue = ConfigInfo.getValue("keyValue"); String merchantCallbackURL = ConfigInfo.getValue("merchantCallbackURL"); String messageType = "Buy"; // 请求命令,在线支付固定为Buy String currency = "CNY"; // 货币单位 String productDesc = ""; // 商品描述 String productCat = ""; // 商品种类 String productId = ""; // 商品ID String addressFlag = "0"; // 需要填写送货信息 0:不需要 1:需要 String sMctProperties = ""; // 商家扩展信息 String pr_NeedResponse = "0"; // 应答机制 String md5hmac = PanymentUtil.buildHmac(messageType, p1_MerId, orderid, amount, currency, productId, productCat, productDesc, merchantCallbackURL, addressFlag, sMctProperties, pd_FrpId, pr_NeedResponse, keyValue); request.setAttribute("messageType", messageType); request.setAttribute("merchantID", p1_MerId); request.setAttribute("orderId", orderid); request.setAttribute("amount", amount); request.setAttribute("currency", currency); request.setAttribute("productId", productId); request.setAttribute("productCat", productCat); request.setAttribute("productDesc", productDesc); request.setAttribute("merchantCallbackURL", merchantCallbackURL); request.setAttribute("addressFlag", addressFlag); request.setAttribute("sMctProperties", sMctProperties); request.setAttribute("frpId", pd_FrpId); request.setAttribute("pr_NeedResponse", pr_NeedResponse); request.setAttribute("hmac", md5hmac); request.getRequestDispatcher("/WEB-INF/page/connection.jsp").forward(request, response); } } 因为易宝支付所需的数据都是通过表单提交的,所以取得上一步封装的各个参数,通过一个表单提交到易宝支付提供的接口。所以表单的action应该是易宝支付的接口。 <%@ page language="java" pageEncoding="GBK"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>发起支付请求</title> &nbsp; <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> </head> &nbsp; <body onload="javascript:document.forms[0].submit()"> <!&#8211; http://tech.yeepay.com:8080/robot/debug.action &#8211;> <form name="yeepay" action="https://www.yeepay.com/app-merchant-proxy/node" method=&#8217;post&#8217;> <input type=&#8217;hidden&#8217; name=&#8217;p0_Cmd&#8217; value="${messageType}"> <!&#8211; 请求命令,在线支付固定为Buy &#8211;> <input type=&#8217;hidden&#8217; name=&#8217;p1_MerId&#8217; value="${merchantID}"> <!&#8211; 商家ID &#8211;> <input type="hidden" name="p2_Order" value="${orderId}"> <!&#8211; 商家的交易定单号 &#8211;> <input type=&#8217;hidden&#8217; name=&#8217;p3_Amt&#8217; value="${amount}"> <!&#8211; 订单金额 &#8211;> <input type=&#8217;hidden&#8217; name=&#8217;p4_Cur&#8217; value="${currency}"> <!&#8211; 货币单位 &#8211;> <input type=&#8217;hidden&#8217; name=&#8217;p5_Pid&#8217; value="${productId}"> <!&#8211; 商品ID &#8211;> <input type=&#8217;hidden&#8217; name=&#8217;p6_Pcat&#8217; value="${productCat}"> <!&#8211; 商品种类 &#8211;> <input type=&#8217;hidden&#8217; name=&#8217;p7_Pdesc&#8217; value="${productDesc}"> <!&#8211; 商品描述 &#8211;> <input type=&#8217;hidden&#8217; name=&#8217;p8_Url&#8217; value="${merchantCallbackURL}"> <!&#8211; 交易结果通知地址 &#8211;> <input type=&#8217;hidden&#8217; name=&#8217;p9_SAF&#8217; value="${addressFlag}"> <!&#8211; 需要填写送货信息 0:不需要 1:需要 &#8211;> <input type=&#8217;hidden&#8217; name=&#8217;pa_MP&#8217; value="${sMctProperties}"> <!&#8211; 商家扩展信息 &#8211;> <input type=&#8217;hidden&#8217; name=&#8217;pd_FrpId&#8217; value="${frpId}"> <!&#8211; 银行ID &#8211;> <!&#8211; 应答机制 为“1”: 需要应答机制;为“0”: 不需要应答机制 &#8211;> <input type="hidden" name="pr_NeedResponse" value="0"> <input type=&#8217;hidden&#8217; name=&#8217;hmac&#8217; value="${hmac}"> <!&#8211; MD5-hmac验证码 &#8211;> </form> </body> </html> 编写易宝支付处理上一步处理数据完成后所返回的后台处理类(这个处理类必须在公网上,即使是测试程序,即可以访问的),并根据易宝支付所返回的数据,并完成一下几件事(也就是接收易宝支付处理结果的类): (1). 判断支付的结果 ...

September 13, 2014 · 7 min · 1441 words · Bridge Li

动态代理模拟Spring的AOP

这两天研究了一下Java的动态代理,自己闲着无聊,用动态代理模拟了一下Spring的AOP,代码如下,当然真正的Spring是直接操作二进制文件,很复杂,有兴趣的可以自己研究下。 package cn.bridgeli.aop; public interface UserService { void addUser(); } package cn.bridgeli.aop; public class UserServiceImpl implements UserService { public void addUser() { System.out.println("User add&#8230;"); } } package cn.bridgeli.aop; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class UserServiceProxy implements InvocationHandler { private UserService userService; public UserServiceProxy(UserService userService) { this.userService = userService; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("User add start&#8230;"); Object object = method.invoke(userService, args); System.out.println("User add end&#8230;"); return object; } } package cn.bridgeli.aop; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import org.junit.Test; public class UserServiceTest { @Test public void testAddUser() { UserService userService = new UserServiceImpl(); InvocationHandler invocationHandler = new UserServiceProxy(userService); UserService userServiceProxy = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), invocationHandler); userServiceProxy.addUser(); } }

September 12, 2014 · 1 min · 112 words · Bridge Li

JXL解析Excel常用方法

目前在市场上有两个最出名的第三方的JAR包:JXL和POI,他们在处理Excel上都有着不俗的表现,但他们有着细微的差别,主要差别如下: JXL在处理数据方面速度比较快,而POI相对较慢,当数据较少时,其实并不明显; JXL对图片的支持更好,而POI对图片的支持稍弱,但对图片也是支持的; JXL对公示的支持能力稍弱,对于复杂的公式显得无能为力,而POI则做得很好,所以如果做财务软件的话,请慎重选择,建议POI,否则很有可能会引起一些意想不到的问题; JXL的代码简单,也易于理解,下面是JXL处理Excel的常用方法(将来有可能的话,我会把POI的也贴出来,供大家参考): import java.io.File; import java.io.IOException; import java.util.Date; import jxl.CellView; import jxl.Sheet; import jxl.Workbook; import jxl.format.Alignment; import jxl.format.Border; import jxl.format.BorderLineStyle; import jxl.format.CellFormat; import jxl.format.Colour; import jxl.format.VerticalAlignment; import jxl.write.Blank; import jxl.write.Boolean; import jxl.write.DateFormat; import jxl.write.DateTime; import jxl.write.Formula; import jxl.write.Label; import jxl.write.Number; import jxl.write.NumberFormat; import jxl.write.WritableCell; import jxl.write.WritableCellFormat; import jxl.write.WritableFont; import jxl.write.WritableSheet; import jxl.write.WritableWorkbook; import jxl.write.WriteException; import jxl.write.biff.RowsExceededException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class JxlHelper { private static final Logger LOG = LoggerFactory.getLogger(JxlHelper.class); private WritableSheet sheet; public JxlHelper(WritableSheet sheet) { this.sheet = sheet; } public JxlHelper() { } public static WritableWorkbook createWritableWorkbook(String filePath) { WritableWorkbook wwb = null; try { wwb = Workbook.createWorkbook(new File(filePath)); } catch (IOException e) { LOG.error("Create Writable Workbook Failed: IOException", e); } return wwb; } public static WritableWorkbook createWritableWorkbook(String filePath, Workbook wb) { WritableWorkbook wwb = null; try { wwb = Workbook.createWorkbook(new File(filePath), wb); } catch (IOException e) { LOG.error("Create Writable Workbook Failed: IOException", e); } return wwb; } public static Workbook getWorkbook(String filePath) throws Exception { Workbook wb = Workbook.getWorkbook(new File(filePath)); return wb; } public void createSheet(WritableWorkbook wwb, String sheetName, int index) { try { wwb.createSheet(sheetName, index); } catch (Exception e) { LOG.error("Create Sheet Failed", e); } } public void copySheet(WritableWorkbook wwb, int copySheetIndex, String pasteSheetName, int pasteSheetIndex) { try { wwb.copySheet(copySheetIndex, pasteSheetName, pasteSheetIndex); } catch (Exception e) { LOG.error("Copy Sheet Failed", e); } } public void copySheet(WritableWorkbook wwb, String copySheetName, String pasteSheetName, int pasteSheetIndex) { try { wwb.copySheet(copySheetName, pasteSheetName, pasteSheetIndex); } catch (Exception e) { LOG.error("Copy Sheet Failed", e); } } public void removeSheet(WritableWorkbook wwb, int index) { try { wwb.removeSheet(index); } catch (Exception e) { LOG.error("Remove Sheet Failed", e); } } public Sheet[] getSheets(WritableWorkbook wwb) { return wwb.getSheets(); } public void setString(int column, int row, String value, int fontSize) throws WriteException { if (value != null) { sheet.addCell(new Label(column, row, value)); } else { sheet.addCell(new Blank(column, row)); } setCellStyle(column, row, fontSize); } public void setString(int column, int row, String value, CellFormat st) throws WriteException { if (value != null) { sheet.addCell(new Label(column, row, value, st)); } else { sheet.addCell(new Blank(column, row, st)); } } public void setNumber(int column, int row, double value, CellFormat st) throws WriteException { sheet.addCell(new Number(column, row, value, st)); } public void setFormatNumber(int column, int row, double value, int fontSize, LocationEnum location, String format) throws WriteException { Number numCell = new Number(column, row, value); sheet.addCell(numCell); WritableFont font = new WritableFont(WritableFont.createFont(SystemConstant.INVOICE_FONT), fontSize, WritableFont.NO_BOLD); NumberFormat numberFormat = null; WritableCellFormat cellFormat = null; if (!StringUtil.isNullOrEmpty(format)) { numberFormat = new NumberFormat(format); cellFormat = new WritableCellFormat(font, numberFormat); } else { cellFormat = new WritableCellFormat(font); } try { cellFormat.setBorder(Border.ALL, BorderLineStyle.THIN); if (location.equals(LocationEnum.LEFT)) { cellFormat.setBorder(Border.LEFT, BorderLineStyle.THICK); } else if (location.equals(LocationEnum.RIGHT)) { cellFormat.setBorder(Border.RIGHT, BorderLineStyle.THICK); } cellFormat.setAlignment(Alignment.RIGHT); cellFormat.setVerticalAlignment(VerticalAlignment.CENTRE); WritableCell writableCell = sheet.getWritableCell(column, row); writableCell.setCellFormat(cellFormat); } catch (WriteException e) { LOG.error("Set Format Number Failed: WriteException", e); } } public void setBoolean(int column, int row, boolean value) throws WriteException { Boolean boolCell = new Boolean(column, row, value); sheet.addCell(boolCell); } public void setFormatDateTime(int column, int row, Date value, String format) throws WriteException { if (value != null) { WritableCell writableCell = sheet.getWritableCell(column, row); CellFormat cf = writableCell.getCellFormat(); DateTime cell = new DateTime(column, row, value); DateFormat dateFormat = new DateFormat(format); WritableCellFormat wcf = new WritableCellFormat(dateFormat); wcf.setFont(new WritableFont(WritableFont.ARIAL)); wcf.setBorder(Border.LEFT, cf.getBorderLine(Border.LEFT)); wcf.setBorder(Border.RIGHT, cf.getBorderLine(Border.RIGHT)); wcf.setAlignment(Alignment.CENTRE); cell.setCellFormat(wcf); sheet.addCell(cell); } } public void setCellStype2(int column, int row) throws WriteException { WritableFont font = new WritableFont(WritableFont.ARIAL, 10, WritableFont.BOLD); WritableCellFormat cellFormat = new WritableCellFormat(font); cellFormat.setBorder(Border.ALL, BorderLineStyle.THIN); cellFormat.setAlignment(Alignment.CENTRE); cellFormat.setVerticalAlignment(VerticalAlignment.CENTRE); WritableCell writableCell = sheet.getWritableCell(column, row); writableCell.setCellFormat(cellFormat); } public void setFormatDateTime(int column, int row, Date value, CellFormat st) throws WriteException { if (value != null) { sheet.addCell(new DateTime(column, row, value, st)); } else { sheet.addCell(new Blank(column, row, st)); } } public void setFormula(int column, int row, String formula) { try { Formula f = new Formula(column, row, formula); sheet.addCell(f); WritableCellFormat cellFormat = new WritableCellFormat(); cellFormat.setAlignment(Alignment.LEFT); cellFormat.setVerticalAlignment(VerticalAlignment.CENTRE); cellFormat.setBorder(Border.ALL, BorderLineStyle.THIN); WritableCell writableCell = sheet.getWritableCell(column, row); writableCell.setCellFormat(cellFormat); } catch (Exception e) { LOG.error("Set Formula Failed", e); } } public void setFormula(int column, int row, String formula, CellFormat st) { try { sheet.addCell(new Formula(column, row, formula, st)); } catch (Exception e) { LOG.error("Set Formula Failed", e); } } public void setCellStyle(int column, int row, int fontSize) { WritableFont font = new WritableFont(WritableFont.ARIAL, fontSize, WritableFont.BOLD); WritableCellFormat cellFormat = new WritableCellFormat(font); try { cellFormat.setAlignment(Alignment.CENTRE); cellFormat.setVerticalAlignment(VerticalAlignment.CENTRE); WritableCell writableCell = sheet.getWritableCell(column, row); writableCell.setCellFormat(cellFormat); } catch (WriteException e) { LOG.error("Set Cell Style Failed: WriteException", e); } } public void setSumCellBorder(int column, int row, LocationEnum location, String format) { NumberFormat nf = null; if (StringUtil.isNotNull(format)) { nf = new NumberFormat(format); } WritableCellFormat cellFormat = new WritableCellFormat(nf); try { cellFormat.setBorder(Border.ALL, jxl.format.BorderLineStyle.THIN); cellFormat.setBorder(Border.TOP, jxl.format.BorderLineStyle.DOUBLE); if (location.equals(LocationEnum.RIGHT)) { cellFormat.setBorder(Border.RIGHT, jxl.format.BorderLineStyle.THICK); } cellFormat.setBorder(Border.BOTTOM, jxl.format.BorderLineStyle.THICK); cellFormat.setAlignment(Alignment.RIGHT); cellFormat.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE); WritableCell writableCell = sheet.getWritableCell(column, row); writableCell.setCellFormat(cellFormat); } catch (WriteException e) { LOG.error("Set Sum Cell Border Failed: WriteException", e); } } public void setCellStyle(int column, int row) { WritableFont font = new WritableFont(WritableFont.ARIAL); WritableCellFormat cellFormat = new WritableCellFormat(font); try { cellFormat.setAlignment(Alignment.LEFT); cellFormat.setVerticalAlignment(VerticalAlignment.TOP); } catch (WriteException e) { LOG.error("Set Cell Style Failed: WriteException", e); } WritableCell writableCell = sheet.getWritableCell(column, row); writableCell.setCellFormat(cellFormat); } public void hiddenRow(int row) throws RowsExceededException { // sheet.setRowView(row, true); CellView cv = new CellView(); cv.setHidden(true); sheet.setRowView(row, cv); } public void removeRow(int row) { sheet.removeRow(row); } public void insertRow(int row, int height) { sheet.insertRow(row); try { sheet.setRowView(row, height); } catch (RowsExceededException e) { LOG.error("Insert Row Failed: RowsExceededException", e); } } public void mergeCells(int columnStart, int rowsStart, int columnEnd, int rowsEnd) { try { sheet.mergeCells(columnStart, rowsStart, columnEnd, rowsEnd); } catch (RowsExceededException e) { LOG.error("Merge Cells Failed: RowsExceededException", e); } catch (WriteException e) { LOG.error("Merge Cells Failed: WriteException", e); } } public static void close(WritableWorkbook wwb, Workbook wb) { try { if (null != wwb) { wwb.close(); } if (null != wb) { wb.close(); } } catch (WriteException e) { LOG.error("Close WritableWorkbook or Workbook Failed: WriteException", e); } catch (IOException e) { LOG.error("Close WritableWorkbook or Workbook Failed: IOException", e); } } public void setBackgroundColour(int column, int row) { try { WritableCellFormat cellFormat = new WritableCellFormat(); cellFormat.setBackground(Colour.PALE_BLUE); cellFormat.setAlignment(Alignment.LEFT); WritableCell writableCell = sheet.getWritableCell(column, row); writableCell.setCellFormat(cellFormat); } catch (WriteException e) { LOG.error("Set Background Colour Failed: WriteException", e); } } }

September 6, 2014 · 5 min · 995 words · Bridge Li