JSP:使用 'out'(jspWriter)的委托和 jsp 包含更改表达式的行为
JSP: Using a delegate for 'out' ( jspWriter) with jsp includes to change the behaviour of Expressions
说,有一个 class 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
对象... :-(
我们如何在不添加
的情况下为所有包含的 jsp 带来相同的行为
<% 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 ....
如果您查看生成的 jsp class 的顶部,您将看到以下行
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 class
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);
我还没试过。但从概念上讲,它应该有效。如果您可以通过此实现您想要的,请告诉我们。
祝你好运!
说,有一个 class 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
对象... :-(
我们如何在不添加
的情况下为所有包含的 jsp 带来相同的行为<% 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 ....
如果您查看生成的 jsp class 的顶部,您将看到以下行
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 class
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);
我还没试过。但从概念上讲,它应该有效。如果您可以通过此实现您想要的,请告诉我们。
祝你好运!