|
From: Brian Z. <bri...@ya...> - 2001-02-02 03:23:24
|
With the changes I made, it works great now. Here are the two classes I
changed:
pyservlet.PyHandler in the place of the old PyServlet
pyservlet.HandlerAwareHttpServlet
The same handler can deal with both 1) jython servlet derived from
HttpServlet and 2) jython servlet derived from HandlerAwareHttpServlet.
Fortunately most info is from request, so only when you need to port
SnoopServlet do you need to use 2.
I also send this to the jython-dev list in hoping that in future
release, we can have servlet support built-in. I view this as one of the
big strength of using jython, if JSP is mod_php to apache, we have the
equivalent of mod_python now. JDBC, XMLC, imageio, the possiblilities
are endless.
Following are the two java files and some sample jython servlet scripts. I
love it! Thank you
jython developers.
/Brian
// pyservlet/HandlerAwareHttpServlet.java
package pyservlet;
import javax.servlet.http.*;
/**
*
* @author <a href="mailto:bri...@ya...">Brian Zhou</a>
*/
public abstract class HandlerAwareHttpServlet extends HttpServlet {
protected HttpServlet theHandler = null;
public void setHandler(HttpServlet aHandler) {
this.theHandler = aHandler;
}
public HttpServlet getHandler() {
return this.theHandler;
}
}
// pyservlet/PyHandler.java
package pyservlet;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.python.util.PythonInterpreter;
import org.python.core.*;
/**
* This servlet is used to tell the if the Apache JServ installation was
* successful.
*
* @author <a href="mailto:stefano@a...">Stefano Mazzocchi</a>
*/
public class PyHandler extends HttpServlet {
static Hashtable servlets = new Hashtable(); // Cache for HttpServlet
static Hashtable dates = new Hashtable(); // Timestamps for Cache
entries
PythonInterpreter interp = new PythonInterpreter();
public void service (ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
HttpServlet servlet =
getServlet(getServletContext().getRealPath(
((HttpServletRequest)req).getServletPath()) );
if (servlet != null) {
if (servlet instanceof HandlerAwareHttpServlet) {
((HandlerAwareHttpServlet) servlet).setHandler(this);
}
servlet.service(req, res);
}
}
HttpServlet getServlet(String path)
throws ServletException, IOException
{
Long date = (Long) dates.get(path);
if (date != null) { // Check for cache validity
File file = new File(path);
if (date.longValue() < file.lastModified()) // Cache invalid
return (loadServlet(path)); // Reload servlet
else
return ((HttpServlet) servlets.get(path));
} else {
return (loadServlet(path)); // Not in cache, load servlet
}
}
HttpServlet loadServlet(String path)
throws ServletException, IOException
{
HttpServlet servlet = null;
File file = new File(path);
// Extract servlet name from path (strip ".../" and ".py")
int start = path.lastIndexOf(System.getProperty("file.separator"));
if (start < 0)
start = 0;
else
start++;
int end = path.lastIndexOf(".py");
if (end < 0 || end <= start)
end = path.length();
try { // Create servlet
interp.execfile(path);
PyObject pyServlet = interp.eval(path.substring(start,
end)+"()");
servlet =
(HttpServlet) pyServlet.__tojava__(
Class.forName("javax.servlet.http.HttpServlet"));
}
catch (PyException e) {
System.err.println(e);
throw new ServletException("Could not create Jython
servlet");
}
catch (ClassNotFoundException e) {
System.err.println(e);
throw new ServletException("Could not create Jython
servlet");
}
servlets.put(path, servlet); // Add servlet to
cache
dates.put(path, new Long(file.lastModified())); // Add timestamp
return (servlet);
}
}
# hello.py
import sys, java, javax
class hello(javax.servlet.http.HttpServlet):
def doGet(self, req, res):
res.setContentType("text/html");
out = res.getOutputStream()
out.println("""\
<html>
<head><title>Hello World</title></head>
<body>Hello World!
<P>
current server time is: %s
</P>
</body>
</html>
""" % (java.util.Date()))
out.close()
return
# titles.py
import java, javax
class titles(javax.servlet.http.HttpServlet):
def doGet(self, request, response):
response.setContentType("text/plain")
out = response.getOutputStream()
self.dbTitles(out)
out.close()
return
def dbTitles(self, out):
server, db = "ncv-dev2", "pubs"
usr, passwd = "sa", ""
driver = "com.inet.tds.TdsDriver"
port = 1433
url = "jdbc:inetdae:" + server + ":" + `port` + "?database=" + db
java.lang.Class.forName(driver).newInstance()
conn = java.sql.DriverManager.getConnection(url, usr, passwd)
query = "select title, price, ytd_sales, pubdate from titles"
stmt = conn.createStatement()
if stmt.execute(query):
rs = stmt.getResultSet()
while rs and rs.next():
out.println(rs.getString("title"))
if rs.getObject("price"):
out.println("%2.2f" % rs.getFloat("price"))
else:
out.println("null")
if rs.getObject("ytd_sales"):
out.println(rs.getInt("ytd_sales"))
else:
out.println("null")
out.println(rs.getTimestamp("pubdate").toString())
out.println()
stmt.close()
conn.close()
# snoop.py
from pyservlet import HandlerAwareHttpServlet
class snoop(HandlerAwareHttpServlet):
def doGet(self, request, response):
out = response.getOutputStream()
response.setContentType("text/plain");
out.print("""\
Snoop Servlet
""")
out.print("""\
Servlet init parameters:
""")
enum = self.getHandler().getInitParameterNames()
while enum.hasMoreElements():
key = enum.nextElement()
value = self.getInitParameter(key)
out.print("""\
%s = %s
""" % (key, value))
out.print("""\
Context init parameters:
""")
context = self.getHandler().getServletContext()
enum = context.getInitParameterNames()
while enum.hasMoreElements():
key = enum.nextElement()
value = context.getInitParameter(key)
out.print("""\
%s = %s
""" % (key, value))
out.print("""\
Context attributes:
""")
context = self.getHandler().getServletContext()
enum = context.getAttributeNames()
while enum.hasMoreElements():
key = enum.nextElement()
value = context.getAttribute(key)
out.print("""\
%s = %s
""" % (key, value))
out.print("""\
Request attributes:
""")
enum = request.getAttributeNames()
while enum.hasMoreElements():
key = enum.nextElement()
value = request.getAttribute(key)
out.print("""\
%s = %s
""" % (key, value))
out.print("""\
Servlet Name: %s
Protocol: %s
Scheme: %s
Server Name: %s
Server Port: %s
Server Info: %s
Remote Addr: %s
Remote Host: %s
Character Encoding: %s
Content Length: %s
Content Type: %s
Locale: %s
Default Response Buffer Size: %s
""" % (
self.getHandler().getServletName(),
request.getProtocol(),
request.getScheme(),
request.getServerName(),
request.getServerPort(),
self.getHandler().getServletContext().getServerInfo(),
request.getRemoteAddr(),
request.getRemoteHost(),
request.getCharacterEncoding(),
request.getContentLength(),
request.getContentType(),
request.getLocale(),
response.getBufferSize()
))
out.print("""\
Parameter names in this request:
""")
enum = request.getParameterNames()
while enum.hasMoreElements():
key = enum.nextElement()
values = request.getParameterValues(key)
out.print(" '%s' = " % key)
for value in values:
out.print("'%s' " % value)
out.println()
out.print("""\
Headers in this request:
""")
enum = request.getHeaderNames()
while enum.hasMoreElements():
key = enum.nextElement()
value = request.getHeader(key)
out.print("""\
%s = %s
""" % (key, value))
out.print("""\
Cookies in this request:
""")
cookies = request.getCookies()
for cookie in cookies:
out.print("""\
%s = %s
""" % (cookie.getName(), cookie.getValue()))
out.print("""\
Request Is Secure: %s
Auth Type: %s
HTTP Method: %s
Remote User: %s
Request URI: %s
Context Path: %s
Servlet Path: %s
Path Info: %s
Path Trans: %s
Query String: %s
""" % (
request.isSecure(),
request.getAuthType(),
request.getMethod(),
request.getRemoteUser(),
request.getRequestURI(),
request.getContextPath(),
request.getServletPath(),
request.getPathInfo(),
request.getPathTranslated(),
request.getQueryString()
))
session = request.getSession()
out.print("""\
Requested Session Id: %s
Current Session Id: %s
Session Created Time: %s
Session Last Accessed Time: %s
Session Max Inactive Interval Seconds: %d
""" % (
request.getRequestedSessionId(),
session.getId(),
session.getCreationTime(),
session.getLastAccessedTime(),
session.getMaxInactiveInterval()
))
out.print("""\
Session values:
""")
names = session.getAttributeNames()
while names.hasMoreElements():
name = names.nextElement()
out.println(" '%s' = '%s'" % (name,
session.getAttribute(name)))
out.close()
return
----- Original Message -----
From: "Brian Zhou" <bri...@ya...>
To: <jyt...@li...>
Cc: <jyt...@li...>
Sent: Wednesday, January 31, 2001 9:34 AM
Subject: [Jython-users] servlet problem self.getInitParameterNames()
under PyServlet wrapper
> Hello list,
>
> Following http://groups.yahoo.com/group/jpython/message/3714 I
succeeded
> making servlet running under PyServlet wrapper/handler on win2k
tomcat3.2.1.
> So far so good, I can run simple script like:
>
> import sys, java, javax
>
> class hello(javax.servlet.http.HttpServlet):
> def doGet(self, req, res):
> res.setContentType("text/html");
> out = res.getOutputStream()
> out.println("""\
> <html>
> <head><title>Hello World</title></head>
> <body>Hello World!
> <P>
> current server time is: %s
> </P>
> </body>
> </html>
> """ % (java.util.Date()))
> out.close()
> return
>
> Or even dynamicly generate PNG graph thanks to the new javax.imagio
package
> from Sun. I don't expect any difficulty hooking up with database using
JDBC.
>
> However, when trying to port SnoopServlet from java to jython, I found
that
> PyServlet really doesn't handover any instant variables to the jython
> HttpServlet subclass except (request, response). So
>
> enum = self.getInitParameterNames()
>
> will got a NullPointerException. Any operation involve self.attribute
like
> self.getServletContext() will also fail. I don't think jythonc
compiled
> classes will have this problem because the jython servlet handle
service()
> directly bypassing PyServlet.
>
> So my questions are:
>
> 1. Am I missing anything? Any misunderstanding of the API?
> 2. Any way around? Anyone got a better PyServlet?
> 3. If I'm the first one got bitten, any idea how we may overcome this
> problem?
>
> Seeing the power of dynamic python scripting at work (instant feedback
> without re-compiling), I really appreciate what have been done so far,
and
> want to get it going. Here are some of my ideas:
>
> 1. We can have two seperate subclasses of HttpServlet in java:
> one possibly named ServletPyHandler, doing what PyServlet
currently is
> doing, dispatching service() calls to jython servlet;
> the other JyServlet being superclass of all jython servlets, with
> constructor JyServlet(ServletPyHandler), so JyServlet always has a ref
to
> the ServletPyHandler instance;
> The downside of this approach is that now jythonc compiled servlet and
> dynamically interpreted servlet have to be written differently.
>
> 2. Have ServletPyHandler do somthing to the jython servlet class right
> before dispatching service() call, so that inside jython servlet,
later when
> messages like self.getInitParameterNames() will be redirected back to
> ServletPyHandler.
>
> TIA for any ideas,
>
> /Brian
>
>
>
> _______________________________________________
> Jython-users mailing list
> Jyt...@li...
> http://lists.sourceforge.net/lists/listinfo/jython-users
|