OpenFire源码学习之十七:HTTP Service插件
HTTP Service插件
这里的http接口插件是神马?
Openfire主要是在消息推送,那么与其他系统的的消息怎么结合呢,那么这里这个HTTP Service插件就提供了一个基于HTTP的接口。为什么要提供这样的接口?在有些互联网的场景。一个用户平台可以是web的,当然也会有移动终端的APP,那么web端要给移动终端的APP发送消息就依赖这样的接口了。当然这里只是一种实现方式。
首先查看在OF控制太的web页面
本人这里做新增了短信接口。有业务场景的不同这里就不提出来了。
接下来看看插件目录包:
下面编写一个个业务类:
JAVA部分
HttpServiceServlet:
@SuppressWarnings("deprecation") public class HttpServiceServlet extends HttpServlet { private static final long serialVersionUID = 1L; private HttpServicePlugin plugin; private RoutingTable routingTable; private SendMessageUtil sendMessageUtil; private SendMessageUtil messageUtil ; private static XmlPullParserFactory factory = null; private ThreadPool threadPool; static { try { factory = XmlPullParserFactory.newInstance(MXParser.class.getName(), null); factory.setNamespaceAware(true); } catch (XmlPullParserException e) { Log.error("Error creating a parser factory", e); } } @Override public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); plugin = (HttpServicePlugin) XMPPServer.getInstance().getPluginManager().getPlugin("httpedu"); AuthCheckFilter.addExclude("httpedu/httpservice"); if (null == routingTable) routingTable = XMPPServer.getInstance().getRoutingTable(); if (null == sendMessageUtil) sendMessageUtil = new SendMessageUtil(); if (null == threadPool) threadPool = new ThreadPool(10); } @SuppressWarnings("unused") @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); BufferedReader reader = request.getReader(); StringBuffer buffer = new StringBuffer(); String string=""; while ((string = reader.readLine()) != null) { String x = new String(string.getBytes("ISO-8859-1"), "UTF-8"); buffer.append(x); } reader.close(); // Check that our plugin is enabled. if (!plugin.isEnabled()) { Log.warn("http service plugin is disabled: " + request.getQueryString()); replyError("Error1002",response, out); return; } // Check the request type and process accordingly try { JSONObject object = new org.json.JSONObject(buffer.toString()); if(null == object){ Log.warn("json is null " + request.getQueryString()); replyError("Error1003",response, out); return; } //参数 String secret = object.getString("secret").trim(); String optType = object.getString("optType").trim(); String fromid = object.getString("sender").trim(); String domain = object.getString("domain").trim(); String resources = object.getString("resources").trim(); ...... String schoolid = object.getString("schoolid").trim(); // Check this request is authorised if (secret == null || !secret.equals(plugin.getSecret())){ Log.warn("secret is error: " + request.getQueryString()); replyError("Error1004",response, out); return; } ...... if (null == messageUtil) messageUtil = new SendMessageUtil(); if ("1".equals(optType)){ //Personal business to send separately if(toIds == null || "".equals(toIds)){ Log.warn("toIds is error: " + request.getQueryString()); replyError("Error1020",response, out); return; } try { threadPool.execute(createTask(object,routingTable)); replyMessage("ok", response, out); } catch (Exception e) { Log.warn("toIds is error: " + request.getQueryString()); } } else { Log.warn("opttype is error: " + request.getQueryString()); replyError("Error1021",response, out); } } catch (IllegalArgumentException e) { Log.error("IllegalArgumentException: ", e); replyError("Ex1002",response, out); } catch (Exception e) { Log.error("Exception: ", e); replyError("Ex1001",response, out); } } @SuppressWarnings("unused") private void replyMessage(String message,HttpServletResponse response, PrintWriter out){ response.setContentType("text/xml"); out.println("<result>" + message + "</result>"); out.flush(); } private void replyError(String error,HttpServletResponse response, PrintWriter out){ response.setContentType("text/xml"); out.println("<error>" + error + "</error>"); out.flush(); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } @Override public void destroy() { threadPool.waitFinish(); threadPool.closePool(); super.destroy(); // Release the excluded URL AuthCheckFilter.removeExclude("httpedu/httpservice"); } private static Runnable createTask(final JSONObject object,final RoutingTable routingTable) { return new Runnable() { public void run() { SendMessageUtil messageUtil = new SendMessageUtil(); try { messageUtil.sendSingleMessage(object,routingTable); } catch (JSONException e) { e.printStackTrace(); } } }; } }
HttpServicePlugin:
/** * Plugin that allows the administration of https via HTTP requests. * * @author huwf */ public class HttpServicePlugin implements Plugin, PropertyEventListener { private XMPPServer server; private String secret; private boolean enabled; private String smsAddrs; private SendThread sendThread; public void initializePlugin(PluginManager manager, File pluginDirectory) { server = XMPPServer.getInstance(); secret = JiveGlobals.getProperty("plugin.httpservice.secret", ""); // If no secret key has been assigned to the http service yet, assign a random one. if (secret.equals("")){ secret = StringUtils.randomString(8); setSecret(secret); } // See if the service is enabled or not. enabled = JiveGlobals.getBooleanProperty("plugin.httpservice.enabled", false); // Get the list of IP addresses that can use this service. An empty list means that this filter is disabled. smsAddrs = JiveGlobals.getProperty("plugin.httpservice.smsAddrs", ""); // Listen to system property events PropertyEventDispatcher.addListener(this); if (null == sendThread) sendThread = new SendThread(); } public void destroyPlugin() { // Stop listening to system property events PropertyEventDispatcher.removeListener(this); } /** * Returns the secret key that only valid requests should know. * * @return the secret key. */ public String getSecret() { return secret; } /** * Sets the secret key that grants permission to use the httpservice. * * @param secret the secret key. */ public void setSecret(String secret) { JiveGlobals.setProperty("plugin.httpservice.secret", secret); this.secret = secret; } public String getSmsAddrs() { return smsAddrs; } public void setSmsAddrs(String smsAddrs) { JiveGlobals.setProperty("plugin.httpservice.smsAddrs", smsAddrs); this.smsAddrs = smsAddrs; } /** * Returns true if the http service is enabled. If not enabled, it will not accept * requests to create new accounts. * * @return true if the http service is enabled. */ public boolean isEnabled() { return enabled; } /** * Enables or disables the http service. If not enabled, it will not accept * requests to create new accounts. * * @param enabled true if the http service should be enabled. */ public void setEnabled(boolean enabled) { this.enabled = enabled; JiveGlobals.setProperty("plugin.httpservice.enabled", enabled ? "true" : "false"); } public void propertySet(String property, Map<String, Object> params) { if (property.equals("plugin.httpservice.secret")) { this.secret = (String)params.get("value"); } else if (property.equals("plugin.httpservice.enabled")) { this.enabled = Boolean.parseBoolean((String)params.get("value")); } else if (property.equals("plugin.httpservice.smsAddrs")) { this.smsAddrs = (String)params.get("smsAddrs"); } } public void propertyDeleted(String property, Map<String, Object> params) { if (property.equals("plugin.httpservice.secret")) { this.secret = ""; } else if (property.equals("plugin.httpservice.enabled")) { this.enabled = false; } else if (property.equals("plugin.httpservice.smsAddrs")) { this.smsAddrs = ""; } } public void xmlPropertySet(String property, Map<String, Object> params) { // Do nothing } public void xmlPropertyDeleted(String property, Map<String, Object> params) { // Do nothing } }
SendThread:
public class SendThread { ...... static{ ssu = new SendSmsUtil(); httpServicePlugin = (HttpServicePlugin) XMPPServer.getInstance().getPluginManager().getPlugin("httpedu"); client = new HttpClient(); initialize(client); executor = new ThreadPoolExecutor(1, 3, 3*1000, TimeUnit.MILLISECONDS, executeQueue, new RejectedHandler()); } private static void initialize(HttpClient client){ MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); HttpConnectionManagerParams connectionParams = connectionManager.getParams(); connectionParams.setConnectionTimeout(2000); connectionParams.setDefaultMaxConnectionsPerHost(500); connectionParams.setMaxTotalConnections(500); client.setHttpConnectionManager(connectionManager); HttpClientParams httpParams = client.getParams(); httpParams.setParameter(HttpMethodParams.RETRY_HANDLER, new HttpMethodRetryHandler() { @Override public boolean retryMethod(HttpMethod method, IOException exception, int executionCount) { if(method == null){ return false; } if(executionCount > MAX_RETRY_COUNT){ return false; } if(!method.isRequestSent()){ return true; } if(exception instanceof NoHttpResponseException){ return true; } return false; } }); } public static boolean push(SmsEnity msg){ return push(msg, false); } public static boolean push(final SmsEnity msg, boolean reliable){ PostMethod postMethod = null; try { String urlAddrs = httpServicePlugin.getSmsAddrs(); postMethod = createPostMethod(msg, urlAddrs); client.executeMethod(postMethod); int statusCode = postMethod.getStatusCode(); if(statusCode == HttpStatus.SC_OK){ String retMsg = new String(postMethod.getResponseBody()); retMsg = URLDecoder.decode(retMsg, "UTF-8"); if("".equals(retMsg) || null == retMsg){ LOG.info("sms send success! sendid: " + msg.getSendid() + " Receiveid: " + msg.getReceiveid() + " Content: " + msg.getContent()); }else{ throw new PushException(retMsg); } return true; }else if(statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR){ throw new PushException("Push server internal error: " + HttpStatus.SC_INTERNAL_SERVER_ERROR); } }catch (IOException e1) { if(reliable){ try { failQueue.put(new Runnable() { public void run() { push(msg,true); } }); LOG.info(Thread.currentThread().getName()+": in the queue..."); if(!start){ startup(); } } catch (InterruptedException e) { e.printStackTrace(); } } }catch(PushException e2){ LOG.info("The sms Push failure and throws PushException" + e2.getMessage() + "\n" + "sms content-> Sendid:" + msg.getSendid() + " Receiveid: " + msg.getReceiveid() + " Content: " + msg.getContent() + " Sendtype:" + msg.getSendtype()); }catch(Exception e3){ LOG.info("The sms Push failure and throws PushException" + e3.getMessage() + "\n" + "sms content-> Sendid:" + msg.getSendid() + " Receiveid: " + msg.getReceiveid() + " Content: " + msg.getContent() + " Sendtype:" + msg.getSendtype()); }finally{ postMethod.releaseConnection(); } return false; } private static PostMethod createPostMethod(SmsEnity se, String uri) throws Exception{ PostMethod postMethod = null; postMethod = new PostMethod(uri); if (null != se.getSendid() && !"".equals(se.getSendid())) postMethod.addParameter(new NameValuePair("sendid", se.getSendid())); if (null != se.getToken() && !"".equals(se.getSendid())) postMethod.addParameter(new NameValuePair("token", se.getToken())); postMethod.addParameter(new NameValuePair("sendtype", se.getSendtype() != null ? se.getSendtype() : "")); if (null != se.getReceiveid() && !"".equals(se.getReceiveid())) postMethod.addParameter(new NameValuePair("receiveid", se.getReceiveid())); if (null != se.getClassid() && !"".equals(se.getClassid())) postMethod.addParameter(new NameValuePair("classid", se.getClassid())); postMethod.addParameter(new NameValuePair("schoolid", se.getSchoolid() != null ? se.getSchoolid() : "")); if (null != se.getGroupid() && !"".equals(se.getGroupid())) postMethod.addParameter(new NameValuePair("groupid", se.getGroupid())); if (null != se.getSerial_num() && !"".equals(se.getSerial_num())) postMethod.addParameter(new NameValuePair("serial_num", se.getSerial_num())); if (null != se.getContent() && !"".equals(se.getContent())) postMethod.addParameter(new NameValuePair("content", se.getContent())); return postMethod; } /** * Start a background thread */ private synchronized static void startup(){ LOG.info(Thread.currentThread().getName()+" : Start a background thread..."); if(!start){ start = true; worker = new Thread(){ @Override public void run() { workStart(this); } }; worker.setName("worker thread"); worker.start(); } } /** * Submit to perform tasks * @param thread */ private static void workStart(Thread thread){ while(start && worker == thread){ Runnable task = failQueue.poll(); LOG.info(Thread.currentThread().getName()+" : The queue of the communist party of China has a number of tasks: " + failQueue.size()); LOG.info(Thread.currentThread().getName()+" : From the queue"+task==null?"no":""+"Take out the task..."); if(task != null){ executor.execute(task); }else{ try { Thread.sleep(5*1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } /** * Denial of service processing strategy */ static class RejectedHandler implements RejectedExecutionHandler{ public void rejectedExecution(Runnable task, ThreadPoolExecutor executor) { if(!executor.isShutdown()){ if(!executor.isTerminating()){ try { failQueue.put(task); } catch (InterruptedException e) { e.printStackTrace(); } } } } } }
ThreadPool:
@SuppressWarnings("rawtypes") public class ThreadPool extends ThreadGroup { // thread pool closed private boolean isClosed = false; private LinkedList workQueue; private static int threadPoolID = 1; /** * created and started for work thread * * @param poolSize * the thread size in pool */ public ThreadPool(int poolSize) { super(threadPoolID + ""); setDaemon(true); workQueue = new LinkedList(); for (int i = 0; i < poolSize; i++) { new WorkThread(i).start(); } } /** * Work queue to add a new task, the worker thread to execute the office * * @param task */ @SuppressWarnings("unchecked") public synchronized void execute(Runnable task) { if (isClosed) { throw new IllegalStateException(); } if (task != null) { // Adding a task to the queue workQueue.add(task); // Wake one being getTask () method to be the work of the task // threads notify(); } } /** * Removed from the work queue a task, the worker thread will call this * method * * @param threadid * @return * @throws InterruptedException */ private synchronized Runnable getTask(int threadid) throws InterruptedException { while (workQueue.size() == 0) { if (isClosed) return null; System.out.println("work thread:" + threadid + "wait task..."); // If no work queue task waits for the task wait(); } System.out.println("work thread:" + threadid + "start run task"); // Inverse return the first element in the queue, and removed from the // queue return (Runnable) workQueue.removeFirst(); } /** * close thread pool */ public synchronized void closePool() { if (!isClosed) { // After waiting worker threads waitFinish(); isClosed = true; // Empty the work queue and interrupt the thread pool thread for all // the work, // this method inherited from class ThreadGroup workQueue.clear(); interrupt(); } } /** * Waiting for a worker to perform all tasks completed */ public void waitFinish() { synchronized (this) { isClosed = true; // Wake up all still getTask () method to wait for the task worker // thread notifyAll(); } // Return of active threads in this thread group estimates. Thread[] threads = new Thread[activeCount()]; // enumerate () method inherited from ThreadGroup class, // according to the estimated value of active threads in the thread // group to get // all currently active worker threads int count = enumerate(threads); for (int i = 0; i < count; i++) { try { threads[i].join(); } catch (InterruptedException ex) { ex.printStackTrace(); } } } /** * Inner classes, the worker thread is responsible for removing the task * from the work queue and executes * * @author huwf * */ private class WorkThread extends Thread { private int id; public WorkThread(int id) { // Parent class constructor, the thread is added to the current // ThreadPool thread group super(ThreadPool.this, id + ""); this.id = id; } public void run() { // isInterrupted () method inherited from the Thread class, // to determine whether the thread is interrupted while (!isInterrupted()) { Runnable task = null; try { task = getTask(id); } catch (InterruptedException ex) { ex.printStackTrace(); } // If getTask () returns null or thread getTask () is // interrupted, then the end of this thread if (task == null) return; try { // run task; task.run(); } catch (Throwable t) { t.printStackTrace(); } } } } }
SendMessageUtil:
public class SendMessageUtil { private static Map<Integer, XMPPPacketReader> parsers = new ConcurrentHashMap<Integer, XMPPPacketReader>(); private static XmlPullParserFactory factory = null; private static final Logger log = LoggerFactory .getLogger(SendMessageUtil.class); /** * Send a single message interface * @throws JSONException */ public String sendSingleMessage(JSONObject ae,RoutingTable routingTable) throws JSONException { String state = "failure"; SmsEnity se = new SmsEnity(); String fromid = ae.getString("sender"); String domain = ae.getString("domain"); String resources = ae.getString("resources"); String toId = ae.getString("toIds"); String msgType = ae.getString("msgType"); String msgNo = ae.getString("msgNo"); String smsType = ae.getString("smsType"); //RoutingTable routingTable = ae.getRoutingTable(); String token = "";//暂时为空 String smsBody = ae.getString("smsBody"); String schoolid = ae.getString("schoolid"); //0指定用户发送,1给学生发送,2全班发送,3,多个班级发送 6.发给学生家长你那发给老师是0 String rectype = ae.getString("rectype"); String classid = ""; if ("10014".equals(msgType)){ classid = ae.getString("classId"); } String sender = fromid + "@" + domain + "/" + resources; StringBuffer sb = new StringBuffer(); if (toId.length() > 0) { String tos[] = toId.split(","); for (int i = 0; i < tos.length; i++) { String to = tos[i] + "@" + domain; Message packet; if (!sender.contains(to) && !sender.equals(to)) { packet = assemblyMessages(to, sender, "1", msgType, msgNo, null, null, null,classid); if ("2".equals(smsType)) sb.append(tos[i] + ","); PacketRouter router = XMPPServer.getInstance().getPacketRouter(); router.route(packet); log.info("send: " + packet); state = "ok"; if ("1".equals(smsType)){ if (null == routingTable.getClientRoute(new JID(to + "/" + resources))) sb.append(tos[i] + ","); } } } String receiveids = sb.toString(); // Send SMS if (!"".equals(smsType) && receiveids.length() > 0 && null != rectype) { se.setSendid(fromid); se.setToken(token); if (",".equals(sb.substring(sb.length() - 1))) receiveids = receiveids.substring(0,receiveids.length() - 1); se.setSendtype(rectype); se.setReceiveid(receiveids); String body; try { body = java.net.URLEncoder.encode(smsBody, "UTF-8"); se.setContent(body); } catch (UnsupportedEncodingException e) { log.error("send sms UnsupportedEncodingException:"+e.getMessage()); } se.setSchoolid(schoolid); se.setGroupid(""); se.setClassid(""); se.setSerial_num(String.valueOf(System.currentTimeMillis())); SendThread.push(se); } } return state; } public boolean isDigit(String sender, String to){ return to.contains(sender) ; } /** * Send group business messages */ public String sendGroupMessage(AdditionalEntities ae) { //短信发送 } /** * The message format assembled */ public Message assemblyMessages(String to...) { //封装消息 return packet; } }
Web部分
web-custom.xml
<?xml version='1.0' encoding='ISO-8859-1'?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <!-- Servlets --> <servlet> <servlet-name>HttpServiceServlet</servlet-name> <servlet-class>com.....httpedu.httpservlet.HttpServiceServlet</servlet-class> </servlet> <!-- Servlet mappings --> <servlet-mapping> <servlet-name>HttpServiceServlet</servlet-name> <url-pattern>/httpservice</url-pattern> </servlet-mapping> </web-app>
http-service.jsp
<%@ page import="java.util.*, org.jivesoftware.openfire.XMPPServer, org.jivesoftware.util.*, com.montnets.httpedu.plugin.HttpServicePlugin" errorPage="error.jsp" %> <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %> <%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %> <%-- Define Administration Bean --%> <jsp:useBean id="admin" class="org.jivesoftware.util.WebManager" /> <c:set var="admin" value="${admin.manager}" /> <% admin.init(request, response, session, application, out ); %> <% // Get parameters boolean save = request.getParameter("save") != null; boolean success = request.getParameter("success") != null; String secret = ParamUtils.getParameter(request, "secret"); boolean enabled = ParamUtils.getBooleanParameter(request, "enabled"); String smsAddrs = ParamUtils.getParameter(request, "smsAddrs"); //注意:这里getPlugin("httpedu")里面的参数是插件的目录名称 HttpServicePlugin plugin = (HttpServicePlugin) XMPPServer.getInstance().getPluginManager().getPlugin("httpedu"); // Handle a save Map errors = new HashMap(); if (save) { if (errors.size() == 0) { plugin.setEnabled(enabled); plugin.setSecret(secret); plugin.setSmsAddrs(smsAddrs); response.sendRedirect("http-service.jsp?success=true"); return; } } secret = plugin.getSecret(); enabled = plugin.isEnabled(); smsAddrs = plugin.getSmsAddrs(); %> <html> <head> <title>HTTP Service Properties</title> <meta name="pageID" content="http-service"/> </head> <body> <p> This is an HTTP service plug-in it is mainly to complete business push message center system and off-line message interface implementation </p> <% if (success) { %> <div class="jive-success"> <table cellpadding="0" cellspacing="0" border="0"> <tbody> <tr><td class="jive-icon"><img src="images/success-16x16.gif" width="16" height="16" border="0"></td> <td class="jive-icon-label"> HTTP service properties edited successfully. </td></tr> </tbody> </table> </div><br> <% } %> <form action="http-service.jsp?save" method="post"> <fieldset> <legend>HTTP Service</legend> <div> <p> This main set message center call switch, text messaging and SMS address configuration </p> <ul> <input type="radio" name="enabled" value="true" id="hrb01" <%= ((enabled) ? "checked" : "") %>> <label for="hrb01"><b>Enabled</b> - HTTP service requests will be processed.</label> <br> <input type="radio" name="enabled" value="false" id="hrb02" <%= ((!enabled) ? "checked" : "") %>> <label for="hrb02"><b>Disabled</b> - HTTP service requests will be ignored.</label> <br><br> <label for="h_text_secret">Secret key:</label> <input type="text" name="secret" value="<%= secret %>" id="h_text_secret"> <br><br> <label for="h_smsAddrs">SMS address:</label> <input type="text" id="h_smsAddrs" name="smsAddrs" size="80" value="<%= smsAddrs == null ? "" : smsAddrs %>"/> </ul> </div> </fieldset> <br><br> <input type="submit" value="Save Settings"> </form> </body> </html>
Plugin.xml:
<?xml version="1.0" encoding="UTF-8"?> <plugin> <class>com.montnets.httpedu.plugin.HttpServicePlugin</class> <name>Http Service</name> <description>The message center services and A short letter to push</description> <author>HuWenFeng</author> <version>1.4.2</version> <date>10/7/2013</date> <minServerVersion>3.5.1</minServerVersion> <adminconsole> <tab id="tab-server"> <sidebar id="sidebar-server-settings"> <item id="http-service" name="Http Service" url="http-service.jsp" description="The message center services and A short letter to push" /> </sidebar> </tab> </adminconsole> </plugin>
测试
TestHttpedu:
public class TestHttpedu { public static void main(String[] args) throws JSONException, InterruptedException { String datetime = (new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS")).format(new Date()); System.out.println(datetime); int a = 0; for (int i=0;i<1;i++){ MyThread my = new MyThread(a++); my.start(); my.sleep(100); } } }
MyThread:
public class MyThread extends Thread{ private int i; public MyThread(int i){ this.i=i; } public void run(){ httpedu(); } public void httpedu(){ JSONObject jb = new JSONObject(); try { jb.put("secret", "montnets@123");//montnets@123 jb.put("optType", "1"); //你需要发送的参数 try { testPost(jb); } catch (IOException e) { e.printStackTrace(); } } catch (JSONException e) { e.printStackTrace(); } } public void testPost(JSONObject json) throws IOException, JSONException { URL url = new URL("http://127.0.0.1:9090/plugins/httpedu/httpservice"); URLConnection connection = url.openConnection(); connection.setDoOutput(true); OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8"); String j = json.toString(); out.write(j); out.flush(); out.close(); //返回 String sCurrentLine; String sTotalString; sCurrentLine = ""; sTotalString = ""; InputStream l_urlStream; l_urlStream = connection.getInputStream(); BufferedReader l_reader = new BufferedReader(new InputStreamReader(l_urlStream)); while ((sCurrentLine = l_reader.readLine()) != null) { sTotalString += sCurrentLine; } System.out.println("返回第 " +i + " 结果:" + sTotalString); if(sTotalString.indexOf("ok")==-1){ System.out.println(sTotalString+" : " + json.toString()); } }
这里,代码都不是很规范,也有些不全。本人只是贴出了做个示范。有需要该代码的可以单独联系我。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。