oracle调用java 汉字_Oracle发送http请求中文乱码问题

本文介绍了在Oracle存储过程中调用Java发送HTTP请求时遇到的中文乱码和报文不完整问题,提供了详细的解决步骤,包括XML报文的URL编码和解码,以及在Java Servlet接收和响应时的处理方法。
摘要由CSDN通过智能技术生成

在日常开发中,可以需要使用Oracle存储过程进行http请求发送,有时会遇到,客户端接收的xml中文乱码,还有报文格式不完整,以及接收返回报文中文乱码问题,下面就为大家举例,并提供解决方法。

发送例子:

一、Oracle存储过程部分:

1、调用发送方法的存储过程

create or replace procedure CallHttpRequest(

pi_URL  in varchar2,    --发送的Http URL

po_ReMsg  out varchar2  --返回信息

) is

obj_xmldoc sys.xmltype;       --响应报文xml对象

ro_xmlContent varchar2(10000); --请求报文

begin

--要发送的报文

ro_xmlContent:='<?xml version="1.0" encoding="GBK"?>

0066667626

测试

2018-12-03

10:12:30

单证类型

单证回销类型值

';

--调用发送方法

SqlHttpRequest(pi_URL, ro_xmlContent, po_ReMsg, obj_xmldoc);

end CallHttpRequest;

2、具体的发送存储过程

create or replace procedure SqlHttpRequest(

pi_URL  in varchar2,    --发送的Http URL

pi_Content in varchar2, --发送的报文内容

po_ReMsg out varchar2,  --错误内容

po_xmltype out xmltype  --响应报文内容

)

as

obj_http_req   UTL_HTTP.REQ;    --http请求对象

obj_http_resp  UTL_HTTP.RESP;   --http响应对象

v_req_clob     varchar2(32767); --请求报文

v_resp_clob     clob;           --响应报文

v_buffer_text  varchar2(32767); --缓存

TIMEOUT          INTEGER   DEFAULT 3600;

begin

v_req_clob:=pi_Content;

-- 初始化晌应CLOB.

DBMS_LOB.createtemporary(v_resp_clob, FALSE);

-- 初始化HTTP请求参数.

UTL_HTTP.SET_TRANSFER_TIMEOUT(TIMEOUT);

obj_http_req  := UTL_HTTP.BEGIN_REQUEST (pi_URL, 'POST');

UTL_HTTP.SET_HEADER (obj_http_req,'Content-Type','text/xml;chartset=utf-8');

v_req_clob:=utl_url.escape(v_req_clob,true,'UTF8');--进行url编码

UTL_HTTP.SET_HEADER (obj_http_req,'Content-Length',lengthb(v_req_clob));

UTL_HTTP.SET_BODY_CHARSET(obj_http_req,'UTF-8');

--发送HTTP请求

UTL_HTTP.WRITE_TEXT (obj_http_req,v_req_clob);

--接收响应

obj_http_resp := UTL_HTTP.GET_RESPONSE(obj_http_req);

BEGIN

LOOP

UTL_HTTP.READ_TEXT(obj_http_resp, v_buffer_text, 32767);

DBMS_LOB.WRITEAPPEND(v_resp_clob, length(v_buffer_text), v_buffer_text);

END LOOP;

--关闭HTTP连接

UTL_HTTP.END_RESPONSE(obj_http_resp);

EXCEPTION

WHEN UTL_HTTP.REQUEST_FAILED THEN

UTL_HTTP.END_RESPONSE(obj_http_resp);

DBMS_LOB.freetemporary(v_resp_clob);

po_ReMsg := 'HTTP请求失败:' || 'DBS' || to_char(SQLCODE) || ':' || substr(SQLERRM,1,128);

WHEN UTL_HTTP.TRANSFER_TIMEOUT THEN

UTL_HTTP.END_RESPONSE(obj_http_resp);

DBMS_LOB.freetemporary(v_resp_clob);

po_ReMsg := 'HTTP请求超时失败:' || 'DBS' || to_char(SQLCODE) || ':' || substr(SQLERRM,1,128);

WHEN UTL_HTTP.END_OF_BODY THEN

UTL_HTTP.END_RESPONSE(obj_http_resp);

WHEN OTHERS THEN

UTL_HTTP.END_RESPONSE(obj_http_resp);

DBMS_LOB.freetemporary(v_resp_clob);

po_ReMsg := 'HTTP请求错误:' || 'DBS' || to_char(SQLCODE) || ':' || substr(SQLERRM,1,128);

END;

dbms_output.put_line('返回-------------->'||v_resp_clob);

--创建XMLTYPE对象

po_xmltype:=sys.XMLTYPE(v_resp_clob);

--释放clob

DBMS_LOB.freetemporary(v_resp_clob);

po_ReMsg := '请求成功!';

EXCEPTION

WHEN OTHERS THEN

UTL_HTTP.END_RESPONSE(obj_http_resp);

DBMS_LOB.freetemporary(v_resp_clob);

po_ReMsg := 'XML内容错误:' || 'DBS' || to_char(SQLCODE) || ':' || substr(SQLERRM,1,128);

end SqlHttpRequest;

二、Java部分

1、一个接收oracle存储过程发送请求的servlet

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.InterruptedIOException;

import java.io.OutputStream;

import java.text.SimpleDateFormat;

import java.util.Date;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.dom4j.Document;

import org.dom4j.DocumentHelper;

import org.dom4j.Element;

public class OracleHttpResponse extends HttpServlet {

/**

*

*/

private static final long serialVersionUID = -6824462722279265976L;

/**

* Destruction of the servlet.

*/

public void destroy() {

super.destroy(); // Just puts "destroy" string in log

// Put your code here

}

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doPost(request, response);

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

// 设置接收的内容编码

request.setCharacterEncoding("utf-8");

// 接收请求的输入流数据

String sendMessage = null;

try {

InputStream in = request.getInputStream();

InputStreamReader isr = new InputStreamReader(in);

BufferedReader br = new BufferedReader(isr);

StringBuffer buffer = new StringBuffer();

String line = "";

while ((line = br.readLine()) != null) {

buffer.append(line);

}

sendMessage = buffer.toString();

} catch (InterruptedIOException e) {

e.printStackTrace();

} catch (IOException ioe) {

ioe.printStackTrace();

} catch (NullPointerException npe) {

npe.printStackTrace();

}

System.out.println("oracle过来的xml数据:" + sendMessage);

OutputStream url_out = null;

String xmlData = CreateResponseData();

response.setContentType("text/xml;charset=utf-8");

response.reset();

url_out = response.getOutputStream();

url_out.write(xmlData.getBytes("utf-8"), 0, xmlData.getBytes("utf-8").length);

url_out.flush();

url_out.close();

}

private String CreateResponseData() {

Document document = DocumentHelper.createDocument();

// 增加根节点

Element TXLife = document.addElement("TXLife");

Element TXLifeResponse = TXLife.addElement("TXLifeResponse");

Element TransRefGUID = TXLifeResponse.addElement("TransRefGUID");

TransRefGUID.setText("1000000000");

Element TransType = TXLifeResponse.addElement("TransType");

TransType.setText("测试同步交易");

TransType.addAttribute("tc", "WLSCBS_QY_BL_0001");

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

String dateStr = dateFormat.format(new Date());

Element TransExeDate = TXLifeResponse.addElement("TransExeDate");

TransExeDate.setText(dateStr.split(" ")[0]);

Element TransExeTime = TXLifeResponse.addElement("TransExeTime");

TransExeTime.setText(dateStr.split(" ")[1]);

Element TransResult = TXLifeResponse.addElement("TransResult");

Element ResultCode = TransResult.addElement("ResultCode");

ResultCode.setText("测试成功");

ResultCode.addAttribute("tc", "1");

return document.asXML();

}

public void init() throws ServletException {

// Put your code here

}

三、测试

1、右键存储过程callhttprequest,选择Test,进入测试界面,输入前面我定义的servlet的访问路径

27ff75363349bce1e3aac47781c16809.png

2、查看servlet接收的报文

首先是乱码:

oracle过来的xml数据:<?xml version="1.0" encoding="GBK"?>      0066667626    娴嬭瘯    2018-12-03    10:12:30          鍗曡瘉绫诲瀷      鍗曡瘉鍥為攢绫诲瀷鍊?      

出现这个问题需要改一下servlet的接收方法,改一句代码即可

将 InputStreamReader isr = new InputStreamReader(in);

改成InputStreamReader isr = new InputStreamReader(in, "utf-8");

再次测试,中文不乱码了,但报文不完整

oracle过来的xml数据:<?xml version="1.0" encoding="GBK"?>      0066667626    测试    2018-12-03    10:12:30          单证类型      单证回销类型值      

c4d5848d07aa0f1149ea51029b4ab64e.png

此时可以看到接收到的xml没有完整结束。原因是因为Oracle发送过来的xml中有中文导致的。

而且Oracle这里接收到的返回报文还是乱码

a881654b6f183579327239296a6e4908.png

四、解决方法

就是进行url编码

1、Oracle存储过程发送xml报文前进行url编码

v_req_clob:=utl_url.escape(v_req_clob,true,'UTF-8');--进行url编码

具体位置:

a2d53da03d95a353ef146f2dd6c1c7a6.png

2、servlet接收时,进行url解码

sendMessage = java.net.URLDecoder.decode(sendMessage,"utf-8");

具体位置:

1963e51b8900d1def9836b90cded7696.png

3、返回给oracle报文前,进行url编码

xmlData = java.net.URLEncoder.encode(xmlData,"utf-8").replaceAll("\\+",  "%20");

具体位置:

f592afcefb3164ecb958370bc9275d31.png

4、Oracle存储过程在接收到servlet返回时,进行url解码

v_resp_clob := utl_url.unescape(v_resp_clob, 'utf-8');--进行url解码

具体位置

a8f590d8089de9669b6dabc416a9ad9c.png

五、再次进行测试

18b4af3e9f6c7f6468b3e0a047d0454e.png

1、servle端接收到的xml报文完整了,而且格式还保持了

5c099195f8f309b33d7dc65ff9473ec7.png

2、Oracle接收到servlet的返回,也正常了

c9ee5364a52022160ba04eaf71b21518.png

至此问题全部解决完毕!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值