Web Api 的优点

关于Web Api的描述,就不在赘述,下面一张偷过来的图,清晰的表明了 Web Api 的优点

WebApi入门_xml

什么时候使用Web Api

  • 需要Web Service但是不需要SOAP
  • 需要在已有的WCF服务基础上建立non-soap-based http服务
  • 只想发布一些简单的Http服务,不想使用相对复杂的WCF配置
  • 发布的服务可能会被带宽受限的设备访问
  • 希望使用开源框架,关键时候可以自己调试或者自定义一下框架

开始学习

为了证明 WEB API 的平台无关性质,下面将 以JavaC# 代码 共同请求一个C#写的 Web Api

搭建 WebApi

Step 1 建立项目

WebApi入门_入门_02

Step2 选择模板

WebApi入门_入门_03

Step 3 建立一个PersonModel类 在 Model 文件夹下 用于模拟一些数据

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace DemoWebApi.Models
{
    /// <summary>
    /// Person 类 用于模拟一些数据
    /// </summary>
    public class PersonModel
    {
        public string IdNumber { get; set; }

        public string Name { get; set; }

        public string Gender { get; set; }

        public string Address { get; set; }
    }
}

Step 4 建立一个控制器命名为 PersonController

WebApi入门_入门_04

Step 5: 了解控制器中的方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace DemoWebApi.Controllers
{
    public class PersonController : ApiController
    {
        // GET: api/Person
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET: api/Person/5
        public string Get(int id)
        {
            return "value";
        }

        // POST: api/Person
        public void Post([FromBody]string value)
        {
        }

        // PUT: api/Person/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE: api/Person/5
        public void Delete(int id)
        {
        }
    }
}

HTTP请求的方法 在 WebApi 中的用途
GET 用于查询
POST 用于添加
PUT 用于更新
DELETE 用于删除

完成WebApi

修改方法的命名

我想控制器中的方法名,我并不希望他们就是简单的Get Put 等。我希望给他们换一个更加容易理解的名字。

使用 [HttpGet]、[HttpPost]、[HttpPut]、[HttpDelete] 分别标记各个方法

[FromBody] 特性标记 该参数来自哪里 [FromBody] 表示来自 HTTP 请求体 [FromUri] 表示参数来自URL 地址

[HttpGet]
public IEnumerable<PersonModel> GetPersons()
  
[HttpGet]
public PersonModel GetPersonByIdNumber(PersonModel idNumber)

[HttpPost]
public void AddPerson([FromBody]PersonModel person)

[HttpPut]
public void UpdatePersonByIdNumber(int id, [FromBody]PersonModel person)

[HttpDelete]
public void DeletePersonByIdNumber(string idNumber)

完成方法

using DemoWebApi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace DemoWebApi.Controllers
{
    public class PersonController : ApiController
    {
        static List<PersonModel> personList = new List<PersonModel>()
        {
            new PersonModel() {  Name="鲁迅认识的那只猹", Gender="男", Address="来自星星", IdNumber="123"},
            new PersonModel() {  Name="路人甲", Gender="男", Address="Earth", IdNumber="124"},
            new PersonModel() {  Name="吃瓜群众", Gender="男", Address="Sky", IdNumber="125"},
        };

        /// <summary>
        /// 获取全部的Person
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IEnumerable<PersonModel> GetPersons()
        {
            return personList;
        }

        /// <summary>
        /// 根据IdNumber查找学生
        /// </summary>
        /// <param name="idNumber"></param>
        /// <returns></returns>
        [HttpGet]
        public PersonModel GetPersonByIdNumber(string idNumber)
        {
            return personList.Find(t => t.IdNumber == idNumber);
        }

        /// <summary>
        /// 添加一个 person
        /// </summary>
        /// <param name="person"></param>
        [HttpPost]
        public void AddPerson([FromBody]PersonModel person)
        {
            personList.Add(person);
        }

        /// <summary>
        /// 更新 指定idNumber 的person对象
        /// </summary>
        /// <param name="idNumber"></param>
        /// <param name="person"></param>
        [HttpPut]
        public void UpdatePersonByIdNumber([FromUri]string idNumber, [FromBody]PersonModel person)
        {
            PersonModel tempPerson = personList.Find(t => t.IdNumber == idNumber);
            if (tempPerson != null)
            {
                tempPerson.Name = person.Name;
                tempPerson.Address = person.Address;
                tempPerson.Gender = person.Gender;
            }
        }

        /// <summary>
        /// 根据idNumber 删除对象
        /// </summary>
        /// <param name="idNumber"></param>
        [HttpDelete]
        public void DeletePersonByIdNumber(string idNumber)
        {
            personList.RemoveAll(t => t.IdNumber == idNumber);
        }
    }
}

在浏览器中使用GET方法

直接运行在浏览器中查看 访问 http://localhost:60544/API/Person 这个地址,哈 我们发现 我们的数据直接就被显示成 xml格式了。

因为浏览器默认的网址就是发送的GET 请求,在浏览器中就可以直接查看,而不用去写额外的代码。

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfPersonModel xmlns="http://schemas.datacontract.org/2004/07/DemoWebApi.Models" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">  
  <PersonModel> 
    <Address>来自星星</Address>  
    <Gender>男</Gender>  
    <IdNumber>123</IdNumber>  
    <Name>鲁迅认识的那只猹</Name> 
  </PersonModel>  
  <PersonModel> 
    <Address>Earth</Address>  
    <Gender>男</Gender>  
    <IdNumber>124</IdNumber>  
    <Name>路人甲</Name> 
  </PersonModel>  
  <PersonModel> 
    <Address>Sky</Address>  
    <Gender>男</Gender>  
    <IdNumber>125</IdNumber>  
    <Name>吃瓜群众</Name> 
  </PersonModel> 
</ArrayOfPersonModel>

在浏览器使用IdNumber查找Person

运行程序并访问 以下的网址 http://localhost:60544/API/Person?IdNumber=123 , 我们发现我们想要的内容出现了。

<?xml version="1.0" encoding="utf-8"?>

<PersonModel xmlns="http://schemas.datacontract.org/2004/07/DemoWebApi.Models" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">  
  <Address>来自星星</Address>  
  <Gender>男</Gender>  
  <IdNumber>123</IdNumber>  
  <Name>鲁迅认识的那只猹</Name> 
</PersonModel>

通过代码进行GET POST PUT DELETE 操作

我们的代码将会有C#何Java两个不同的版本。用来测试我们的WebApi , 由于比较懒,我就不进行发布到IIS操作了,访问的时候,我将直接运行着我的WebApi进行操作。

GET 请求

这里只查询了全部的Person, 如果想要 根据 IdNumber 查询,可以使用 URL 串参数的方式进行查询

如: http://localhost:60544/API/Person?IdNumber=123

C#版本

static void GetPerson()
{
    HttpWebRequest webRequest = WebRequest.Create("http://localhost:60544/API/Person") as HttpWebRequest;
    webRequest.Method = "GET";

    //设置一些请求的参数
    //这是可接收内容的类型 /webRequest.ContentType = "text/json" 为 json 格式
    // webRequest.ContentType = "text/xml"; 为xml格式
    webRequest.ContentType = "text/json";
    //webRequest.ContentType = "text/xml";

    //直到 执行GeTResponse() 时候才进行发送请求
    HttpWebResponse response = webRequest.GetResponse() as HttpWebResponse;

    //获取结果代码
    HttpStatusCode code = response.StatusCode;

    Console.WriteLine(code.ToString());

    Stream stream = response.GetResponseStream();

    StreamReader reader = new StreamReader(stream, Encoding.UTF8);
    string value = reader.ReadToEnd();

    Console.WriteLine(value);

    stream.Close();
    stream.Flush();
}

输出结果

[
    {
        "IdNumber": "123", 
        "Name": "鲁迅认识的那只猹", 
        "Gender": "男", 
        "Address": "来自星星"
    }, 
    {
        "IdNumber": "124", 
        "Name": "路人甲", 
        "Gender": "男", 
        "Address": "Earth"
    }, 
    {
        "IdNumber": "125", 
        "Name": "吃瓜群众", 
        "Gender": "男", 
        "Address": "Sky"
    }
]

Java 版本

public static void getPerson() {
	try {
		URL url = new URL("http://localhost:60544/API/Person");
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		// 设置一些请求的属性
		conn.setRequestProperty("ContentType", "text/json");
		// 设置请求方法
		conn.setRequestMethod("GET");
		// 获取结果码
		int code = conn.getResponseCode();
		System.out.println("结果代码:" + code);
		StringBuffer buffer = new StringBuffer();
		// 获取到请求的结果
		InputStreamReader reader = new InputStreamReader(conn.getInputStream(), "utf-8");

		int c = -1;
		while ((c = reader.read()) != -1) {
			buffer.append((char) c);
		}
		System.out.println(buffer.toString());

		reader.close();

	} catch (Exception e) {
	}
}

输出结果

结果代码:200
[
    {
        "IdNumber": "123", 
        "Name": "鲁迅认识的那只猹", 
        "Gender": "男", 
        "Address": "来自星星"
    }, 
    {
        "IdNumber": "124", 
        "Name": "路人甲", 
        "Gender": "男", 
        "Address": "Earth"
    }, 
    {
        "IdNumber": "125", 
        "Name": "吃瓜群众", 
        "Gender": "男", 
        "Address": "Sky"
    }
]
POST 请求

GET 请求直接通过URL传递参数即可参数,POST 需要将参数放到请求体中。

C#代码

/// <summary>
/// 添加一个Person
/// </summary>
static void PostPerson()
{
    //我们要传递一个Person对象,格式直接是  属性=值&属性=值....
    string person = "IdNumber=126&Name=Test&Gender=男&Address=Test";
    byte[] buffer = Encoding.UTF8.GetBytes(person);

    HttpWebRequest webRequest = WebRequest.Create("http://localhost:60544/API/Person") as HttpWebRequest;

    //设置传递的参数格式为 名称/值对 的标准格式
    webRequest.ContentType = "application/x-www-form-urlencoded";

    webRequest.Method = "POST";

    webRequest.AllowWriteStreamBuffering = true;

    //写入数据
    Stream requestStream = webRequest.GetRequestStream();
    requestStream.Write(buffer, 0, buffer.Length);
    requestStream.Close();
    requestStream.Flush();

    //直到 执行GeTResponse() 时候才进行发送请求
    HttpWebResponse response = webRequest.GetResponse() as HttpWebResponse;
    //获取结果代码
    HttpStatusCode code = response.StatusCode;
    Console.WriteLine((int)code+" "+code.ToString());
}

输出结果 这是我们再次运行 GetPerson() 方法会有以下结果

[
    {
        "IdNumber": "123", 
        "Name": "鲁迅认识的那只猹", 
        "Gender": "男", 
        "Address": "来自星星"
    }, 
    {
        "IdNumber": "124", 
        "Name": "路人甲", 
        "Gender": "男", 
        "Address": "Earth"
    }, 
    {
        "IdNumber": "125", 
        "Name": "吃瓜群众", 
        "Gender": "男", 
        "Address": "Sky"
    }, 
  	//这是我们新添加的记录
    {
        "IdNumber": "126", 
        "Name": "Test", 
        "Gender": "男", 
        "Address": "Test"
    }
]

Java代码

public static void postPerson() {
	try {
		String person = "IdNumber=126&Name=Test&Gender=男&Address=Test";

		URL url = new URL("http://localhost:60544/API/Person");
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		// 设置请求方法
		conn.setRequestMethod("POST");
		
		//POST 必须有下面的代码
		conn.setDoOutput(true);
		
		//写入数据
		OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), "utf-8");
		writer.write(person);
		writer.flush();
		writer.close();
		
		// 获取结果码
		int code = conn.getResponseCode();
		System.out.println("结果代码:" + code);

	} catch (Exception e) {
		e.printStackTrace();
	}
}

源码下载

剩下的PUT DELETE 请求基本类似这里就不在贴出,如要查看请下载源码

NOTE: Java中的PUT请求不知为何一直无法请求成功 415 错误码

除非特殊声明否则,本博客文章均属 鲁迅认识的那只猹 原创,未经许可禁止转载,否则将保留追究法律责任的权利。

如果本博客损害了您的相关权益,请及时联系我,我将妥善处理。 Email: wangyidong_cn@outlook.com