Skip navigation.
Home

BeanHack: Plugging BeanShell into the Web tier

I wrote BeanHack to add [BeanShell|http://www.beanshell.org] scripting capabilities to any complaint servlet container. It enables you to write in BeanShell taking advantage of it's simpler syntax, for example, to rapidly prototype some idea as no compilation (not even by the container) is involved. It's BSD-licensed and the binary JAR file is attached to this article (__rename it from .jar.txt to just .jar__). I'm also planning to write some compiled BeanShell commands to further ease the access (but also considering security) to the underlying servlet model. To install BeanHack on Tomcat *In $TOMCAT_HOME/conf/web.xml, add the this servlet declaration {{{ bsh beanhack.BshServlet }}} and this mapping to the mappings section {{{ bsh *.bsh }}} *In $TOMCAT_HOME/shared/lib add the beanhack jar and the bsh-core and bsh-commands jar (can be downloaded from http://www.beanshell.org/, tested with version 2.0b4).. That's all! now copy and past the following BeanShell script to $TOMCAT_HOME/webapps/ROOT/rockon.bsh {{{ print("BeanShell rocks Tomcat!"); }}} and invoke it by pointing your browser to http://localhost:8080/rockon.bsh .Source code follows {{{ package beanhack; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintStream; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import bsh.Interpreter; /** *

* Adds BeanShell [http://www.beanshell.org] * scripting capabilities to any complaint servlet container. * It intercepts URIs with a ".bsh" at the end, locates the script * and pass it to a newly created instance of the BeanShell interpreter. *

* * Implicit Objects *

* The following objects are exposed to BeanShell scripts: *

    *
  • context: ServletContext associated with current request
  • *
  • request: HttpServletRequest associated with current request
  • *
  • response: HttpServletResponse associated with current request
  • *
  • session[optional]: HttpSession associated with current request * (see Initialization Parameters below)
  • *
*

*

* Initialization Parameters: *

    *
  • contentType: Response content type. Default is "text/html".
  • *
  • startSession[true|false]: Expose (and implicitly start) session object to scripts. * You can selectively start session from within a BeanShell script by calling getSession() * of the request implicit object.
  • *
*

* * @author Ahmed Saad * @version 0.1b */ public class BshServlet extends HttpServlet { private static final long serialVersionUID = 1L; ServletConfig config; public BshServlet() { config = null; } /** * Capture ServletConfig. * * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig) */ public void init(ServletConfig config) throws ServletException { super.init(config); this.config = config; } /** * Process the BeanShell script. * * @see javax.servlet.http.HttpServlet#service( javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // extract file name String uri = request.getRequestURI(); String filename = uri.substring(uri.lastIndexOf('/')); // reslove to filesystem path String path = config.getServletContext().getRealPath(filename); // extract base directory (CWD for script) String base = path.substring(0, path.lastIndexOf(File.separatorChar)); // double-escape slashes in path // (required for passing windows pathes to BeanShell) StringBuilder builder = new StringBuilder(); for (int x = 0, n = base.length(); x < n; x++) { char c = base.charAt(x); if (c == '\\') { builder.append('\\'); } builder.append(c); } // execute script Interpreter interpreter = new Interpreter(); interpreter.setOut(new PrintStream(response.getOutputStream())); try { interpreter.eval("bsh.cwd = \"" + builder.toString() + "\""); if (config.getInitParameter("contentType") != null) { response.setContentType(config.getInitParameter("contentType")); } else { response.setContentType("text/html"); }; interpreter.set("request", request); interpreter.set("response", response); interpreter.set("context", config.getServletContext()); if (config.getInitParameter("startSession") != null) { interpreter.set("session", request.getSession()); } interpreter.source(path); } catch(FileNotFoundException fnf) { response.sendError(HttpServletResponse.SC_NOT_FOUND, uri); } catch (Exception e) { throw new ServletException(e); } } } }}}
AttachmentSize
beanhack-0.1b.jar.txt2.27 KB