【问题标题】:JSP: Using a delegate for 'out' ( jspWriter) with jsp includes to change the behaviour of ExpressionsJSP:使用带有 jsp 的“out”( jspWriter) 的委托来更改表达式的行为
【发布时间】:2015-04-08 07:14:48
【问题描述】:

比如说,有一个类 MyJSPWriter 扩展了 JspWriter 并实现了所有抽象方法。并且 print(String ) 被修改以添加一些特殊行为,因此所有字符串表达式都会被区别对待(也许我可以将它用于一些特殊的编码或类似的东西——这是一个简化的例子):

package com.myproject.base;

import java.io.IOException;
import javax.servlet.jsp.JspWriter;

public class MyJSPWriter extends JspWriter{

    JspWriter out = null;

    public MyJSPWriter(JspWriter out) {
        super(0, true);
        this.out = out;
    }


    @Override
    public String toString() {
        return out.toString();
    }

    @Override
    public void clear() throws IOException {
        out.clear();
    }

    @Override
    public void clearBuffer() throws IOException {
        out.clearBuffer();
    }

    @Override
    public void close() throws IOException {
        out.close();
    }

    @Override
    public void flush() throws IOException {
        out.flush();
    }

    @Override
    public int getRemaining() {
        return out.getRemaining();
    }

    @Override
    public void newLine() throws IOException {
        out.newLine();
    }

    @Override
    public void print(boolean b) throws IOException {
        out.print(b);
    }

    @Override
    public void print(char c) throws IOException {
        out.print(c);
    }

    @Override
    public void print(int i) throws IOException {
        out.print(i);
    }

    @Override
    public void print(long l) throws IOException {
        out.print(l);
    }

    @Override
    public void print(float f) throws IOException {
        out.print(f);
    }

    @Override
    public void print(double d) throws IOException {
        out.print(d);
    }

    @Override
    public void print(char[] s) throws IOException {
        out.print(s);
    }

    @Override
    public void print(String s) throws IOException {
        out.print("Processed String: " + s);
    }

    @Override
    public void print(Object obj) throws IOException {
        out.print(obj);
    }

    @Override
    public void println() throws IOException {
        out.println();
    }

    @Override
    public void println(boolean x) throws IOException {
        out.println(x);
    }

    @Override
    public void println(char x) throws IOException {
        out.println(x);
    }

    @Override
    public void println(int x) throws IOException {
        out.println(x);
    }

    @Override
    public void println(long x) throws IOException {
        out.println(x);
    }

    @Override
    public void println(float x) throws IOException {
        out.println(x);
    }

    @Override
    public void println(double x) throws IOException {
        out.println(x);
    }

    @Override
    public void println(char[] x) throws IOException {
           out.println(x);
    }

    @Override
    public void println(String x) throws IOException {
           out.println(x);
    }

    @Override
    public void println(Object x) throws IOException {
           out.println(x);
    }

    @Override
    public void write(char[] cbuf, int off, int len) throws IOException {
        out.write(cbuf, off, len);
    }


}

我有 jsp(比如Main.jsp),它看起来像这样:

<%@page import="com.myproject.base"%>
<% out = new MyJSPWriter(out); %>

<%= " Hello World" %>

所以,在我的输出中,它看起来像

Processed String: Hello World

现在,如果我有更多的 jsp:includes,并且可能在其中的每一个中包含更多.. 例如:

Main.jsp

<%@page import="com.myproject.base"%>
<% out = new MyJSPWriter(out); %>

<%= " Hello World" %>
<jsp:include page="Sub1.jsp"></jsp:include>
<jsp:include page="Sub2.jsp"></jsp:include>

Sub1.jsp

<%= " Hello World from sub1.jsp" %>

Sub2.jsp

<%= " Hello World from sub2.jsp" %>
<jsp:include page="Sub3.jsp"></jsp:include>

等等……

但是所有子 jsp 都会有自己的 out 对象... :-(

我们如何在不添加的情况下为所有包含的 jsps 带来相同的行为

<% out = new MyJSPWriter(out); %>

在每个文件中(因为我试图在旧版应用程序中使用它)?

我还有其他方法可以解决这个问题吗?

其他信息: 当我们查看生成的jsp的.java文件时, 这就是部分代码的样子

public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws java.io.IOException, ServletException {

    PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;
    PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html");
      pageContext = _jspxFactory.getPageContext(this, request, response,
                null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;
      out = new MyJSPWriter(out);
      // and so on writing content ....

【问题讨论】:

    标签: java jsp servlets


    【解决方案1】:

    如果你查看生成的jsp类的顶部,你会看到下面一行

     private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();
    

    现在,自定义out 对象的一种可能解决方案是自定义JspFactory 实现。

    步骤

    创建自定义 JspFactory 实现

    public class MyJspFactory extends JspFactory {
        private static JspFactory _myFactory = null;
        public MyJspFactory(JspFactory factory) {
            _myFactory = factory;
        } 
       //All abstract methods which looks up _myFactory and does the same thing
    
       public PageContext getPageContext(Servlet servlet, ServletRequest request, ServletResponse response, String errorPageURL, boolean needsSession, int bufferSize, boolean autoflush) {
            PageContext myCtxt = _myFactory.getPageContext(....)
            //Create a customPageContext and wrap myCtxt in it and return
       }
    }
    

    创建一个 CutsomPageContext 类

    public class MyPageContext extends PageContext {
        private PageContext _ctxt = null;
    
        public void setPageContext(PageContext ctxt) {
            _ctxt = ctxt;
        }
    
        //Implement all abstract methods using _ctxt object
    
        @override
        public  JspWriter getOut() {
            JspWriter _out = _ctxt.getOut();
    
            //Wrap _out object using MyJSPWriter as mentioned in question and return back;
    
        }
    }
    

    现在在 servlet 的初始化过程中,添加以下行

    JspFactory newFactory = new MyJspFactory(JspFactory.getDefaultFactory());
    JspFactory.setDefaultFactory(newFactory);   
    

    我还没试过。但从概念上讲,它应该有效。请让我们知道您是否可以通过此实现您想要的。

    祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-18
      相关资源
      最近更新 更多