【转】HttpHandler的认识与加深理解
原文:http://www.cnblogs.com/whtydn/archive/2009/10/19/1585778.html
HttpHandler是HTTP请求的处理中心,真正地对客户端请求的服务器页面做出编译和执行,并将处理过后的信息附加在HTTP请求信息流中再次返回到HttpModule中。HttpHandler与HttpModule不同,一旦定义了自己的HttpHandler类,那么它对系统的HttpHandler的关系将是“覆盖”关系. HttpHandler功能的实现通过实现IHttpHandler接口来达到.
当一个HTTP请求经同HttpModule容器传递到HttpHandler容器中时,ASP.NET Framework会调用HttpHandler的ProcessRequest成员方法来对这个HTTP请求进行真正的处理。以一个ASPX页面为例,正是在这里一个ASPX页面才被系统处理解析,并将处理完成的结果继续经由HttpModule传递下去,直至到达客户端。
对于ASPX页面,ASP.NET Framework在默认情况下是交给System.Web.UI.PageHandlerFactory这个HttpHandlerFactory来处理的。所谓一个HttpHandlerFactory,所谓一个HttpHandlerFactory,是指当一个HTTP请求到达这个HttpHandler Factory时,HttpHandlerFactory会提供出一个HttpHandler容器,交由这个HttpHandler容器来处理这个HTTP请求。
一个HTTP请求都是最终交给一个HttpHandler容器中的ProcessRequest方法来处理的。
IHttpHandler接口声明:
public interface IHttpHandler
{
bool IsReusable { get; }
public void ProcessRequest(HttpContext context); //请求处理函数
}
v2.0.50727 下的machine.config中httpHandlers结点是这样的:<httpHandlers />,并没有给出详细的处理程序,在Web.config中才能看到。
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" validate="false" type=""/>
<add verb="*" path="*_AppService.axd" validate="false" type=""/>
<add verb="GET,HEAD" path="ScriptResource.axd" type=""/>
<add verb="GET" path="CrystalImageHandler.aspx" type=""/>
</httpHandlers>
可以看到,在<httpHandlers>结点中将不同的文件类型映射给不同的Handler去处理. 上面的type部分为了好显示我去掉了,其实你打开web.config,可以看到里面的内容的.
Verb属性:指定了处理程序支持的HTTP动作。*-支持所有的HTTP动作;“GET”-支持Get操作;“POST”-支持Post操作;“GET, POST”-支持两种操作
Path属性:指定了需要调用处理程序的路径和文件名(可以包含通配符).“*”、“*.aspx”
Type属性:用名字空间、类名称和程序集名称的组合形式指定处理程序或处理程序工厂的实际类型. ASP.NET运行时首先搜索bin目录中的DLL,接着在GAC中搜索
IHttpHandler工厂
IHttpHandlerFactory的作用是对IHttpHandler进行管理。接口如下:
public interface IHttpHandlerFactory
{
IHttpHandler GetHandler (HttpContext context,string requestType,string url,string pathTranslated);
void ReleaseHandler (IHttpHandler handler);
}
GetHandler返回实现IHttpHandler接口的类的实例
ReleaseHandler使工厂可以重用现有的处理程序实例
HttpHandler的示例:
把硬盘上的图片以流的方式写在页面上
class TestHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
FileStream fs = new FileStream(context.Server.MapPath("test.jpg"), FileMode.Open);
byte[] b = new byte[fs.Length];
fs.Read(b, 0, (int)fs.Length);
fs.Close();
context.Response.OutputStream.Write(b, 0, b.Length);
} public bool IsReusable
{
get
{
return true;
}
}
}
Web.Config配置文件
<httpHandlers>
<add verb="*" path="*" type="ClassLibrary831.TestHandler,ClassLibrary831"></add>
</httpHandlers>
使用HttpHandler实现图片防盗链
namespace CustomHandler
{
public class JpgHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
// 获取文件服务器端物理路径
string FileName = context.Server.MapPath(context.Request.FilePath);
// 如果UrlReferrer为空,则显示一张默认的禁止盗链的图片
if (context.Request.UrlReferrer.Host == null)
{
context.Response.ContentType = "image/JPEG";
context.Response.WriteFile("/error.jpg");
}
else
{
// 如果 UrlReferrer中不包含自己站点主机域名,则显示一张默认的禁止盗链的图片
if (context.Request.UrlReferrer.Host.IndexOf("yourdomain.com") > 0)
{
context.Response.ContentType = "image/JPEG";
context.Response.WriteFile(FileName);
}
else
{
context.Response.ContentType = "image/JPEG";
context.Response.WriteFile("/error.jpg");
}
}
} public bool IsReusable{
get{ return true; }
}
}
}
编译后复制DLL文件到Bin文件夹下,然后在web.config注册
<httpHandlers>
<add path="*.jpg" verb="*" type="CustomHandler.JpgHandler, CustomHandler" />
</httpHandlers>
通过IhttpHandler实现图片验证码
ashx是什么文件呢? 其实该文件用于写web handler. 在web里面添加一个这样的文件,可以看到下列的代码:
<%@ WebHandler Language="C#" Class="Handler" %> using System;
using System.Web; public class Handler : IHttpHandler
{
public void ProcessRequest (HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.Write("Hello World");
}
public bool IsReusable {
get {
return false;
}
}
}
在上面的基础上修改我们需要的代码如下:
<%@ WebHandler Language="C#" Class="Handler" %> using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Web;
using System.Web.SessionState; public class Handler : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) {
context.Response.ContentType = "image/gif";
//建立Bitmap对象,绘图
Bitmap basemap = new Bitmap(200, 60);
Graphics graph = Graphics.FromImage(basemap);
graph.FillRectangle(new SolidBrush(Color.White), 0, 0, 200, 60);
Font font = new Font(FontFamily.GenericSerif, 48, FontStyle.Bold, GraphicsUnit.Pixel);
Random r = new Random();
string letters = "ABCDEFGHIJKLMNPQRSTUVWXYZ";
string letter;
StringBuilder s = new StringBuilder();
//添加随机的五个字母
for (int x = 0; x < 5; x++) {
letter = letters.Substring(r.Next(0, letters.Length - 1), 1);
s.Append(letter);
graph.DrawString(letter, font, new SolidBrush(Color.Black), x * 38, r.Next(0, 15));
}
//混淆背景
Pen linePen = new Pen(new SolidBrush(Color.Black), 2);
for (int x = 0; x < 6; x++)
graph.DrawLine(linePen, new Point(r.Next(0, 199), r.Next(0, 59)), new Point(r.Next(0, 199), r.Next(0, 59)));
//将图片保存到输出流中
basemap.Save(context.Response.OutputStream, ImageFormat.Gif);
context.Session["CheckCode"] = s.ToString(); //如果没有实现IRequiresSessionState,则这里会出错,也无法生成图片
context.Response.End();
} public bool IsReusable {
get { return true; }
}
}
最后的就是需要在页面上引用这个验证码了. 创建一个新的aspx页面.
<img src="Handler.ashx" alt="图片验证码" />
需要注意的就是我们继承了一个IRequiresSessionState接口:
public interface IRequiresSessionState{}
Handler类不仅需要实现 IHttpHandler接口,为了在这个Handler类中使用SessionState,还需要实现IRequiresSessionState接口,对于这个接口,MSDN的解释是这样的:Specifies that the target HTTP handler requires read and write access to session-state values. This is a marker interface and has no methods.(中文大概的意思:指定当前Http Handler需要对SessionState值的读写访问权。这是一个标记接口,没有任何方法)。这个接口没有任何需要实现的方法或属性,大家只要记得:如果想在HttpHandler中使用SessionState,必须实现这个接口,实际上也就是在类的标头将这个接口加进去。
收集整理与自己见解总结, 且当回忆, 下次再讨论一下HttpModule的理论与方法.
【转】HttpHandler的认识与加深理解的更多相关文章
- 一篇RPO漏洞挖掘文章翻译加深理解。
这是我第一次尝试翻译一篇漏洞挖掘文章,翻译它也是为了加深理解它.这是一篇很有意思的漏洞挖掘文章. 前几天在看fd的博客,偶然看到了这篇文章,虽然有点老了.但是思路真的牛皮.我决定花费时间和精力研究它们 ...
- 通过自己实现接口来加深理解SpringMVC的执行流程
功能介绍 上篇文章[从源码角度了解SpringMVC的执行流程]通过接口源码向大家介绍了SpringMVC的执行流程,主要偏重于源码.这篇文件我们来自己实现那几个关键接口,来真实体验下SpringMV ...
- 加深理解Java异常概念并熟记5个最常见的运行时异常
加深理解Java异常概念并熟记5个最常见的运行时异常 说明Error与Exception的联系和区别有哪些? 列举最常见的5个运用时异常. 1.Error和Exception的联系和区别: Error ...
- [ZigBee] 13、ZigBee基础阶段性回顾与加深理解——用定时器1产生PWM来控制LED亮度(七色灯)
引言:PWM对于很多软件工程师可能又熟悉又陌生,以PWM调节LED亮度为例,其本质是在每个周期都偷工减料一些,整体表现出LED欠压亮度不同的效果.像大家看到的七色彩灯其原理也类似,只是用3路PWM分别 ...
- Sql Server之旅——第六站 使用winHex利器加深理解数据页
这篇我来介绍一个winhex利器,这个工具网上有介绍,用途大着呢,可以用来玩数据修复,恢复删除文件等等....它能够将一个file解析成 hex形式,这样你就可以对hex进行修改,然后你就可以看到修复 ...
- typedef (还需经常看看加深理解)
看了 c++primer 1,typedef名字 typedef定义以关键字typedef开始,后面是 数据类型+标示符. 并未引入新的类型,只是现有数据类型的同义词 例: typedef doubl ...
- java是通过值传递,也就是通过拷贝传递——通过方法操作不同类型的变量加深理解(勿删)
head first java里写到“java是通过值传递的,也就是通过拷贝传递”,由此得出结论,方法无法改变调用方传入的参数.该怎么理解呢? 看例子: public class Test1 { pu ...
- 加深理解UIView,UIResponder,UIController
转载出处:http://www.th7.cn/Program/IOS/201503/406514.shtml 原文地址==>自定义控件:http://objccn.io/issue-3-4/ 读 ...
- 【转】HttpRuntime的认识与加深理解
原文:http://www.cnblogs.com/whtydn/archive/2009/10/16/1584418.html 下面最先介绍HttpRuntime的Web.config里的配置 ...
随机推荐
- STL容器能力一览表和各个容器操作函数异常保证
STL容器能力一览表 Vector Deque List Set Multiset map Multimap 典型内部 结构 dynamic array Array of arrays Doubly ...
- mvc和mtv
Java中MVC详解以及优缺点总结 概念: MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一 ...
- 小朋友学Java(1):Mac系统安装JDK
1 打开终端 方法可以参考http://blog.csdn.net/haishu_zheng/article/details/73410594 2 在终端输入 java -version,提示没有Ja ...
- MAN 手册各章节功能介绍及快捷键键位整理
前言 Man 手册页(Manua pages ,缩写man page) 是在linux操作系统在线软件文档的一种普遍形式.内容包括计算机程序库和系统调用等命令的帮助手册. 手册页是用troff排版 ...
- Linux 下的两种分层存储方案
背景介绍 随着固态存储技术 (SSD),SAS 技术的不断进步和普及,存储介质的种类更加多样,采用不同存储介质和接口的存储设备的性能出现了很大差异.SSD 相较于传统的机械硬盘,由于没有磁盘的机械转动 ...
- Solr学习总结(六)solr的函数查询Function Queries
摘要: 函数查询允许你使用一个或多个数字字段的真实值生成一个相关性分数,函数查询在standard,DisMax,eDisMax下都能使用. 查询函数可以是常量,字段或者其他函数的组合.使用函数可以影 ...
- 地址解析协议ARP(Address Resolution Protocol)
1.引言 说明: ARP的作用,解决了什么问题: 以太网中的链路层,可能会采用不同的网络技术,而且不以ip作为路由依据. 链路层以mac地址作为路由依据. ARP的功能是在32 bit的IP地址和采用 ...
- Nginx-ingress-controller部署
参考官网https://kubernetes.github.io/ingress-nginx/ 部署pod:nginx-ingress-controller/nginx-default-backend ...
- load data
LOAD DATA INFILE 'D:\GX\\mm.txt' REPLACE INTO TABLE mm FIELDS TERMINATED BY ' ' // 以空格为分隔符插入数据,前提是mm ...
- drop user和drop user cascade的区别
SQL> delete user itp2;delete user itp2 *第 1 行出现错误:ORA-00903: 表名无效 SQL> drop user itp2;dr ...