Servlet学习——分析一牛同事的代码

原创 2007年10月10日 09:48:00
 
业务需求:一管理系统,系统架构是struts+sping+hibernate,客户在页面上点击一按钮,触发一个发送E-mail的操作。Email的内容是html的格式,内容不是死的,但有一个模板。
 
解决思路:
其一,读入这个模板的html源代码,把需要动态显示的部分分别用特殊的代码做标记,然后在后台把这些特殊的标记用该显示的内容替换。这样做的缺点,如果动态显示的内容较多,需要做多个特殊标记,引起代码混乱,也不便于以后的维护。
其二,把这个模板作为一个jsp页面,发送email的时候,先生成这个jsp页面,当然这个页面不在前台显示,然后把这个jsp页面转换为html文件。然后在读取这个html文件作为email的内容发送。这样做方法一的所有缺点都不存在了。但是如何把一个jsp在后台转换为一个html文件,是一个难点。一较猛同事给出了如下方法,我在这事后诸葛亮,给大家做个分析,共同学习。
    /** *//**
     * 
@param jspFile jsp文件路径
     * 
@param htmlFile 要输出的html文件的路径
     * @add  2007/08/30
     
*/

     
public  void convertJspToHtml(HttpServletRequest request,
                HttpServletResponse response, String jspFile, String htmlFile)
                
throws ServletException, IOException ...{

            String url 
= jspFile;
            String name 
= htmlFile;
            ServletContext servletContext 
= request.getSession()
                    .getServletContext();
            //生成一个特定于jsp的RequestDispatcher对象,以用来对jsp传送请求信息.

            RequestDispatcher requestDispatcher 
= servletContext
                    .getRequestDispatcher(url);
            
/**//*new这个ByteArrayOutputStream的作用在于它有一个writeTo(OutputStream out)方法.
               用于将此字节数组输出流的全部内容写入到指定的输出流参数中.
*/

            
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            
            
//实现了servlet.ServletOutputStream抽象类的write方法,用于把响应信息写入到刚new的byteArrayOutputStream中.
            /**//*只是不知道为什么要实现这两个write方法*/
            
final ServletOutputStream servletOutputStream = new ServletOutputStream() ...{
                
public void write(byte[] data, int offset, int length) ...{
                    byteArrayOutputStream.write(data, offset, length);
                }


                
public void write(int b) throws IOException ...{
                    byteArrayOutputStream.write(b);
                }

            }
;
            
            
//new一个PrintWriter,连接到刚new的byteArrayOutputStream中
            final PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(
                    byteArrayOutputStream));
            
            
//重写了servlet.HttpServletResponseWrapper类的两个方法
            HttpServletResponse res = new HttpServletResponseWrapper(response) ...{
                
//此方法返回ServletOutputStream对象,它是java.io.OutputStream的一个子类。此对象向客户发送二进制数据。
                public ServletOutputStream getOutputStream() ...{
                    
return servletOutputStream;
                }

                
//此方法将返回PrintWriter对象,把servlet的结果作为文本返回给调用者。
                
//PrintWriter对象自动把Java内部的UniCode编码字符转换成正确的编码以使客户端能够阅读。
                public PrintWriter getWriter() ...{
                    
return printWriter;
                }

            }
;
            requestDispatcher.include(request, res);
            printWriter.flush();
            FileOutputStream fos 
= new FileOutputStream(name); // 把jsp输出的内容写到xxx.htm
            byteArrayOutputStream.writeTo(fos);
            fos.close();
        }

 

 

/*在这学习一下RequestDispatcher,它有两个方法,forward(ServletRequest request, ServletResponse response)
             和include(ServletRequest request, ServletResponse response),都是用与servlet之间的通讯.
            .forward()方法:
            被用来从这个Servlet向其它服务器资源传递请求。
            当一个Servlet对响应作了初步的处理,并要求其它的对象对此作出响应时,可以使用这个方法。
           
            request对象被传递到目标对象时,请求的URL路径和其他路径参数会被调整为反映目标对象的目标URL路径。
           
            如果已经通过响应返回了一个ServletOutputStream对象或PrintWriter对象,这个方法将不能使用,
            否则,这个方法会抛出一个IllegalStateException
           
            我的理解:用于一个servlet向目标servlet的单向通讯.
           
            2.include()方法:
            用来包括发送给其他服务器资源的响应的内容。本质上来说,这个方法反映了服务器端的内容。
           
            请求对象传到目标对象后会反映调用请求的请求URL路径和路径信息。
             这个响应对象只能调用这个ServletServletOutputStream对象和PrintWriter对象。
           
             一个调用includeServlet不能设置头域,如果这个Servlet调用了必须设置头域的方法(例如cookie),
             这个方法将不能保证正常使用。作为一个Servlet开发者,你必须妥善地解决那些可能直接存储头域的方法。
             例如,即使你使用会话跟踪,为了保证session的正常工作,你必须在一个调用includeServlet之外开始你的session
            
             我的理解:用于两个servlet之间的双向通讯.
            */
 
 /*public abstract class ServletOutputStream extends OutputStream
            这是一个由Servlet引擎使用的抽象类。Servlet通过使用ServletResponse接口的使用获得了对一个这种类型的对象的说明。
            利用这个输出流可以将数据返回到客户端。
           
            这个类的子类必须提供一个向OutputStream接口写入有关信息的方法。
            在这个接口中,当一个刷新或关闭的方法被调用时。所有数据缓冲区的信息将会被发送到客户端,也就是说响应被提交了。
            请注意,关闭这种类型的对象时不一定要关闭隐含的socket流。*/
 
 
/*
             public PrintWriter(OutputStream out)
             根据现有的 OutputStream 创建不带自动行刷新的新 PrintWriter
             此便捷构造方法创建必要的中间 OutputStreamWriter,后者使用默认字符编码将字符转换为字节。
             */
/*public class ServletResponseWrapper
            extends java.lang.Object
            implements ServletResponse
           
            Provides a convenient implementation of the ServletResponse interface t
            hat can be subclassed by developers wishing to adapt the response from a Servlet.
            This class implements the Wrapper or Decorator pattern.
            Methods default to calling through to the wrapped response object.*/
 
我做了如下修改也可以
    public  void convertJspToHtml(HttpServletRequest request,
            HttpServletResponse response, String jspFile, String htmlFile)
            
throws ServletException, IOException ...{

        String url 
= jspFile;
        String name 
= htmlFile;
        ServletContext servletContext 
= request.getSession()
                .getServletContext();
        
//生成一个特定于jsp的RequestDispatcher对象,以用来对jsp传送请求信息.
        RequestDispatcher requestDispatcher = servletContext
                .getRequestDispatcher(url);
        
/**//*new这个ByteArrayOutputStream的作用在于它有一个writeTo(OutputStream out)方法.
           用于将此字节数组输出流的全部内容写入到指定的输出流参数中.
*/

        
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        
        
//实现了servlet.ServletOutputStream抽象类的write方法,用于把响应信息写入到刚new的byteArrayOutputStream中.
        final class ServletOutputStream ...{
            
public void write(byte[] data, int offset, int length) ...{
                byteArrayOutputStream.write(data, offset, length);
            }


            
public void write(int b) throws IOException ...{
                byteArrayOutputStream.write(b);
            }

        }
;
        
        
//new一个PrintWriter,连接到刚new的byteArrayOutputStream中
        final PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(
                byteArrayOutputStream));
        
        
//重写了servlet.HttpServletResponseWrapper类的两个方法
        HttpServletResponse res = new HttpServletResponseWrapper(response) ...{
            
//此方法返回ServletOutputStream对象,它是java.io.OutputStream的一个子类。此对象向客户发送二进制数据。
//            public ServletOutputStream getOutputStream() {
//
                return servletOutputStream;
//
            }
            
//此方法将返回PrintWriter对象,把servlet的结果作为文本返回给调用者。
            
//PrintWriter对象自动把Java内部的UniCode编码字符转换成正确的编码以使客户端能够阅读。
            public PrintWriter getWriter() ...{
                
return printWriter;
            }

        }
;
        requestDispatcher.include(request, res);
        printWriter.flush();
        FileOutputStream fos 
= new FileOutputStream(name); // 把jsp输出的内容写到xxx.htm
        byteArrayOutputStream.writeTo(fos);
        fos.close();
    }

Servlet基本结构的源码解析

如何写一个Servlet类?围绕这个问题,可以看一下Servlet的类结构。首先Servlet类也是一个Java...
  • yuhongye111
  • yuhongye111
  • 2014年08月30日 21:06
  • 3882

Latke源码解析(一)Servlet部分

最近研究java Web的MVC,发现一款轻量级的框架,官网描述为类似 Spring 但以 JSON 为主的 Java Web 框架。具体详情见latke github。由于此框架的mvc部分基于Se...
  • wthfeng
  • wthfeng
  • 2017年04月27日 11:49
  • 447

servlet代码分析-整个执行流程

对于Servlet的理解,对于我们更好的理解框架非常的有帮助的,所以!我之前看过的书,好多都忘记了,这个东西太多,一时间忘记了也是很正常的涩,所以我们必须多去深刻的理解整个过程,帮助我们更好的完成工作...
  • u012881904
  • u012881904
  • 2016年05月15日 10:28
  • 5297

新浪云+七牛云实现 Mysql + Servlet + Jsp 使用记录

前言笔者最近遇到的项目,后端是用 Java Servlet + Jsp + Mysql 实现的,后端中使用的图片托管在七牛云CDN,整个 Java Web 应用是托管在新浪云上的。这儿坐下项目记录,便...
  • never_cxb
  • never_cxb
  • 2016年01月24日 11:38
  • 1701

史上最牛的Java思维学习导图

我做过有道云笔记、印象笔记,也写过博客,几十篇文章之后,发现对笔记分类整理很麻烦,查询不容易,往往自己写的内容都不愿意看一眼,后来用了思维导图,很好用,结构清晰,一目了然,又灵机一动把导图做成chm格...
  • wojiushiwo577785
  • wojiushiwo577785
  • 2017年12月02日 15:28
  • 288

10个最“牛叉”的代码注释

你看到过的最好的代码注释是什么样的?看看这些够不够牛!
  • wdcxylg
  • wdcxylg
  • 2016年03月16日 23:31
  • 240

WordPress纯代码纯静态开启七牛CDN并集成七牛缩略图和水印功能

最近发现好多网站都使用了动静分离,我就研究了下使用七牛缓存图片,并使用七牛图片样式对图片进行缩略和加水印。 七牛步骤 先注册七牛帐号,并在账户里面充值10元钱,用于使用七牛的CDN功能,先...
  • liuxuekai
  • liuxuekai
  • 2016年08月03日 01:28
  • 1324

大数据相关技术

现今大数据发展十分火热,这里主要介绍一些大数据的相关基础内容,帮助读者了解大数据,为以后大家更加深入的学习大数据提供帮助。...
  • suchang1127
  • suchang1127
  • 2015年10月24日 00:54
  • 765

年薪200万数据库牛人牛新庄的成长历程

转自:http://blog.itpub.net/10640532/viewspace-566595 作者简介:       牛新庄博士,研究方向为数据仓库和数据挖掘。是IBM官方资深培训讲师(培...
  • DADADIE
  • DADADIE
  • 2015年04月09日 13:17
  • 1943

仿牛客UI Android版

只实现该app的部分功能和UI。特别声明一下【标题栏(ActionBar)部分牛客的标题可以向上滑动隐藏,可以使用安卓的suppost-V7实现,为节省时间直接在布局中写出来了,下拉刷新功能也没有实现...
  • u013271384
  • u013271384
  • 2016年01月26日 10:53
  • 483
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Servlet学习——分析一牛同事的代码
举报原因:
原因补充:

(最多只允许输入30个字)