我心中的核心组件~HttpHandler和HttpModule实现图像的缩放与Url的重写

说在前

对于资源列表页来说,我们经常会把图像做成N多种,大图,小图,中图等等,很是麻烦,在数据迁移时,更是一种痛快,而如果你把图像资源部署到nginx上,那么这种图像缩放就变得很容易了,因为它有自己的过滤器来实现这个功能,只要程序员简单的配置即可(GraphicsMagick),其实在nginx上实现缩略图的方式有很多,而对于IIS服务来说,实现这种缩略图就没有直接的方法了,必须开发人员自己写代码来实现,下面解释两个比较早的技术(被执行的期间比较早,在页面渲染之前)HttpModule和httpHandler,这两个东西我在之前的文章中也已经讲过,细节不再重复。[HttpModule几大事件,HttpHandler实现图像防盗链]

做在后

一 HttpModule对URL地址进行重写,将扩展名为jpg,jpeg,png,gif结尾的URL地址进行复写,让它支持漂亮的缩略图参数,如原地址为:new1.jpg,实现缩略图原地址为:new1.jpg?w=100&h=100,进行Url重写后的漂亮地址为:new1_100x100.jpg,怎么样,是否是很漂亮,有点像MVC 的router吧,呵呵

    /// <summary>
    /// 实现URL的重写
    /// </summary>
    public class UrlRewriteModule : IHttpModule
    {
        #region IHttpModule 成员

        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(Application_BeginRequest);
        }
        /// <summary>
        /// url重写
        /// .png?w=100&h=100
        /// _100x100.png
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Application_BeginRequest(Object sender, EventArgs e)
        {
            string oldUrl = HttpContext.Current.Request.RawUrl;
            if (oldUrl.LastIndexOf(".") > -1)
            {
                string ext = oldUrl.Substring(oldUrl.LastIndexOf(".")).ToLower();
                //是图像文件
                if (ext == ".jpg"
                    ||
                    ext == ".jpeg"
                    ||
                    ext == ".png"
                    ||
                    ext == "gif")
                {
                    var param = oldUrl.Substring(oldUrl.LastIndexOf("_") + 1, (oldUrl.IndexOf(".") - oldUrl.LastIndexOf("_") - 1)).Split(new char[] { 'x' }, StringSplitOptions.RemoveEmptyEntries);
                    //有图像缩放请求
                    if (oldUrl.LastIndexOf("_") > -1)
                    {
                        string newUrl = oldUrl.Substring(0, oldUrl.LastIndexOf("_"));
                        newUrl = string.Format(newUrl + ext + "?w={0}&h={1}", param[0], param[1]);
                        //将请求中的URL进行重写
                        HttpContext.Current.RewritePath(newUrl);
                    }
                }
            }

        }

        #endregion

        #region IHttpModule 成员

        public void Dispose()
        {
        }

        #endregion
    }

二 使用HttpHandler进行对图像的缩放,你的服务器是指与图像资源在一起的那台电脑

    /// <summary>
    /// 图片动态缩放处理程序
    /// </summary>
    public class ImageScalingHandler : IHttpHandler
    {
        /// <summary>
        /// 图像等比例缩放,图像默认为白色
        /// </summary>
        /// <param name="image"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        private Bitmap CreateThumbnail(Image image, int width, int height)
        {
            Point point = new Point(0, 0); //图像从那个坐标点进行截取
            double wRate = 1, hRate = 1, setRate = 1;
            int newWidth = 0, newHeight = 0;
            try
            {
                if (width == 0) width = image.Width;
                if (height == 0) height = image.Height;

                if (image.Height > height)
                {
                    hRate = (double)height / image.Height;
                }

                if (image.Width > width)
                {
                    wRate = (double)width / image.Width;
                }

                if (wRate != 1 || hRate != 1)
                {
                    if (wRate > hRate)
                    {
                        setRate = hRate;
                    }
                    else
                    {
                        setRate = wRate;
                    }
                }

                newWidth = (int)(image.Width * setRate);
                newHeight = (int)(image.Height * setRate);
                if (height > newHeight)
                {
                    point.Y = Convert.ToInt32(height / 2 - newHeight / 2);
                }
                if (width > newWidth)
                {
                    point.X = Convert.ToInt32(width / 2 - newWidth / 2);
                }

                Bitmap bit = new Bitmap(width, height);
                Rectangle r = new Rectangle(point.X, point.Y, (int)(image.Width * setRate), (int)(image.Height * setRate));
                Graphics g = Graphics.FromImage(bit);
                g.Clear(Color.White);
                g.DrawImage(image, r);
                g.Dispose();
                return bit;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 处理请求
        /// </summary>
        /// <param name="context"></param>
        public void ProcessRequest(HttpContext context)
        {
            int w = 0, h = 0;
            int.TryParse(context.Request.QueryString["w"], out w);
            int.TryParse(context.Request.QueryString["h"], out h);
            Image image = Image.FromFile(context.Request.PhysicalPath);
            context.Response.ContentType = "image/jpeg";
            Bitmap bitMap = CreateThumbnail(image, w, h);
            bitMap.Save(context.Response.OutputStream, ImageFormat.Jpeg);
            image.Dispose();
            bitMap.Dispose();
            context.Response.End();
        }

        public bool IsReusable
        {
            get { return false; }
        }
    }

三 最后就是在Module和Handler的入口配置的,即如何将它们加入到当然网站中,我们采用web.config配置的方法

 <system.web>
    <httpModules>
      <!-- this is for Classic mode and Cassini -->
      <add name="UrlRewriteModule" type="EntityFrameworks.Web.Core.HttpModules.UrlRewriteModule,EntityFrameworks.Web.Core" />
    </httpModules>
  </system.web>
<system.webServer>

    <modules runAllManagedModulesForAllRequests="true" >
      <!--This is for Integrated mode-->
      <add name="UrlRewriteModule" type="EntityFrameworks.Web.Core.HttpModules.UrlRewriteModule,EntityFrameworks.Web.Core" />
    </modules>

    <handlers>
      <add name="ImageFunction1" path="*.jpg" verb="GET" type="EntityFrameworks.Web.Core.HttpHandlers.ImageScalingHandler,EntityFrameworks.Web.Core"  />
      <add name="ImageFunction2" path="*.png" verb="GET" type="EntityFrameworks.Web.Core.HttpHandlers.ImageScalingHandler,EntityFrameworks.Web.Core"  />
      <add name="ImageFunction3" path="*.gif" verb="GET" type="EntityFrameworks.Web.Core.HttpHandlers.ImageScalingHandler,EntityFrameworks.Web.Core"  />
      <add name="ImageFunction4" path="*.jpeg" verb="GET" type="EntityFrameworks.Web.Core.HttpHandlers.ImageScalingHandler,EntityFrameworks.Web.Core"  />
</handlers>

从上面的代码中,我们可以看到,对于modules来说,那有两种方式注入,一为IIS经典模式下的,另一种是IIS集成模式下的,我们需要分别进行配置。

可以看一下效果,成功的喜悦!

大叔框架集又一成功组件...

本文转自博客园张占岭(仓储大叔)的博客,原文链接:我心中的核心组件~HttpHandler和HttpModule实现图像的缩放与Url的重写,如需转载请自行联系原博主。

时间: 2024-11-02 01:21:25

我心中的核心组件~HttpHandler和HttpModule实现图像的缩放与Url的重写的相关文章

我心中的核心组件(可插拔的AOP)~大话开篇及目录

核心组件 我心中的核心组件,核心组件就是我认为在项目中比较常用的功能,如日志,异常处理,消息,邮件,队列服务,调度,缓存,持久化,分布式文件存储,NoSQL存储,IoC容器,方法拦截等等. 对于以上内容可以说即是一个大餐,又是一个挑战,就让我带着大家去迎接这份挑战吧,呵呵! 可插拔的AOP AOP即面向切面的编程,是指将一个公用的与领域无关的组件抽象出来,方便在各个项目中使用.在微软很多项目中,基本都会有这种组件,它们叫它frameworks,或者叫core,从字面上看,就是核心的东西,而这些核

关于HttpHandler与HttpModule的理解和应用方法_实用技巧

神秘的HttpHandler与HttpModule        大学时候我是从拖控件开始学习asp.net的,对.net的很多类库对象都不是很了解.所以看到大家写一些个性的asp.net名词,就感觉asp.net总有一层神秘的面纱笼罩着,让我琢磨不透,相信园子里面也有很多和我经历差不多的.net攻城师.在以前看HttpHandler与HttpModule都是神秘莫测的.哈哈,今天我为大家展示下我对他的理解,以及应用.       也许你不懂HttpHandler与HttpModule(大侠Re

HttpHandler与HttpModule的用处与区别

HttpHandler与HttpModule的用处与区别 问题1:什么是HttpHandler? 问题2:什么是HttpModule? 问题3:什么时候应该使用HttpHandler什么时候使用HttpModule? 答案1:HttpHandler,Http请求的处理者,例如ScriptHandler.WebServiceHandler,IHttpHandler的实现都是为了处理某一类的请求.如ScriptHandler负责处理对脚本的请求. 答案2:HttpModule,Http模块.实际上就

Asp.NET中 HttpHandler、HttpModule深入分析

在我们 .NET web.config 的配置文件中经常会看到HttpHandler与HttpModule这两个词,那么你真正理解这两个词吗?下面就给大家讲解一下HttpHandler.HttpModule的作用和应用. 什么是IHttpHandler? IHttpHandler定义了实现HTTP请求的一些基本约定,简单理解就是配置一个HttpHandler就实现了一个URL请求.如果一个IHttpHandler定义了其实现类,那么就相当于是覆盖关系. IHttpHandler的使用方法 Htt

httphandler和httpmodule的区别

ASP.Net处理Http Request时,使用Pipeline(管道)方式,由各个HttpModule对请求进行处理,然后到达 HttpHandler,HttpHandler处理完之后,仍经过Pipeline中各个HttpModule的处理,最后将HTML发送到客户端浏览 器中. 生命周期中涉及到几个非常重要的对象:HttpHandler,HttpModule,IHttpHandlerFactory,他们的执行(顺序)大致的执行过程是这样的:client端发送页面请求,被IIS的某个进程截获

我心中的核心组件(可插拔的AOP)~第三回 日志记录组件之log4net

在项目中有统一的日志是很必要的,之前自己写过vlog项目,这个项目与现在比较流行的log4net很像,用起来也很方便,今天主要说一下log4net这个日志工具,这使用vs2012测试的,使用nuget把log4net组件添加到项目中,如图: 然后在项目里为log4net建立一个配置文件,可以命名为log4net.config,一般代码如下: <log4net> <logger name="loginfo"> <level value="INFO&

我心中的核心组件(可插拔的AOP)~第一回 日志记录组件之自主的Vlog

对于.net环境而言,日志的开源组件有很多,像Nlog,log4net等等,而我今天要介绍的是我的日志组件VLog,呵呵,事实上实现原理与作用都大同小异. 作用:记录程序运行中的相关信息 特点:提供了消息日志,错误日志,调试日志,警告日志,崩溃日志等等 优势:提供了多种日志实现的方式,如SQL数据库,XML文本,WIN日志等等 配置:它可以通过配置文件进行设置,提供了日志级别和记录方式等参数 说明:VLog项目层次分明,一个接口,一个基类,5个实现的功能类,一切都是那么自然,下面看一下结构图:

我心中的核心组件(可插拔的AOP)~调度组件quartz.net

quartz.net是一个任务调度组件,它可以灵活的设置你的调试方式,按时间,按日期,按周期都可以很容易的实现,quartz不仅可以用在web中,而且还可以部署在winform,winservice上,下面我们就来作一个简单的调试服务,我们以WEB环境为例,WEB端采用比较流行的MVC3实现. 首先需要引入三个组件DLL C5.DLL,log4net.DLL,Quartz.DLL,Common.Logging 对于WEB项目来说,调度的注入后我们可以放在global.asax里,它可以使我们的调

我心中的核心组件(可插拔的AOP)~第四回 异常拦截器

之前说过有关拦截器的文章,第二回  缓存拦截器,事实上,在那讲里说的最多是AOP和缓存组件,对于拦截的概念并没有详细的说明,这一讲,不说AOP,主要说一下拦截器,拦截器Interception,主要是在方法执行前或者执行后,动态添加一些行为,而这个行为主要包含缓存,日志,异常处理及你可以想到的所有的一切,呵呵. 这一讲是异常拦截器,它的主要意义在于,当你的一个方法被执行时,你可以通过配置文件去管理这个方法执行前与执行后是否附加统一异常处理行为. 拦截器组件我们还是用Unity.Intercept