系出名门Android(10) - HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理

简介:
[索引页]
[源码下载]


系出名门Android(10) - HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理


作者: webabcd


介绍
在 Android 中与服务端做 HTTP 通信,解析 XML,通过 Handler 实现异步消息处理
  • HTTP 通信 - 与服务端做 HTTP 通信,分别以 GET 方式和 POST 方式做演示
  • XML 解析 - 可以用两种方式解析 XML,分别是 DOM 方式和 SAX 方式
  • 异步消息处理 - 通过 Handler 实现异步消息处理,以一个自定义的异步下载类来说明 Handler 的用法 


1、HTTP 通信和 XML 解析的 Demo
MySAXHandler.java
package com.webabcd.communication; 

import org.xml.sax.Attributes; 
import org.xml.sax.SAXException; 
import org.xml.sax.helpers.DefaultHandler; 

// 继承 DefaultHandler 以实现指定 XML 的 SAX 解析器 
// DOM - W3C 标准,需要把 xml 数据全部加载完成后才能对其做解析,可对树做任意遍历 
// SAX - 流式解析,通过事件模型解析 xml,只能顺序解析 
public  class MySAXHandler  extends DefaultHandler { 

         private  boolean mIsTitleTag =  false
         private  boolean mIsSalaryTag =  false
         private  boolean mIsBirthTag =  false
         private String mResult = ""; 
         
         // 打开 xml 文档的回调函数 
        @Override 
         public  void startDocument()  throws SAXException { 
                 // TODO Auto-generated method stub 
                 super.startDocument(); 
        } 
         
         // 关闭 xml 文档的回调函数 
        @Override 
         public  void endDocument()  throws SAXException { 
                 // TODO Auto-generated method stub 
                 super.endDocument(); 
        } 
         
         // 一发现元素开始标记就回调此函数 
        @Override 
         public  void startElement(String uri, String localName, String qName, 
                        Attributes attributes)  throws SAXException { 
                 if (localName ==  "title"
                        mIsTitleTag =  true
                 else  if (localName ==  "salary"
                        mIsSalaryTag =  true
                 else  if (localName ==  "dateOfBirth"
                        mIsBirthTag =  true
                 else  if (localName ==  "employee"
                        mResult +=  "\nname:" + attributes.getValue( "name");         
        } 

         // 一发现元素结束标记就回调此函数 
        @Override 
         public  void endElement(String uri, String localName, String qName) 
                         throws SAXException { 
                 if (localName ==  "title"
                        mIsTitleTag =  false
                 else  if (localName ==  "salary"
                        mIsSalaryTag =  false
                 else  if (localName ==  "dateOfBirth"
                        mIsBirthTag =  false
        } 

         // 一发现元素值或属性值就回调此函数 
        @Override 
         public  void characters( char[] ch,  int start,  int length) 
                         throws SAXException { 
                 if (mIsTitleTag) 
                        mResult +=  new String(ch, start, length); 
                 else  if (mIsSalaryTag) 
                        mResult +=  " salary:" +  new String(ch, start, length); 
                 else  if (mIsBirthTag) 
                        mResult +=  " dateOfBirth:" +  new String(ch, start, length); 
        } 
         
         public String getResult(){ 
                 return mResult; 
        } 
}
 
Main.java
package com.webabcd.communication; 

import java.io.BufferedInputStream; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.HttpURLConnection; 
import java.net.URL; 
import java.net.URLConnection; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.Map; 

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.SAXParser; 
import javax.xml.parsers.SAXParserFactory; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.client.entity.UrlEncodedFormEntity; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.message.BasicNameValuePair; 
import org.apache.http.protocol.HTTP; 
import org.apache.http.util.ByteArrayBuffer; 
import org.apache.http.util.EncodingUtils; 
import org.w3c.dom.Document; 
import org.w3c.dom.Element; 
import org.w3c.dom.NodeList; 
import org.xml.sax.InputSource; 
import org.xml.sax.XMLReader; 

import android.app.Activity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.Button; 
import android.widget.TextView; 

public  class Main  extends Activity { 
         
         private TextView textView; 
         
         /** Called when the activity is first created. */ 
        @Override 
         public  void onCreate(Bundle savedInstanceState) { 
                 super.onCreate(savedInstanceState); 
                setContentView(R.layout.main); 
                 
                textView = (TextView)  this.findViewById(R.id.textView); 
                 
                Button btn1 = (Button)  this.findViewById(R.id.btn1); 
                btn1.setText( "http get demo"); 
                btn1.setOnClickListener( new Button.OnClickListener() { 
                         public  void onClick(View v) { 
                                httpGetDemo(); 
                        } 
                }); 
                 
                Button btn2 = (Button)  this.findViewById(R.id.btn2); 
                btn2.setText( "http post demo"); 
                btn2.setOnClickListener( new Button.OnClickListener() { 
                         public  void onClick(View v) { 
                                httpPostDemo(); 
                        } 
                }); 
                 
                Button btn3 = (Button)  this.findViewById(R.id.btn3); 
                 // DOM - Document Object Model 
                btn3.setText( "DOM 解析 XML"); 
                btn3.setOnClickListener( new Button.OnClickListener() { 
                         public  void onClick(View v) { 
                                DOMDemo(); 
                        } 
                }); 
                 
                Button btn4 = (Button)  this.findViewById(R.id.btn4); 
                 // SAX - Simple API for XML 
                btn4.setText( "SAX 解析 XML"); 
                btn4.setOnClickListener( new Button.OnClickListener() { 
                         public  void onClick(View v) { 
                                SAXDemo(); 
                        } 
                }); 
        } 
         
         // Android 调用 http 协议的 get 方法 
         // 本例:以 http 协议的 get 方法获取远程页面响应的内容 
         private  void httpGetDemo(){ 
                 try { 
                         // 模拟器测试时,请使用外网地址 
                        URL url =  new URL( "http://xxx.xxx.xxx"); 
                        URLConnection con = url.openConnection(); 
                         
                        String result = "http status code: " + ((HttpURLConnection)con).getResponseCode() + "\n"
                        // HttpURLConnection.HTTP_OK 
                         
                        InputStream is = con.getInputStream(); 
                        BufferedInputStream bis = new BufferedInputStream(is); 
                        ByteArrayBuffer bab = new ByteArrayBuffer(32); 
                        int current = 0; 
                        while ( (current = bis.read()) != -1 ){ 
                                bab.append((byte)current); 
                        } 
                        result += EncodingUtils.getString(bab.toByteArray(), HTTP.UTF_8); 
                         
                        bis.close(); 
                        is.close(); 

                        textView.setText(result); 
                } catch (Exception e) { 
                        textView.setText(e.toString()); 
                } 
        } 
         
        // Android 调用 http 协议的 post 方法 
        // 本例:以 http 协议的 post 方法向远程页面传递参数,并获取其响应的内容 
        private void httpPostDemo(){ 
                try { 
                        // 模拟器测试时,请使用外网地址 
                        String url = "http://5billion.com.cn/post.php"; 
                        Map<String, String> data = new HashMap<String, String>(); 
                        data.put("name""webabcd"); 
                        data.put("salary""100"); 
                         
                        DefaultHttpClient httpClient = new DefaultHttpClient(); 
                        HttpPost httpPost = new HttpPost(url); 
                        ArrayList<BasicNameValuePair> postData = new ArrayList<BasicNameValuePair>(); 
                        for (Map.Entry<String, String> m : data.entrySet()) { 
                                postData.add(new BasicNameValuePair(m.getKey(), m.getValue())); 
                        } 

                        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(postData, HTTP.UTF_8); 
                        httpPost.setEntity(entity); 
                         
                        HttpResponse response = httpClient.execute(httpPost); 
                         
                        String result = "http status code: " + response.getStatusLine().getStatusCode() + "\n"
                        // HttpURLConnection.HTTP_OK 
                         
                        HttpEntity httpEntity = response.getEntity(); 
                         
                        InputStream is = httpEntity.getContent(); 
                        result += convertStreamToString(is); 
                         
                        textView.setText(result); 
                } catch (Exception e) { 
                        textView.setText(e.toString());         
                } 
        } 
         
        // 以 DOM 方式解析 XML(xml 数据详见 res/raw/employee.xml) 
        private void DOMDemo(){ 
                try        { 
                        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); 
                        DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); 
                        Document doc = docBuilder.parse(this.getResources().openRawResource(R.raw.employee)); 
                        Element rootElement = doc.getDocumentElement(); 
                        NodeList employeeNodeList = rootElement.getElementsByTagName("employee"); 
                         
                        textView.setText("DOMDemo" + "\n"); 
                        String title = rootElement.getElementsByTagName("title").item(0).getFirstChild().getNodeValue(); 
                        textView.append(title); 
                        for (int i=0; i<employeeNodeList.getLength(); i++){ 
                                Element employeeElement = ((Element)employeeNodeList.item(i)); 
                                String name = employeeElement.getAttribute("name"); 
                                String salary = employeeElement.getElementsByTagName("salary").item(0).getFirstChild().getNodeValue(); 
                                String dateOfBirth = employeeElement.getElementsByTagName("dateOfBirth").item(0).getFirstChild().getNodeValue(); 
                                textView.append("\nname: "+name+" salary: "+salary+" dateOfBirth: " + dateOfBirth); 
                        } 
                } catch (Exception e) { 
                        textView.setText(e.toString());         
                } 
        } 
         
        // 以 SAX 方式解析 XML(xml 数据详见 res/raw/employee.xml) 
        // SAX 解析器的实现详见 MySAXHandler.java 
        private void SAXDemo(){ 
                try        { 
                        SAXParserFactory saxFactory = SAXParserFactory.newInstance(); 
                        SAXParser parser = saxFactory.newSAXParser(); 
                        XMLReader reader = parser.getXMLReader(); 
                         
                        MySAXHandler handler = new MySAXHandler(); 
                        reader.setContentHandler(handler); 
                        reader.parse(new InputSource(this.getResources().openRawResource(R.raw.employee))); 
                        String result = handler.getResult(); 
                        textView.setText("SAXDemo" + "\n"); 
                        textView.append(result); 
                } catch (Exception e) { 
                        textView.setText(e.toString());         
                } 
        } 

        // 辅助方法,用于把流转换为字符串 
        private String convertStreamToString(InputStream is) { 
                BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 
                StringBuilder sb = new StringBuilder();        

                String line = null
                try { 
                        while ((line = reader.readLine()) != null) { 
                                sb.append(line + "\n"); 
                        } 
                } catch (IOException e) { 
                        e.printStackTrace(); 
                } finally { 
                        try { 
                                is.close(); 
                        } catch (IOException e) { 
                                e.printStackTrace(); 
                        } 
                }        

                return sb.toString(); 
        } 
}
 
 
2、用 Handler 来实现异步消息处理,以一个可以实时汇报下载进度的异步下载类为例
开发一个 Android 类库,本例中此类库名为 webabcd_util

New -> Java Project
项目上点右键 -> Build Path -> Add Libraries -> User Library -> User Libraries -> New -> 为类库起个名字 -> 选中这个类库 -> Add JARs 导入 Android 的 jar 包
项目上点右键 -> Build Path -> Add Libraries -> User Library -> 选择 Android 库

DownloadManagerAsync.java
package webabcd.util; 

import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.URL; 
import java.net.URLConnection; 

import org.apache.http.protocol.HTTP; 

import android.os.Handler; 
import android.os.Message; 
import android.util.Log; 

// 以一个实例,即异步下载,来演示 Android 的异步消息处理(用 Handler 的方式) 
public  class DownloadManagerAsync { 

         public DownloadManagerAsync() { 

        } 

         // 实例化自定义的 Handler 
        EventHandler mHandler =  new EventHandler( this); 

         // 按指定 url 地址下载文件到指定路径 
         public  void download( final String url,  final String savePath) { 
                 new Thread( new Runnable() { 
                         public  void run() { 
                                 try { 
                                        sendMessage(FILE_DOWNLOAD_CONNECT); 
                                        URL sourceUrl =  new URL(url); 
                                        URLConnection conn = sourceUrl.openConnection(); 
                                        InputStream inputStream = conn.getInputStream(); 

                                         int fileSize = conn.getContentLength(); 

                                        File savefile =  new File(savePath); 
                                         if (savefile.exists()) { 
                                                savefile.delete(); 
                                        } 
                                        savefile.createNewFile(); 

                                        FileOutputStream outputStream =  new FileOutputStream( 
                                                        savePath,  true); 

                                         byte[] buffer =  new  byte[1024]; 
                                         int readCount = 0; 
                                         int readNum = 0; 
                                         int prevPercent = 0; 
                                         while (readCount < fileSize && readNum != -1) { 
                                                readNum = inputStream.read(buffer); 
                                                 if (readNum > -1) { 
                                                        outputStream.write(buffer); 
                                                        readCount = readCount + readNum; 

                                                         int percent = ( int) (readCount * 100 / fileSize); 
                                                         if (percent > prevPercent) { 
                                                                 // 发送下载进度信息 
                                                                sendMessage(FILE_DOWNLOAD_UPDATE, percent, 
                                                                                readCount); 

                                                                prevPercent = percent; 
                                                        } 
                                                } 
                                        } 

                                        outputStream.close(); 
                                        sendMessage(FILE_DOWNLOAD_COMPLETE, savePath); 

                                }  catch (Exception e) { 
                                        sendMessage(FILE_DOWNLOAD_ERROR, e); 
                                        Log.e( "MyError", e.toString()); 
                                } 
                        } 
                }).start(); 
        } 

         // 读取指定 url 地址的响应内容 
         public  void download( final String url) { 
                 new Thread( new Runnable() { 
                         public  void run() { 
                                 try { 
                                        sendMessage(FILE_DOWNLOAD_CONNECT); 
                                        URL sourceUrl =  new URL(url); 
                                        URLConnection conn = sourceUrl.openConnection(); 
                                        conn.setConnectTimeout(3000); 
                                        BufferedReader reader =  new BufferedReader( 
                                                         new InputStreamReader(conn.getInputStream(), 
                                                                        HTTP.UTF_8)); 

                                        String line =  null
                                        StringBuffer content =  new StringBuffer(); 
                                         while ((line = reader.readLine()) !=  null) { 
                                                content.append(line); 
                                        } 

                                        reader.close(); 

                                        sendMessage(FILE_DOWNLOAD_COMPLETE, content.toString()); 

                                }  catch (Exception e) { 
                                        sendMessage(FILE_DOWNLOAD_ERROR, e); 
                                        Log.e( "MyError", e.toString()); 
                                } 
                        } 
                }).start(); 
        } 

         // 向 Handler 发送消息 
         private  void sendMessage( int what, Object obj) { 
                 // 构造需要向 Handler 发送的消息 
                Message msg = mHandler.obtainMessage(what, obj); 
                 // 发送消息 
                mHandler.sendMessage(msg); 
        } 

         private  void sendMessage( int what) { 
                Message msg = mHandler.obtainMessage(what); 
                mHandler.sendMessage(msg); 
        } 

         private  void sendMessage( int what,  int arg1,  int arg2) { 
                Message msg = mHandler.obtainMessage(what, arg1, arg2); 
                mHandler.sendMessage(msg); 
        } 

         private  static  final  int FILE_DOWNLOAD_CONNECT = 0; 
         private  static  final  int FILE_DOWNLOAD_UPDATE = 1; 
         private  static  final  int FILE_DOWNLOAD_COMPLETE = 2; 
         private  static  final  int FILE_DOWNLOAD_ERROR = -1; 

         // 自定义的 Handler 
         private  class EventHandler  extends Handler { 
                 private DownloadManagerAsync mManager; 

                 public EventHandler(DownloadManagerAsync manager) { 
                        mManager = manager; 
                } 

                 // 处理接收到的消息 
                @Override 
                 public  void handleMessage(Message msg) { 

                         switch (msg.what) { 
                         case FILE_DOWNLOAD_CONNECT: 
                                 if (mOnDownloadConnectListener !=  null
                                        mOnDownloadConnectListener.onDownloadConnect(mManager); 
                                 break
                         case FILE_DOWNLOAD_UPDATE: 
                                 if (mOnDownloadUpdateListener !=  null
                                        mOnDownloadUpdateListener.onDownloadUpdate(mManager, 
                                                        msg.arg1); 
                                 break
                         case FILE_DOWNLOAD_COMPLETE: 
                                 if (mOnDownloadCompleteListener !=  null
                                        mOnDownloadCompleteListener.onDownloadComplete(mManager, 
                                                        msg.obj); 
                                 break
                         case FILE_DOWNLOAD_ERROR: 
                                 if (mOnDownloadErrorListener !=  null
                                        mOnDownloadErrorListener.onDownloadError(mManager, 
                                                        (Exception) msg.obj); 
                                 break
                         default
                                 break
                        } 
                } 
        } 

         // 定义连接事件 
         private OnDownloadConnectListener mOnDownloadConnectListener; 
         public  interface OnDownloadConnectListener { 
                 void onDownloadConnect(DownloadManagerAsync manager); 
        } 
         public  void setOnDownloadConnectListener(OnDownloadConnectListener listener) { 
                mOnDownloadConnectListener = listener; 
        } 

         // 定义下载进度更新事件 
         private OnDownloadUpdateListener mOnDownloadUpdateListener; 
         public  interface OnDownloadUpdateListener { 
                 void onDownloadUpdate(DownloadManagerAsync manager,  int percent); 
        } 
         public  void setOnDownloadUpdateListener(OnDownloadUpdateListener listener) { 
                mOnDownloadUpdateListener = listener; 
        } 

         // 定义下载完成事件 
         private OnDownloadCompleteListener mOnDownloadCompleteListener; 
         public  interface OnDownloadCompleteListener { 
                 void onDownloadComplete(DownloadManagerAsync manager, Object result); 
        } 
         public  void setOnDownloadCompleteListener( 
                        OnDownloadCompleteListener listener) { 
                mOnDownloadCompleteListener = listener; 
        } 

         // 定义下载异常事件 
         private OnDownloadErrorListener mOnDownloadErrorListener; 
         public  interface OnDownloadErrorListener { 
                 void onDownloadError(DownloadManagerAsync manager, Exception e); 
        } 
         public  void setOnDownloadErrorListener(OnDownloadErrorListener listener) { 
                mOnDownloadErrorListener = listener; 
        } 
}
 
调用上面的自定义的 Android 类库

项目上点右键 -> Properties -> Java Build Path -> Projects -> Add 引用上面的类库

Main.java
package com.webabcd.handler; 

import android.app.Activity; 
import android.os.Bundle; 
import android.widget.TextView; 

import webabcd.util.DownloadManagerAsync; 

public  class Main  extends Activity  implements 
                DownloadManagerAsync.OnDownloadCompleteListener, 
                DownloadManagerAsync.OnDownloadUpdateListener, 
                DownloadManagerAsync.OnDownloadErrorListener { 
         
        TextView txt; 
         
         /** Called when the activity is first created. */ 
        @Override 
         public  void onCreate(Bundle savedInstanceState) { 
                 super.onCreate(savedInstanceState); 
                setContentView(R.layout.main); 
                 
                DownloadManagerAsync manager =  new DownloadManagerAsync(); 
                manager.setOnDownloadCompleteListener( this); 
                manager.setOnDownloadUpdateListener( this); 
                manager.download( "http://files.cnblogs.com/webabcd/Android.rar", "/sdcard/Android.rar"); 
                 
                txt = (TextView) this.findViewById(R.id.txt); 
                txt.setText("开始下载"); 
        } 

        public void onDownloadComplete(DownloadManagerAsync manager, Object result) { 

                txt.setText("下载完成"); 
        } 
         
        public void onDownloadUpdate(DownloadManagerAsync manager, int percent) { 

                txt.setText("下载进度:" + String.valueOf(percent) + "%"); 
        } 
         
        public void onDownloadError(DownloadManagerAsync manager, Exception e) { 

                txt.setText("下载出错"); 
        } 
}
 


     本文转自webabcd 51CTO博客,原文链接: http://blog.51cto.com/webabcd/342102 ,如需转载请自行联系原作者


相关文章
|
9月前
|
缓存 监控 搜索推荐
301重定向实现原理全面解析:从HTTP协议到SEO最佳实践
301重定向是HTTP协议中的永久重定向状态码,用于告知客户端请求的资源已永久移至新URL。它在SEO中具有重要作用,能传递页面权重、更新索引并提升用户体验。本文详解其工作原理、服务器配置方法(如Apache、Nginx)、对搜索引擎的影响及最佳实践,帮助实现网站平稳迁移与优化。
1035 68
|
8月前
|
缓存 网络协议 UED
深度解析HTTP协议从版本0.9至3.0的演进和特性。
总的来说,HTTP的演进是互联网技术不断发展和需求日益增长的结果。每一次重要更新都旨在优化性能,增进用户体验,适应新的应用场景,而且保证了向后兼容,让互联网的基础架构得以稳定发展。随着网络技术继续进步,我们可以预期HTTP协议在未来还会继续演化。
956 0
|
8月前
|
数据采集 JSON Go
Go语言实战案例:实现HTTP客户端请求并解析响应
本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。
|
10月前
|
网络协议 API Python
解析http.client与requests在Python中的性能比较和改进策略。
最后,需要明确的是,这两种库各有其优点和适用场景。`http.client` 更适合于基础且并行的请求,`requests` 则因其易用且强大的功能,更适用于复杂的 HTTP 场景。对于哪种更适合你的应用,可能需要你自己进行实际的测试来确定。
244 10
|
11月前
|
域名解析 网络协议 网络安全
SSL证书验证全攻略:DNS/HTTP/手动解析怎么选?
SSL证书在网络安全中至关重要,1Panel提供三种验证方式:DNS验证、HTTP验证和手动解析。DNS验证便捷,适合CDN网站;HTTP验证快速,需服务器在线;手动解析灵活,但操作复杂。根据需求选择合适确认方式,定期检查证书状态。
1123 2
|
11月前
|
安全 网络协议 算法
HTTP/HTTPS与SOCKS5协议在隧道代理中的兼容性设计解析
本文系统探讨了构建企业级双协议隧道代理系统的挑战与实现。首先对比HTTP/HTTPS和SOCKS5协议特性,分析其在工作模型、连接管理和加密方式上的差异。接着提出兼容性架构设计,包括双协议接入层与统一隧道内核,通过协议识别模块和分层设计实现高效转换。关键技术部分深入解析协议转换引擎、连接管理策略及加密传输方案,并从性能优化、安全增强到典型应用场景全面展开。最后指出未来发展趋势将更高效、安全与智能。
511 1
|
网络安全
网络问题解析:如何解决CondaHTTPError HTTP 000 CONNECTION FAILED错误。
以上就是斯诺普为你准备的解决Conda出现HTTP连接错误的手术室。希望这辆小车可以顺利驶出棘手的泥潭,再次在自由的大路上疾驰。一切的尝试和努力,只为更好的探索与开发。
476 17
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
1251 29
|
12月前
|
安全 网络安全 数据安全/隐私保护
HTTP 与 HTTPS 协议及 SSL 证书解析-http和https到底有什么区别?-优雅草卓伊凡
HTTP 与 HTTPS 协议及 SSL 证书解析-http和https到底有什么区别?-优雅草卓伊凡
673 3
|
缓存 安全 Java
深入解析HTTP请求方法:Spring Boot实战与最佳实践
这篇博客结合了HTTP规范、Spring Boot实现和实际工程经验,通过代码示例、对比表格和架构图等方式,系统性地讲解了不同HTTP方法的应用场景和最佳实践。
1080 5

推荐镜像

更多
  • DNS
  • 下一篇
    开通oss服务