HttpClient的使用

1.拳头之Get/Post
拳头是最基本的一重武器,也是最重要的,好比练武之人必须先扎稳马步。

java 代码
  1. HttpClient httpclient=new HttpClient();//创建一个客户端,类似打开一个浏览器  
  2. GetMethod getMethod=new GetMethod("http://www.blablabla.com");//创建一个get方法,类似在浏览器地址栏中输入一个地址  
  3. int statusCode=httpclient.executeMethod(getMethod);//回车——出拳!  
  4. System.out.println("response=" + getMethod.getResponseBodyAsString());//察看拳头命中情况,可以获得的东西还有很多,比如head, cookies等等  
  5. getMethod.releaseConnection();//释放,记得收拳哦  



2.孔雀翎之支持https

如何支持https?

java 代码
  1. static{  
  2.     Protocol easyhttps = new Protocol("https"new EasySSLProtocolSocketFactory(), 443);  
  3.     Protocol.registerProtocol("https", easyhttps);  
  4. }  


在执行具体的http method之前,暗中将https协议注册一把,如孔雀翎暗藏玄机,毙敌于无形。记住,官方的binary发行版本没有ssl的contribute包,方法一是下载源代码版本来打造你的孔雀翎。

3.多情环之cookies
常道人老多情,其实是记忆太多,所以情之所至,正如cookies甜心,无论你走到那,总把你牵挂:

java 代码
  1. HttpClient httpclient=new HttpClient();  
  2. httpclient.getParams().setCookiePolicy(CookiePolicy.RFC_2109);//RFC_2109是支持较普遍的一个,还有其他cookie协议  
  3. HttpState initialState = new HttpState();  
  4. Cookie cookie=new Cookie();  
  5. cookie.setDomain("www.balblabla.com");  
  6. cookie.setPath("/");  
  7. cookie.setName("多情环");  
  8. cookie.setValue("多情即无情");  
  9. initialState.addCookie(cookie);  
  10. httpclient.setState(initialState);  
  11. ...  



4.离别钩之解构cookies

多情环的反面即离别钩,钩出,敌之身体某个部件即要与身体别离,端的是无情:

java 代码
  1. ...//执行了某些get/post方法后  
  2. Cookie[] cookies = httpclient.getState().getCookies();  
  3. System.out.println("Present cookies: ");  
  4. for (int i = 0; i < cookies.length; i++) {//循环结构零部件  
  5.     System.out.println(" - " + cookies[i].toExternalForm());  
  6.     System.out.println(" - domain=" + cookies[i].getDomain());  
  7.     System.out.println(" - path=" + cookies[i].getPath());  
  8.     ...            
  9. }  



5.霸王抢之post参数
枪,长兵器之王,诸多名将均使一杆或金或银命名的名枪,比如岳飞。post方法在提交参数对时,犹如灵蛇出洞:

java 代码
  1. PostMethod postMethod = new PostMethod("http://www.saybot.com/postme");  
  2. NameValuePair[] postData = new NameValuePair[2];  
  3. postData[0] = new NameValuePair("武器""枪");  
  4. postData[1] = new NameValuePair("什么枪""神枪");  
  5. postMethod.addParameters(postData);  
  6. ...//出枪吧  



6.七星碧玉刀之支持代理(proxy)

代理,非常重要,尤其在局域网横行的年头,没有代理,你在公司上不了QQ,没有代理,google不了网页快照,代理之威,可比七星碧玉刀,无刀,在局域网和开发当中,一切白搭:

java 代码
  1. HttpClient httpclient=new HttpClient();  
  2. httpClient.getHostConfiguration().setProxy("192.168.0.1"9527);  
  3. httpClient.getParams().setAuthenticationPreemptive(true);//重要!!!告诉httpclient,使用抢先认证,否则你会收到“你没有资格”的恶果  
  4. /* 
  5.   这一步也至关重要,MyProxyCredentialsProvider实现了org.apache.commons.httpclient.auth.CredentialsProvider接口, 
  6.   返回代理的credential(username/password)*/  
  7. httpClient.getParams().setParameter(CredentialsProvider.PROVIDER, new MyProxyCredentialsProvider());  
  8. httpClient.getState().setProxyCredentials(  
  9.     new AuthScope("192.168.0.1",  
  10.         AuthScope.ANY_PORT, //任意端口哦,可要小心  
  11.         AuthScope.ANY_REALM),//任意域哦,可要小心  
  12. new UsernamePasswordCredentials("username",//proxy的用户名  
  13.                         "password"));//proxy的密码  


...

7.长生剑之天下第一
看httpclient的官方文档:jakarta.apache.org/commons/httpclient/userguide.html
看Hilton网友写的小葵花宝典笔记:www.cnjm.net/tech/article1155.html
通读后,你会有种拔剑四顾心茫然的高手感觉

 

 

 

 

 

 

 

 

 

利用HttpClient来获取JSON数据代码:

 

 public static String getJsonData(String url, String data) throws Exception{  
     
  Integer statusCode = -1;
  // Create HttpClient Object
  DefaultHttpClient client = new DefaultHttpClient();
  // Send data by post method in HTTP protocol,use HttpPost instead of
  // PostMethod which was occurred in former version
  HttpPost post = new HttpPost(url);
  // Construct a string entity
  StringEntity entity = new StringEntity(data,"UTF-8");
  entity.setContentType("application/json;charset=UTF-8");
  // Set XML entity
  post.setEntity(entity);
  // Set content type of request header
  post.setHeader("accept", "application/json");
  post.setHeader("Content-Type", "application/json;charset=UTF-8");
  // Execute request and get the response
  HttpResponse response = client.execute(post);

  // Response Header - StatusLine - status code
  statusCode = response.getStatusLine().getStatusCode();
  
  if (statusCode != HttpStatus.SC_OK) {
   throw new HttpException("Http Status is error.");
  }
  HttpEntity entityRsp = response.getEntity();
  StringBuffer result = new StringBuffer();
  BufferedReader rd = new BufferedReader(new InputStreamReader(entityRsp
    .getContent(), HTTP.UTF_8));
  String tempLine = rd.readLine();
  while (tempLine != null) {
   result.append(tempLine);
   tempLine = rd.readLine();
  }

  if (entityRsp != null) {
   entityRsp.consumeContent();
  }
  return result.toString();

 }

 

项目中与对方进行数据交互时,对方提供了一套夸域json方式传递数据,并给出了一个js示例

  1. $.getJSON(  
  2.     "http://www.----aspx?callback=?",  
  3.     {Name:"123",Pass:"123"},   
  4.     function(json){  
  5.         if(json.UserId==null){  
  6.             alert("NO");  
  7.         }else{  
  8.             alert(json.UserId);  
  9.         }  
  10.     }  
  11. );  

 但是此方法处理数据时,只能在页面中进行,局限性很大。因此在具体实施时,使用了HttpClient来代替。

  1. import java.io.InputStreamReader;  
  2. import java.util.ArrayList;  
  3. import java.util.List;  
  4.   
  5. import org.apache.http.HttpEntity;  
  6. import org.apache.http.HttpResponse;  
  7. import org.apache.http.HttpStatus;  
  8. import org.apache.http.NameValuePair;  
  9. import org.apache.http.client.HttpClient;  
  10. import org.apache.http.client.methods.HttpGet;  
  11. import org.apache.http.client.utils.URLEncodedUtils;  
  12. import org.apache.http.impl.client.DefaultHttpClient;  
  13. import org.apache.http.message.BasicNameValuePair;  
  14. import org.apache.http.protocol.HTTP;  
  15. import org.json.JSONException;  
  16. import org.json.JSONObject;  
  17. import org.json.JSONTokener;  
  18.   
  19.   
  20. /** 
  21.  * 使用HttpClient请求页面并返回json格式数据. 
  22.  * 对方接收的也是json格式数据。 
  23.  * 因此使用HttpGet。 
  24.  * */  
  25. public class Json {  
  26.       
  27.     public static void main(String[] args) throws JSONException {  
  28.           
  29.         JSONObject json = new JSONObject();  
  30.         List<NameValuePair> params = new ArrayList<NameValuePair>();  
  31.         params.add(new BasicNameValuePair("Name""123"));  
  32.         params.add(new BasicNameValuePair("Pass""123"));  
  33.         //要传递的参数.  
  34.         String url = "http://www.----aspx?" + URLEncodedUtils.format(params, HTTP.UTF_8);  
  35.         //拼接路径字符串将参数包含进去  
  36.         json = get(url);  
  37.         System.out.println(json.get("UserId"));  
  38.           
  39.     }  
  40.   
  41.     public static JSONObject get(String url) {  
  42.           
  43.         HttpClient client = new DefaultHttpClient();  
  44.         HttpGet get = new HttpGet(url);  
  45.         JSONObject json = null;  
  46.         try {  
  47.             HttpResponse res = client.execute(get);  
  48.             if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {  
  49.                 HttpEntity entity = res.getEntity();  
  50.                 json = new JSONObject(new JSONTokener(new InputStreamReader(entity.getContent(), HTTP.UTF_8)));  
  51.             }  
  52.         } catch (Exception e) {  
  53.             throw new RuntimeException(e);  
  54.               
  55.         } finally{  
  56.             //关闭连接 ,释放资源  
  57.             client.getConnectionManager().shutdown();  
  58.         }  
  59.         return json;  
  60.     }  
  61. }  

 

 

 

 

 

package com.lianlian.agentllav.web.phoneReader.action;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.http.HttpEntity;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class PhoneReaderAction {

 public static void main(String[] args) {
  
  HttpClient httpClient = new DefaultHttpClient();
  try {
   HttpGet httpGet = new HttpGet("地址");//此处传入请求地址,返回JSON格式数据
   System.out.println("手机报列表请求地址:" + httpGet.getURI());
   HttpResponse response = httpClient.execute(httpGet);
   HttpEntity entity = response.getEntity();
   System.out.println("----------------------------------------");
   System.out.println(response.getStatusLine());
   if (entity != null) {
    String contentString = EntityUtils.toString(entity);
    System.out.println("返回JSON:" + contentString);
    Gson gson = new Gson();       
    Type targetType = new TypeToken<List<ViewObj>>(){}.getType();  
    List<ViewObj> list = gson.fromJson(contentString,targetType);
    for(ViewObj vo : list){  
     System.out.println("原生方式: "+vo.getId()+","+vo.getName()+","+vo.getIntro());  
    }
   }else{
    //do something
   }
   System.out.println("----------------------------------------");
   //终止操作
   httpGet.abort();
  } catch (ClientProtocolException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   //关闭连接
   httpClient.getConnectionManager().shutdown();
  }
 }

}
------------------------------------------------------------------------------------------------

   HttpPost httpPost = new HttpPost(ORDER_URL);
   System.out.println("手机报订制地址:" + httpPost.getURI());
   List<NameValuePair> nvps = new ArrayList<NameValuePair>();
   nvps.add(new BasicNameValuePair("cid", channelNo));
   nvps.add(new BasicNameValuePair("mobile", custNo));
   nvps.add(new BasicNameValuePair("bid", bid));
   httpPost.setEntity(new UrlEncodedFormEntity(nvps));
   ResponseHandler<String> responseHandler = new BasicResponseHandler();
   String responseBody = httpClient.execute(httpPost, responseHandler);
   System.out.println("返回移动订制结果JSON:" + responseBody);//返回结果示例:{"result":1000}

   Gson gson = new Gson();
   Properties prop = gson.fromJson(responseBody, Properties.class);
   String reCode = prop.get("result").toString();

------------------------------------------------------------------------------------------------

//返回json格式为:

{"list":[{"id":137,"name":"打黑2","intro":"一场黑与黑的对决,一场情与法的冲突。绝望中的冷滟秋,手持致命“暗器”,在血与火的洗礼中,迅速做大,成为东州企业界一霸。可卧底棉球的死,让滟秋失去刻骨铭心的爱情,从而彻底走上一条不归路。"},{"id":138,"name":"余震","intro":"1976年7月的唐山,原本过着平凡幸福生活的一家四口,在某个傍晚遭遇了突然发生的地震。为了救孩子,父亲死了。但是两个孩子还被同一块楼板压在两边,想救哪一个都意味着要放弃另一个......"}]}
    Gson gson = new Gson();
    Type type = new TypeToken<HashMap<String, List<Book>>>() {}.getType();

    HashMap<String, List<Book>> hashMap = gson.fromJson(string, type);
    list = hashMap.get("list");

此处需要注意Book文件中只能包含id,name,intro属性,如需扩展属性,可通过extend 其他对象进行扩展,否则在windows下解析不会报错,可是到了linux系统下解析就报错了,本人暂时找不出原因。O(∩_∩)O哈哈~

 

 

复制代码
json数据格式解析我自己分为两种;

一种是普通的,一种是带有数组形式的;


 

普通形式的:
服务器端返回的json数据格式如下:

{"userbean":{"Uid":"100196","Showname":"\u75af\u72c2\u7684\u7334\u5b50","Avtar":null,"State":1}}

分析代码如下:

// TODO 状态处理 500 200 
                int res = 0; 
                res = httpClient.execute(httpPost).getStatusLine().getStatusCode(); 
                if (res == 200) { 
                    /* 
                     * 当返回码为200时,做处理 
                     * 得到服务器端返回json数据,并做处理 
                     * */ 
                    HttpResponse httpResponse = httpClient.execute(httpPost); 
                    StringBuilder builder = new StringBuilder(); 
                    BufferedReader bufferedReader2 = new BufferedReader( 
                            new InputStreamReader(httpResponse.getEntity().getContent())); 
                    String str2 = ""; 
                    for (String s = bufferedReader2.readLine(); s != null; s = bufferedReader2 
                            .readLine()) { 
                        builder.append(s); 
                    } 
                    Log.i("cat", ">>>>>>" + builder.toString());

JSONObject jsonObject = new JSONObject(builder.toString()) 
                        .getJSONObject("userbean"); 

                String Uid; 
                String Showname; 
                String Avtar; 
                String State; 

                Uid = jsonObject.getString("Uid"); 
                Showname = jsonObject.getString("Showname"); 
                Avtar = jsonObject.getString("Avtar"); 
                State = jsonObject.getString("State");
带数组形式的:
服务器端返回的数据格式为:

{"calendar": 
    {"calendarlist": 
            [ 
            {"calendar_id":"1705","title":"(\u4eb2\u5b50)ddssd","category_name":"\u9ed8\u8ba4\u5206\u7c7b","showtime":"1288927800","endshowtime":"1288931400","allDay":false}, 
            {"calendar_id":"1706","title":"(\u65c5\u884c)","category_name":"\u9ed8\u8ba4\u5206\u7c7b","showtime":"1288933200","endshowtime":"1288936800","allDay":false} 
            ] 
    } 
}

分析代码如下:

// TODO 状态处理 500 200 
                int res = 0; 
                res = httpClient.execute(httpPost).getStatusLine().getStatusCode(); 
                if (res == 200) { 
                    /* 
                     * 当返回码为200时,做处理 
                     * 得到服务器端返回json数据,并做处理 
                     * */ 
                    HttpResponse httpResponse = httpClient.execute(httpPost); 
                    StringBuilder builder = new StringBuilder(); 
                    BufferedReader bufferedReader2 = new BufferedReader( 
                            new InputStreamReader(httpResponse.getEntity().getContent())); 
                    String str2 = ""; 
                    for (String s = bufferedReader2.readLine(); s != null; s = bufferedReader2 
                            .readLine()) { 
                        builder.append(s); 
                    } 
                    Log.i("cat", ">>>>>>" + builder.toString()); 
                    /** 
                     * 这里需要分析服务器回传的json格式数据, 
                     */ 
                    JSONObject jsonObject = new JSONObject(builder.toString()) 
                            .getJSONObject("calendar"); 
                    JSONArray jsonArray = jsonObject.getJSONArray("calendarlist"); 
                    for(int i=0;i<jsonArray.length();i++){ 
                        JSONObject jsonObject2 = (JSONObject)jsonArray.opt(i); 
                        CalendarInfo calendarInfo = new CalendarInfo(); 
                        calendarInfo.setCalendar_id(jsonObject2.getString("calendar_id")); 
                        calendarInfo.setTitle(jsonObject2.getString("title")); 
                        calendarInfo.setCategory_name(jsonObject2.getString("category_name")); 
                        calendarInfo.setShowtime(jsonObject2.getString("showtime")); 
                        calendarInfo.setEndtime(jsonObject2.getString("endshowtime")); 
                        calendarInfo.setAllDay(jsonObject2.getBoolean("allDay")); 
                        calendarInfos.add(calendarInfo); 
                    }

总结,普通形式的只需用JSONObject ,带数组形式的需要使用JSONArray 将其变成一个list。
复制代码

 

 

 

复制代码
public static JSONObject post(String url,JSONObject json){
        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost(url);
        JSONObject response = null;
        try {
            StringEntity s = new StringEntity(json.toString());
            s.setContentEncoding("UTF-8");
            s.setContentType("application/json");
            post.setEntity(s);
            
            HttpResponse res = client.execute(post);
            if(res.getStatusLine().getStatusCode() == HttpStatus.OK.value()){
                HttpEntity entity = res.getEntity();
                String charset = EntityUtils.getContentCharSet(entity);
                response = new JSONObject(new JSONTokener(new InputStreamReader(entity.getContent(),charset)));
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return response;
    }
复制代码

 

 

复制代码
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ClientSendData {
    static Log log = LogFactory.getLog(ClientSendData.class);

    private String Url;

    // 初始化数据
    public ClientSendData() {
        Url = "https://test.yihaodian.com:8443/ims/feedbackToPingAn_getData.action";
    }

    public String sendData(String data) {
        String receivedData = null;
        try {

            Map<String, String> paramsData = new HashMap<String, String>();
            paramsData.put("data", data);
            receivedData = send(Url, paramsData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return receivedData;
    }

    public static String send(String url, Map<String, String> paramsMap) {
        String result = null;
        PostMethod postMethod = null;
        HttpClient httpClient = new HttpClient();

        httpClient.getParams().setParameter(
                HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8");
        postMethod = new PostMethod(url);

        if (paramsMap != null && paramsMap.size() > 0) {
            NameValuePair[] datas = new NameValuePair[paramsMap.size()];
            int index = 0;
            for (String key : paramsMap.keySet()) {
                datas[index++] = new NameValuePair(key, paramsMap.get(key));
            }
            postMethod.setRequestBody(datas);

        }

        HttpClientParams httparams = new HttpClientParams();
        httparams.setSoTimeout(60000);
        postMethod.setParams(httparams);

        try {
            int statusCode = httpClient.executeMethod(postMethod);
            if (statusCode == HttpStatus.SC_OK) {
                result = postMethod.getResponseBodyAsString();
                log.info("发送成功!");
            } else {
                log.error(" http response status is " + statusCode);
            }

        } catch (HttpException e) {
            log.error("error url=" + url, e);
        } catch (IOException e) {
            log.error("error url=" + url, e);
        } finally {
            if (postMethod != null) {
                postMethod.releaseConnection();
            }
        }

        return result;
    }

    public static void main(String[] args) {
        ClientSendData t = new ClientSendData();
        t.sendData("测试SSL单项连接,向服务端发送数据!");
    }
}
复制代码

可能出现的异常

1.java.net.ConnectException: Connection refused: connect

 

服务器没有启动

 

2 .javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed

 

服务端的证书是不可信的。解决办法见这篇文章 http://zhuyuehua.iteye.com/blog/1102347

 

3.java.net.SocketException: Software caused connection abort: recv failed

 

这是由于服务端配置的是SSL双向认证,而客户端发送数据是按照服务器是单向认证时发送的,即没有将客户端证书信息一起发送给服务端。

 

4.org.apache.commons.httpclient.NoHttpResponseException

 

这一般是服务端防火墙的原因。拦截了客户端请求。

 

另外,当服务端负载过重时,也会出现此问题。

 

5.javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake

 

这是由于服务端配置的是SSL双向认证,而客户端发送数据是按照服务器是单向认证时发送的,即没有将客户端证书信息一起发送给服务端。服务端验证客户端证书时,发现客户端没有证书,然后就断开了握手连接。

 

2.SSL双向验证时

 

双向验证时,暂时不知道如何用HTTPCLIENT发送数据,如需要双向验证时发送数据,参考我另外的文章。另外,有知道HTTPCLIENT如何在双向验证时发送数据的,恳请指教。

 

 

 

复制代码
httpclient 通过https访问网站的方式有两种,一种是需要导入证书,一种是不需要的。导入证书的安全性比较高,但是如果网站证书更新了,证书需要重新导入。下面的例子是不安全的:

package net.ben;


import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.util.ArrayList;
import java.util.List;

public class HttpClientTest {
    public static void main(String[] args) throws Exception {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        try {
            TrustManager easyTrustManager = new X509TrustManager() {

                public void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException {
                    //To change body of implemented methods use File | Settings | File Templates.
                }

                public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException {
                    //To change body of implemented methods use File | Settings | File Templates.
                }

                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return new java.security.cert.X509Certificate[0];  //To change body of implemented methods use File | Settings | File Templates.
                }
            };

            SSLContext sslcontext = SSLContext.getInstance("TLS");
            sslcontext.init(null, new TrustManager[]{easyTrustManager}, null);
            SSLSocketFactory sf = new SSLSocketFactory(sslcontext);

            Scheme sch = new Scheme("https", 443, sf);

            httpClient.getConnectionManager().getSchemeRegistry().register(sch);

            HttpGet httpget = new HttpGet("https://www.xxx.com/");

            System.out.println("executing request" + httpget.getRequestLine());

            HttpResponse response = httpClient.execute(httpget);
            HttpEntity entity = response.getEntity();

            System.out.println("----------------------------------------");
            System.out.println(response.getStatusLine());
            if (entity != null) {
                System.out.println("Response content length: " + entity.getContentLength());
            }
            String content = EntityUtils.toString(entity);
            System.out.println(content);


        } finally {
            httpClient.getConnectionManager().shutdown();
        }

    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值