【转】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里的配置 ...
随机推荐
- Java 集合 线程安全
Java中常用的集合框架中的实现类HashSet.TreeSet.ArrayList.ArrayDeque.LinkedList.HashMap.TreeMap都是线程不安全的,如果多个线程同时访问它 ...
- unity3d之Editor的Assembly-CSharp.dll文件路径
在Editor中与自己project中使用的Mono与Managed文件夹路径区别: Editor中:在unity安装路径[AppDir]下: 自己project中:在project的路径下,由bui ...
- Spark wordcount开发并提交到集群运行
使用的ide是eclipse package com.luogankun.spark.base import org.apache.spark.SparkConf import org.apache. ...
- blktrace未公开选项网络保存截取数据
本文链接地址: blktrace未公开选项网络保存截取数据 我们透过blktrace来观察io行为的时候,第一件事情需要选择目标设备,以便分析该设备的io行为.具体使用可以参考我之前写的几篇:这里 这 ...
- Hash的一点测试
哈希表的学习与测试 以前写的hash都是碰运气的hash,就是乘上质数取模的那种,这样不能保证不碰撞,所以今天先写上几个双hush和链表的hash,并比较一下他们的速度,测试的话用洛谷上的“字符串哈希 ...
- [Dart] Flutter 上传文件
/** * 请求响应数据 */ class MsgResponse { int code; // 状态代码,0 表示没有错误 Object data; // 数据内容,一般为字符串 String er ...
- UVA-10115
字符查找替换,WA了N次,一次只能替换一个,下一次find必须从第0个位置开始 import java.io.File; import java.io.FileNotFoundException; i ...
- php中点击链接直接下载图片
最近需要一个功能,是点击链接,直接把图片下载下来,一般情况下,图片是在新页直接打开的,不会自动提示下载,在网上找来找,用这个挺好使,代码如下: $filename = basename($downfi ...
- leetcode210
public class Solution { //test case [1,0] public int[] findOrder(int numCourses, int[][] prerequisit ...
- 24.OGNL与ValueStack(VS)-集合对象初步
转自:https://wenku.baidu.com/view/84fa86ae360cba1aa911da02.html 首先在LoginAction中增加如下字段并提供相应的get/set方法: ...