C#之WebClient学习笔记

来源:互联网 发布:金蝶软件多少钱 编辑:程序博客网 时间:2024/05/21 02:19

        最近在用C#做项目,需要和HTTP服务器通信,网上的资料很多,样例代码不少,但为了实地验证一下WebClient的用法,所以准备了一套简单的环境。下面记录了验证WebClient类使用方法的笔记。

基本环境

HTTP服务器

        由于对Java了解更多,所以决定使用tomcat来做HTTP服务器。从官网下载了新版本的tomcat和j2ee Eclipse,准备了Web开发环境,开发一个简单的Servlet,专用于接收HTTP请求消息,分析消息的内容。在Eclipse里搭建web开发环境的过程网上有很多,所以这里不详细写。Servlet的源码如下。

package com.jackie;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.util.Collection;import java.util.Enumeration;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.Part;/** * Servlet implementation class Player */@WebServlet("/Player")public class Player extends HttpServlet {    private static final long serialVersionUID = 1L;    /**     * Default constructor.     */    public Player() {    }    /**     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse     *      response)     */    @Override    protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException,    IOException {        System.out.println("in doGet");        process(request, response);    }    /**     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse     *      response)     */    @Override    protected void doPost(final HttpServletRequest request, final HttpServletResponse response)            throws ServletException, IOException {        System.out.println("in doPost");        process(request, response);    }    private void process(final HttpServletRequest request, final HttpServletResponse response) throws IOException,    IllegalStateException, ServletException {        final Enumeration<String> headers = request.getHeaderNames();        while (headers.hasMoreElements()) {            final String headerName = headers.nextElement();            final String headerValue = request.getHeader(headerName);            System.out.println("HEADER, " + headerName + "=" + headerValue);        }        final Enumeration<String> attributes = request.getAttributeNames();        while (attributes.hasMoreElements()) {            final String attrName = attributes.nextElement();            final Object attrValue = request.getAttribute(attrName);            System.out.println("ATTRIBUTE, " + attrName + "=" + attrValue);        }        final int contentLength = request.getContentLength();        System.out.println("ContentLength=" + contentLength);        final InputStream stream = request.getInputStream();        try (final BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {            String line = null;            while ((line = reader.readLine()) != null) {                System.out.println("INPUT, line=" + line);            }        }        System.out.println("QueryString=" + request.getQueryString());        System.out.println("RequestUrl=" + request.getRequestURL());        System.out.println("PathInfo=" + request.getPathInfo());        System.out.println("PathInfo=" + request.getPathTranslated());        final Collection<Part> parts = request.getParts();        for (final Part part : parts) {            System.out.println("Part, name=" + part.getName() + ", value=" + part.getContentType());        }        response.setStatus(HttpServletResponse.SC_OK);        final String out = "hello1111";        final OutputStream os = response.getOutputStream();        os.write(out.getBytes());        response.setContentLength(out.length());        response.setContentType("txt/html");    }}

        代码里把request对象里能输出的信息都通过命令行输出出来,方便观察行为。

HTTP客户端

        下载官方的C#开发环境,VS C# express 2010版本,安装完成之后需要注册,否则只有30天使用期限。创建一个命令行工程,加入如下代码。

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Net;using System.Threading;namespace ConsoleApplication{    class Program    {        static void Main(string[] args)        {            string url = "http://localhost:8080/Player";            using (WebClient wc = new WebClient())            {                wc.QueryString.Add("aaa", "bbb");                wc.QueryString.Add("aaa1", "bbb1");                wc.QueryString.Add("aaa2", "bbb2");                wc.Proxy = null;                wc.Headers.Add("wc", "value");                string data = wc.DownloadString(url);                Console.WriteLine("data {0}", data);                wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);                wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted2);                wc.DownloadStringAsync(new Uri(url));                                Thread.Sleep(2000);                byte[] buffer = wc.DownloadData(url);                data = Encoding.UTF8.GetString(buffer);                Console.WriteLine("data1 {0}", data);                wc.DownloadDataCompleted += new DownloadDataCompletedEventHandler(wc_DownloadDataCompleted);                wc.DownloadDataAsync(new Uri(url));                                Thread.Sleep(2000);            }                    }        static void wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)        {            if (e.Error != null)            {                Console.WriteLine("error {0}", e.Error.Message);                return;            }            string data = Encoding.UTF8.GetString(e.Result);            Console.WriteLine("wc_DownloadDataCompleted {0}", data);        }        static void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)        {            if (e.Error != null)            {                Console.WriteLine("error {0}", e.Error.Message);                return;            }            Console.WriteLine("wc_DownloadStringCompleted {0}", e.Result);        }        static void wc_DownloadStringCompleted2(object sender, DownloadStringCompletedEventArgs e)        {            if (e.Error != null)            {                Console.WriteLine("error {0}", e.Error.Message);                return;            }            Console.WriteLine("wc_DownloadStringCompleted2 {0}", e.Result);        }    }}

收获

        之前一直使用Java来做C/S架构的应用,其它技术了解不多,感觉可以学到不少东东。

C#相关

1、event类型只允许有+=和-=两种运算,换句话说就是只能增加和删除事件处理方法,其它的运算都是非法的。这一点比较有用,假如支持=运算的话,会在增加事件处理器的时候,意外的把已增加的事件处理器删除掉,由此可见,C#在设计时已经屏蔽了容易出错的运算行为。

2、event类型的对象可以增加多个事件处理器方法,处理器方法执行时的顺序和增加的顺序相同。

3、using指令,用于释放系统资源。这个语法非常好用,不需要写恶心的try catch finally。本来Java 7提供了类似的语法,只可惜我所在的项目组还在使用JDK1.6版本,所以新的语法特性带来的便利暂时还享受不到。

4、和Java的字符串格式化方法相比,C#提供的字符串格式化方法在使用上还是非常方便的,一般场景下只需要写{0},而Java则需要写%1$s,省心不少。

WebClient相关

1、 这个类封装了HTPP Get消息相关的使用接口,对一个操作,同时提供了同步接口和异步接口,比如样例代码中的DownloadString和DownloadStringAsync。同时封装了事件完成之后的回调处理器,使用上非常方便。只是第一次看到的时候感觉不习惯,因为方法的命名和事件的处理方式和Java语言有不少差异。另外看惯了JDK自带的DOC文档,再回来阅读MSDN,也不太习惯,找想要的资料时比较吃力。

2、从WebClient类暴露的方法看,应当是对类HttpWebRequest和HttpWebResponse的封装,结果是更加好用。直接使用HttpWebRequest类虽然很灵活,但是在异步处理消息时,由于事件没有封装在一起,其实是蛮难用的,代码比较丑。

3、WebClient类通过OpenWriteAsync和OpenWrite方法可以显式控制HTTP方法,比如使用POST还是GET来传输数据,比较方便。但使用这两个方法时无法获取到HTTP服务器端返回的数据,如果上传数据结束之后还希望提取到HTTP响应消息体里的信息,则最好使用UploadDataXXX之类的方法。

HTTP服务

1、QueryString是什么,在验证WebClient的时候发现可以控制HTTP请求的QueryString,简单验证之后发现原来是URL之后的参数列表,比如有http://1.1.1.1/player?aaa=ccc&bbb=ddd,那么QueryString即是aaa=ccc&bbb=ddd。

2、GET和POST消息里,都可以在URL后面增加QueryString,这也是一大发现。


原创粉丝点击