DebuggingInterceptorpublic class DebuggingInterceptor extends Object implements com.opensymphony.xwork2.interceptor.Interceptor
Provides several different debugging screens to provide insight into the
data behind the page.
The value of the 'debug' request parameter determines
the screen:
-
xml - Dumps the parameters, context, session, and value
stack as an XML document.
-
console - Shows a popup 'OGNL Console' that allows the
user to test OGNL expressions against the value stack. The XML data from
the 'xml' mode is inserted at the top of the page.
-
command - Tests an OGNL expression and returns the
string result. Only used by the OGNL console.
Example:
http://localhost:8080/Welcome.action?debug=xml
This interceptor only is activated when devMode is enabled in
struts.properties. The 'debug' parameter is removed from the parameter list
before the action is executed. All operations occur before the natural
Result has a chance to execute.
|
Fields Summary |
---|
private static final long | serialVersionUID | private static final Log | log | private String[] | ignorePrefixes | private String[] | _ignoreKeys | private HashSet | ignoreKeys | private static final String | XML_MODE | private static final String | CONSOLE_MODE | private static final String | COMMAND_MODE | private static final String | SESSION_KEY | private static final String | DEBUG_PARAM | private static final String | EXPRESSION_PARAM | private boolean | enableXmlWithConsole | private boolean | devMode | private org.apache.struts2.views.freemarker.FreemarkerManager | freemarkerManager | private boolean | consoleEnabled |
Methods Summary |
---|
public void | destroy()Unused.
| private java.lang.String | getParameter(java.lang.String key)Gets a single string from the request parameters
String[] arr = (String[]) ActionContext.getContext().getParameters().get(key);
if (arr != null && arr.length > 0) {
return arr[0];
}
return null;
| public void | init()Unused.
| public java.lang.String | intercept(com.opensymphony.xwork2.ActionInvocation inv)
boolean cont = true;
if (devMode) {
final ActionContext ctx = ActionContext.getContext();
String type = getParameter(DEBUG_PARAM);
ctx.getParameters().remove(DEBUG_PARAM);
if (XML_MODE.equals(type)) {
inv.addPreResultListener(
new PreResultListener() {
public void beforeResult(ActionInvocation inv, String result) {
printContext();
}
});
} else if (CONSOLE_MODE.equals(type)) {
consoleEnabled = true;
inv.addPreResultListener(
new PreResultListener() {
public void beforeResult(ActionInvocation inv, String actionResult) {
String xml = "";
if (enableXmlWithConsole) {
StringWriter writer = new StringWriter();
printContext(new PrettyPrintWriter(writer));
xml = writer.toString();
xml = xml.replaceAll("&", "&");
xml = xml.replaceAll(">", ">");
xml = xml.replaceAll("<", "<");
}
ActionContext.getContext().put("debugXML", xml);
FreemarkerResult result = new FreemarkerResult();
result.setFreemarkerManager(freemarkerManager);
result.setContentType("text/html");
result.setLocation("/org/apache/struts2/interceptor/debugging/console.ftl");
result.setParse(false);
try {
result.execute(inv);
} catch (Exception ex) {
log.error("Unable to create debugging console", ex);
}
}
});
} else if (COMMAND_MODE.equals(type)) {
ValueStack stack = (ValueStack) ctx.getSession().get(SESSION_KEY);
String cmd = getParameter(EXPRESSION_PARAM);
ServletActionContext.getRequest().setAttribute("decorator", "none");
HttpServletResponse res = ServletActionContext.getResponse();
res.setContentType("text/plain");
try {
PrintWriter writer =
ServletActionContext.getResponse().getWriter();
writer.print(stack.findValue(cmd));
writer.close();
} catch (IOException ex) {
ex.printStackTrace();
}
cont = false;
}
}
if (cont) {
try {
return inv.invoke();
} finally {
if (devMode && consoleEnabled) {
final ActionContext ctx = ActionContext.getContext();
ctx.getSession().put(SESSION_KEY, ctx.get(ActionContext.VALUE_STACK));
}
}
} else {
return null;
}
| protected void | printContext()Prints the current context to the response in XML format.
HttpServletResponse res = ServletActionContext.getResponse();
res.setContentType("text/xml");
try {
PrettyPrintWriter writer = new PrettyPrintWriter(
ServletActionContext.getResponse().getWriter());
printContext(writer);
writer.close();
} catch (IOException ex) {
ex.printStackTrace();
}
| protected void | printContext(PrettyPrintWriter writer)Prints the current request to the existing writer.
ActionContext ctx = ActionContext.getContext();
writer.startNode(DEBUG_PARAM);
serializeIt(ctx.getParameters(), "parameters", writer,
new ArrayList<Object>());
writer.startNode("context");
String key;
Map ctxMap = ctx.getContextMap();
for (Object o : ctxMap.keySet()) {
key = o.toString();
boolean print = !ignoreKeys.contains(key);
for (String ignorePrefixe : ignorePrefixes) {
if (key.startsWith(ignorePrefixe)) {
print = false;
break;
}
}
if (print) {
serializeIt(ctxMap.get(key), key, writer, new ArrayList<Object>());
}
}
writer.endNode();
serializeIt(ctx.getSession(), "request", writer, new ArrayList<Object>());
serializeIt(ctx.getSession(), "session", writer, new ArrayList<Object>());
ValueStack stack = (ValueStack) ctx.get(ActionContext.VALUE_STACK);
serializeIt(stack.getRoot(), "valueStack", writer, new ArrayList<Object>());
writer.endNode();
| protected void | serializeIt(java.lang.Object bean, java.lang.String name, PrettyPrintWriter writer, java.util.List stack)Recursive function to serialize objects to XML. Currently it will
serialize Collections, maps, Arrays, and JavaBeans. It maintains a stack
of objects serialized already in the current functioncall. This is used
to avoid looping (stack overflow) of circular linked objects. Struts and
XWork objects are ignored.
writer.flush();
// Check stack for this object
if ((bean != null) && (stack.contains(bean))) {
if (log.isInfoEnabled()) {
log.info("Circular reference detected, not serializing object: "
+ name);
}
return;
} else if (bean != null) {
// Push object onto stack.
// Don't push null objects ( handled below)
stack.add(bean);
}
if (bean == null) {
return;
}
String clsName = bean.getClass().getName();
writer.startNode(name);
// It depends on the object and it's value what todo next:
if (bean instanceof Collection) {
Collection col = (Collection) bean;
// Iterate through components, and call ourselves to process
// elements
for (Object aCol : col) {
serializeIt(aCol, "value", writer, stack);
}
} else if (bean instanceof Map) {
Map map = (Map) bean;
// Loop through keys and call ourselves
for (Object key : map.keySet()) {
Object Objvalue = map.get(key);
serializeIt(Objvalue, key.toString(), writer, stack);
}
} else if (bean.getClass().isArray()) {
// It's an array, loop through it and keep calling ourselves
for (int i = 0; i < Array.getLength(bean); i++) {
serializeIt(Array.get(bean, i), "arrayitem", writer, stack);
}
} else {
if (clsName.startsWith("java.lang")) {
writer.setValue(bean.toString());
} else {
// Not java.lang, so we can call ourselves with this object's
// values
try {
BeanInfo info = Introspector.getBeanInfo(bean.getClass());
PropertyDescriptor[] props = info.getPropertyDescriptors();
for (PropertyDescriptor prop : props) {
String n = prop.getName();
Method m = prop.getReadMethod();
// Call ourselves with the result of the method
// invocation
if (m != null) {
serializeIt(m.invoke(bean), n, writer, stack);
}
}
} catch (Exception e) {
log.error(e, e);
}
}
}
writer.endNode();
// Remove object from stack
stack.remove(bean);
| public void | setDevMode(java.lang.String mode)
this.devMode = "true".equals(mode);
| public void | setEnableXmlWithConsole(boolean enableXmlWithConsole)
this.enableXmlWithConsole = enableXmlWithConsole;
| public void | setFreemarkerManager(org.apache.struts2.views.freemarker.FreemarkerManager mgr)
this.freemarkerManager = mgr;
|
|