- 浏览: 22307 次
- 性别:
- 来自: 西安
最新评论
这两天上司让我编一个程序,读取数据库记录并远程调接口传xml报文,处理返回结果。
想想没啥难的,就二话不说的写起程序来了。结果竟然用了一天多时间才搞定,无比郁闷呐。还是记录下来方便自己查看,并且分享大家。jdk用的1.5.0_22版本。
期间用apache的httpclient也做过,也没有成功,对端一直给我返回个空指针异常,网上怎么查都查不出来个结果。
后来,反编译对端的class后,简直崩溃呀。。。原来对端获取报文方式是request.getParameter("$xml");
用到了两个jar包一起传上来,一个oracle驱动包,一个dom4j解析xml包。
在命令窗口运行,必须配置好环境变量.
直接在命令窗口配置当前命令窗口可用范围的classpath.
注意classpath等号后面的.;是必须要的
set classpath=.;C:\Program Files\java\jdk1.5.0_22\lib\dt.jar;C:\Program Files\java\jdk1.5.0_22\lib\tools.jar;C:\Program Files\java\jdk1.5.0_22\lib;C:\httpxml\oracle_jdbc.jar;C:\httpxml\dom4j.jar javac HttpURLConnectionTest.java java HttpURLConnectionTest http://远程接口地址:端口/接收报文类 数据库ip 数据库sid 数据库用户名 数据库密码
import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.StringReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLDecoder; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; /** * 远程调用接口发送报文 * 2012-03-14 * @author mapengwei * @version 1.0 */ public class HttpURLConnectionTest { //数据库连接对象 private Connection conn = null; /** * 查询数据库所有未处理记录 * @param dbip 数据库地址 * oid oracle数据库sid * username 数据库用户名 * password 数据库密码 * @throws ClassNotFoundException * SQLException * @return List 返回List结果集 */ @SuppressWarnings("unchecked") public List query(String dbIP,String oid,String userName,String passWord) throws ClassNotFoundException, SQLException { List list = new ArrayList(); //加载oracle数据库驱动 Class.forName("oracle.jdbc.driver.OracleDriver"); if(null==conn){ conn = DriverManager.getConnection("jdbc:oracle:thin:@"+dbIP+":1521:"+oid+"", userName,passWord); } //查询数据库flag为0的所有数据,只取ecid,ecname两列。 String sql = "select t.ecid,t.ecname from t_ec t where t.flag=0"; Statement stm = conn.createStatement(); ResultSet rs = stm.executeQuery(sql); //遍历结果集 while (rs.next()) { String[] arras = new String[2]; Map map = new HashMap(); String ecid = rs.getString(1); String ecname = rs.getString(2); arras[0] = ecid; arras[1] = ecname; map.put("ec", arras); list.add(map); } return list; } /** * 组装报文,因为报文只有两个节点是需要动态插入的,其他节点都一样,所以就只传入两个参数 * @param ecid * ecname * @return String 返回报文内容 */ public String packageMessage(String ecID, String ecName) { //格式化日期类型 SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); //存放报文 StringBuffer xmlData = new StringBuffer(); xmlData.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); xmlData.append("<ProvBOSS>"); xmlData.append("<BIPCode>"); xmlData.append("BIP4B728"); xmlData.append("</BIPCode>"); xmlData.append("<BIPVer>"); xmlData.append("0100"); xmlData.append("</BIPVer>"); xmlData.append("<ActivityCode>"); xmlData.append("T4101704"); xmlData.append("</ActivityCode>"); xmlData.append("<ActionCode>"); xmlData.append("0"); xmlData.append("</ActionCode>"); xmlData.append("<ProcID>"); xmlData.append("1000001"); xmlData.append("</ProcID>"); xmlData.append("<TransIDO>"); xmlData.append("123456"); xmlData.append("</TransIDO>"); xmlData.append("<ProcessTime>"); //动态构造当前系统时间 xmlData.append(sdf.format(new Date())); xmlData.append("</ProcessTime>"); xmlData.append("<TestFlag>"); xmlData.append("0"); xmlData.append("</TestFlag>"); xmlData.append("<MsgSender>"); xmlData.append("BOSS"); xmlData.append("</MsgSender>"); xmlData.append("<MsgReceiver>"); xmlData.append("PADC"); xmlData.append("</MsgReceiver>"); xmlData.append("<SvcConVer>"); xmlData.append("0100"); xmlData.append("</SvcConVer>"); xmlData.append("<SvcCont><![CDATA["); xmlData.append("<ECInfo><BaseInfo><ECID>"+ecID); xmlData.append("</ECID><ECName>"); xmlData.append(ecName); xmlData.append("</ECName><OprCode>01</OprCode><ECTel>13844444444</ECTel><ECManName>匿名</ECManName></BaseInfo></ECInfo>]]></SvcCont>"); xmlData.append("</ProvBOSS>"); //打印报文 System.out.println("send xml:"+xmlData.toString()); //返回报文 return xmlData.toString(); } /** * 需要动态输入5个参数,当然也可以在程序中写死 * 动态输入参数方便使用 * @param args[0] 远程接口地址 * args[1] 数据库ip * args[2] oracle数据库sid * args[3] oracle数据库用户名 * args[4] oracle数据库密码 */ public static void main(String[] args) { //接口地址 String url = args[0]; HttpURLConnectionTest at = new HttpURLConnectionTest(); List list = null; try { //获取查询的数据库结果集 list = at.query(args[1],args[2],args[3],args[4]); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } if (null == list) { return; } //遍历数据库结果集 for (int i = 0; i < list.size(); i++) { Map map = (Map) list.get(i); String[] arras = (String[]) map.get("ec"); try { String xmlData = at.packageMessage(arras[0], arras[1]); //取一条数据,就修改一下数据库的flag标示 at.updateDBRecord(arras[0],"","", "1"); //调用远程接口发送xml at.sendAndRecieveXmlData(xmlData,url,arras[0]); } catch (IOException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } //关闭数据库连接 at.closeConnection(); } /** * 解析远程接口返回的报文 * @param InputStream 输入流对象 * ecID 用于修改数据记录,数据库中唯一标识 * @throws IOException * SQLException * DocumentException */ public void parseRepXMl(InputStream inputStream, String ecID) throws IOException, SQLException, DocumentException{ //存放返回的报文 StringBuffer recieveData = new StringBuffer(); BufferedReader in = null; //BufferedReader读取返回报文 in = new BufferedReader(new InputStreamReader(inputStream,"utf-8")); for (String inputLine = null; (inputLine = in.readLine()) != null;){ recieveData.append(inputLine); } //打印接收到的报文 System.out.println("recieveData:"+recieveData.toString()); in.close(); String xmlData = URLDecoder.decode(recieveData.toString(),"utf-8"); Element root = null; //SAXReader解析报文 SAXReader saxReader = new SAXReader(); root = saxReader.read(new StringReader(xmlData)).getRootElement(); //获取报文中的response节点 Element rspElmt = root.element("Response"); //获取报文中response节点中的子节点值 String rspCode = rspElmt.elementTextTrim("RspCode"); String rspDesc = rspElmt.elementTextTrim("RspDesc"); //判断处理是否成功,并修改数据库内容,状态 if(null!=rspCode&&"0000".equals(rspCode)){ updateDBRecord(ecID, rspCode, rspDesc, "2"); }else{ updateDBRecord(ecID, rspCode, rspDesc, "3"); } } /** * 修改数据库内容、状态 * @param ecID * rspCode 返回报文中的返回码 * rspDesc 返回报文中的返回码描述 * flag 将记录修改为flag状态 * @throws SQLException */ public void updateDBRecord(String ecID,String rspCode,String rspDesc,String flag) throws SQLException{ //构造修改sql语句 String sql = "update t_ec t set t.flag ='"+flag+"', t.rspcode = '"+rspCode+"', t.rspdesc = '"+rspDesc+"' where t.ecid = '"+ecID+"'"; //打印sql语句 System.out.println("sql="+sql); PreparedStatement pstm = conn.prepareStatement(sql); int result = 0; result=pstm.executeUpdate(sql); pstm.close(); //判断执行数据库影响行数 if(0!=result){ System.out.println("更新ECID="+ecID+"的记录状态为"+flag+"成功."); }else{ System.out.println("更新ECID="+ecID+"的记录状态为"+flag+"失败."); } } /** * 发送报文 * @param xmlData 发送的报文 * ecID 传参,用于后面方法修改数据库记录 * @throws Exception */ private void sendAndRecieveXmlData(String xmlData, String url, String ecID) throws Exception { OutputStreamWriter osw; //获取http连接 HttpURLConnection con = getConnection(url); byte[] xmlByteData = xmlData.getBytes("utf-8"); try { //设置Context-Length con.setRequestProperty("Context-Length", String.valueOf(xmlByteData.length)); //获得输出流 OutputStream outputStream = con.getOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(outputStream); osw = new OutputStreamWriter(bos, "UTF-8"); //写入 //整了一天多,就是因为这里的$xml,开始以为对方是直接读取传过去的报文,后来反编译对端class后发现,竟然是靠这个参数来接收的,崩溃的... osw.write((new StringBuilder()).append("$xml=").append(xmlData).toString()); //清空缓存 osw.flush(); osw.close(); //解析返回报文 parseRepXMl(con.getInputStream(), ecID); } catch (IOException ex) { throw new IOException(ex.getMessage()); } catch (IllegalArgumentException argumetEx) { throw new IllegalArgumentException(argumetEx.getMessage()); } catch (Exception ex) { throw new Exception(ex.getMessage()); } } /** * 得到一个有效的连接 * @param url 连接端口 * @return HttpURLConnection 一个有效的连接 */ private HttpURLConnection getConnection(String url) throws IOException { HttpURLConnection urlconnection = null; try { //得到url连接对象 URL urlcon = new URL(url); //获取到connection连接对象 urlconnection = (HttpURLConnection) urlcon.openConnection(); //设置头参数 // urlconnection.setRequestProperty("Content-Type", "text/xml;charset=UTF-8"); urlconnection.addRequestProperty("content-type", "application/x-www-form-urlencoded;charset=UTF-8"); // urlconnection.setRequestProperty("Accept", "text/xml"); urlconnection.setRequestProperty("version", "100"); urlconnection.setRequestMethod("POST"); urlconnection.setDoOutput(true); urlconnection.setDoInput(true); urlconnection.setUseCaches(false); } catch (java.net.ProtocolException proEx) { throw new IOException(proEx.getMessage()); } catch (MalformedURLException MaEx) { throw new IOException(MaEx.getMessage()); } catch (Exception ex) { throw new IOException(ex.getMessage()); } //返回连接 return urlconnection; } //关闭数据库连接 public void closeConnection(){ if(null!=conn){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
数据库脚本
create table T_EC ( ECID VARCHAR2(20), ECNAME VARCHAR2(50), FLAG INTEGER default 0, RSPCODE VARCHAR2(20), RSPDESC VARCHAR2(50) ); -- Add comments to the columns comment on column T_EC.FLAG is '0,表示未处理.1,表示正在处理.2.表示已处理.3,表示处理失败'; comment on column T_EC.RSPCODE is '处理结果返回码'; comment on column T_EC.RSPDESC is '处理结果返回码描述';
- dom4j.jar (475.1 KB)
- 下载次数: 4
- oracle_jdbc.jar (1.1 MB)
- 下载次数: 3
发表评论
-
jdk 无限制策略文件(jdk1.6 jdk1.7)
2013-04-02 15:21 1837java.lang.SecurityException ... -
nosql 数据库 redis 安装与使用
2013-03-24 15:13 1081使用的redis主机为linux系统。 1.在linux ... -
多台服务器共享一个数据库(oracle数据库),防止同时访问一批数据
2012-07-07 22:37 3562在处理数据时,经常会用定时任务间隔去跑一批数据。如果 ... -
很少用到的一个html标记
2009-06-15 17:53 128<strike></strike> ... -
用https方式做登录的提交
2009-06-15 17:42 1932String https="https"+ ... -
用程序创建zip或rar压缩包
2009-06-15 17:22 1005public static void main1(String ... -
Java IO实现文件以及文件夹的复制
2009-06-15 17:16 1263public class FolderCopy { pub ... -
Set中存放数据不会重复
2009-06-15 17:04 111一直只是听说,今天试了下果然如此. public static ...
相关推荐
发送XML报文通常涉及到POST或GET请求,这里以POST请求为例,因为POST更适合发送大量数据,如XML文档。 1. **创建XML文档** 在发送XML之前,我们需要先构建XML文档。可以使用DOM(Document Object Model)或者SAX...
在IT领域,尤其是在Java开发中,通过HTTP协议发送XML报文是一种常见的数据交换方式,尤其在与Web服务交互时。本文将深入解析如何利用Java语言实现HTTP请求,并发送XML格式的数据,同时也会涵盖相关的概念、代码解读...
本示例中的代码着重于利用HTTPURLConnection处理XML数据,这在移动应用中尤其常见,比如从远程服务器获取配置信息或者同步用户数据。下面将详细介绍这个主题中的关键知识点。 1. **HTTPURLConnection的使用** - **...
以下是一个使用HttpURLConnection发送POST请求的例子: ```java URL url = new URL("http://your-web-server.com/endpoint"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn....
这篇博文主要探讨了如何在Android应用中获取网络资源、实现多线程断点下载、使用GET和POST方法发送数据以及发送XML格式的数据。以下是对这些知识点的详细解释: 1. **获取网络资源**: Android通过`java.net`和`...
根据给定的文件信息,我们可以总结出以下关于“JAVA postxml”的相关知识点: ### JAVA实现HTTP POST XML 在Java中,实现HTTP POST请求并发送XML数据是常见的需求,尤其是在与Web服务进行交互时。下面将详细阐述...
在调用WebService时,POST方法可以承载请求参数,将其封装在请求体中发送到服务端。 1. **构建HTTP请求** 在Java中,可以使用`java.net.URL`、`java.net.HttpURLConnection`或第三方库如Apache HttpClient来构建...
在使用`HttpURLConnection`发送POST数据时,我们首先需要创建一个URL对象,然后通过`openConnection()`方法打开与指定URL的连接。接着,我们需要配置连接的一些属性,如设置`setDoOutput(true)`表示我们将会发送数据...
在上述代码中,我们创建了一个`HttpURLConnection`对象,设置了请求方法为POST,以及请求头中的Content-Type属性,表明我们正在发送XML数据。然后,我们通过`getOutputStream`写入XML数据,并发送请求。一旦请求完成...
在IT行业中,远程请求URL并发送XML参数是常见的数据交互方式,主要应用于Web服务、API接口调用等场景。下面将详细介绍两种实现这一操作的方法,并结合`SyncDemo`这一示例进行阐述。 方法一:使用Java的...
总结起来,使用JDOM解析XML文件可以帮助你更便捷地操作XML文档,而通过HttpURLConnection发送POST请求可以让你的Java应用与PHP服务器进行数据交换,实现远程资源的获取和发送。在实际开发中,你需要根据具体需求调整...
在Java编程中,生成XML文件并发送报文是一项常见的任务,尤其在系统间的数据交换、API调用或者网络通信中。XML(eXtensible Markup Language)是一种结构化数据表示语言,具有良好的可读性和可扩展性,是数据传输的...
然后,通过HTTP客户端库,如Java的HttpURLConnection或Python的requests库,将这个XML字符串发送到Web服务器。服务器端接收到请求后,会解析XML,找到手机号码,然后进行归属地查询。这可能涉及到数据库查询,比如...
2. **设置请求方法**:调用`setRequestMethod("POST")`,因为通常调用WebService都是POST方式。 3. **设置请求属性**:设置请求头,比如`Content-Type`应设为`text/xml;charset=UTF-8`,表示发送的数据是XML格式。 4...
以上就是使用`HttpURLConnection`发送POST请求的基本步骤。然而,实际开发中,我们可能更倾向于使用Apache HttpClient或OkHttp,因为它们提供了更高级的功能,如自动重试、超时设置和更好的性能。 对于标签中的...
在Android开发中,POST请求通常用于向服务器发送复杂的数据结构,比如JSON或XML格式的数据。以下是实现POST请求的一般步骤: 1. **构建请求体**:你需要将要发送的数据转换成字符串或者字节数组。这通常涉及对Java...
2. **请求体(Request Body)**:包含了要发送的实际数据,可以是字符串、XML或JSON格式等。 3. **状态码(Status Code)**:服务器返回的状态码,用于指示请求是否成功或者出现了什么问题。 #### 三、实现HTTP POST...
在实际项目中,可能还需要处理异常、设置请求头、使用POST方法发送数据等更复杂的操作,但这个基本框架应该能为你提供一个良好的起点。 在提供的压缩包文件中,"ws_server"可能包含了Web Service的服务器端实现,而...