After several hours of working on porting this program over, it appears to finally be in a working state. However, I was wondering if anyone knew of a better way or more complete way of porting Java servlets over into Python. The beginning of the Python script contains a lot of support code to make it easier to port the program line-by-line directly into Python. Does anyone know of a better way to go about this?
Java
// --------------------------------------------------------
// File: Hello.java
// Description: A simple "Hello World" servlet
// --------------------------------------------------------
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import sun.servlet.http.HttpServer;
public class Hello extends HttpServlet {
int count;
public void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// setup response
response.setContentType("text/html");
PrintWriter out = response.getWriter();
// send response
out.println("<html><body>");
out.println("<h5>Stephen Paul Chappell (SPC)</h5>");
out.println("<h5>:) (ZTD) Zero The Dragon :(</h5>");
String name = request.getParameter("NAME");
if (name != null && !name.equals("")) {
out.println("<h2>Hello, " + name + "</h2>");
} else {
out.println();
if (name != null && name.equals("")) {
out.println(" <h2>You didn't enter your name. Please enter your name. </h2>");
} else {
out.println(" <h2>What's your name? </h2>");
}
out.println(" <hr>");
out.println(" <form action=\"http://127.0.0.1:8080/servlet/Hello\">");
out.println();
out.println(" Enter your name: <input type=\"text\" name=\"NAME\" value=\"Fred\"><br>");
out.println(" <input type=\"submit\" value=\"Click for greeting\">");
out.println();
out.println(" </form>");
}
String color = request.getParameter("FAVCOLOR");
if (color != null) {
out.println("<h2>Why, " + color + "开发者_开发百科 is my favorite color too!</h2>");
}
count++;
out.println("This page has been hit " + count + " time(s).");
out.print("</body></html>");
}
// start web server
public static void main(String[] args) throws Exception {
HttpServer.main(args);
}
}
Python
import urllib.parse
import http.server
import cgitb
import sys
import io
################################################################################
class HttpServlet(http.server.BaseHTTPRequestHandler):
__debug = False
@staticmethod
def debug(value):
HttpServlet.__debug = value
def do_GET(self):
if self.path == '/favicon.ico':
self.send_error(404)
return
request = HttpServletRequest(self.path)
response = HttpServletResponse()
try:
self.service(request, response)
except Exception:
if HttpServlet.__debug:
self.send_response(500)
self.send_header('Content-type', 'text/html')
self.end_headers()
klass, value, trace = sys.exc_info()
html = cgitb.html((klass, value, trace.tb_next))
self.wfile.write(html.encode())
else:
self.send_error(500)
else:
self.send_response(200)
self.send_header('Content-type', response._type)
self.end_headers()
self.wfile.write(response._value)
def service(self, request, response):
raise NotImplementedError()
################################################################################
class HttpServletRequest:
def __init__(self, path):
query = urllib.parse.urlparse(path).query
self.__dict = urllib.parse.parse_qs(query, True)
def getParameter(self, name):
return self.__dict.get(name, [None])[0]
################################################################################
class HttpServletResponse:
def __init__(self):
self.__content_type = 'text/plain'
self.__print_writer = PrintWriter()
def setContentType(self, content_type):
self.__content_type = content_type
def getWriter(self):
return self.__print_writer
@property
def _type(self):
return self.__content_type
@property
def _value(self):
return self.__print_writer.getvalue().encode()
################################################################################
class PrintWriter(io.StringIO):
print = io.StringIO.write
def println(self, string):
self.write(string + '\r\n')
################################################################################
class HttpServer(http.server.HTTPServer):
@staticmethod
def main(RequestHandlerClass, port=80):
server = HttpServer(('', port), RequestHandlerClass)
socket = server.socket.getsockname()
print('Serving HTTP on', socket[0], 'port', socket[1], '...')
try:
server.serve_forever()
except KeyboardInterrupt:
print('Keyboard interrupt received: EXITING')
server.server_close()
################################################################################
################################################################################
## ---------------------------------------------------------
## File: Hello.py
## Description: A simple "Hello World" servlet
## ---------------------------------------------------------
class Hello(HttpServlet):
count = 0
def service(self, request, response):
# Setup for a response.
response.setContentType('text/html')
out = response.getWriter()
# Send an appropriate response.
out.println('''\
<html>
<head>
<title>Java to Python servlet</title>
</head>
<body>
<h5>Stephen Paul Chappell (SPC)</h5>
<h5>:) (ZTD) Zero The Dragon :(</h5>''')
name = request.getParameter('NAME')
if name:
out.println('''\
<h2>Hello, {}!</h2>'''.format(name))
else:
if name == '':
out.println('''\
<h2>You did not enter your name.</h2>
<h3>Please enter your name.</h3>''')
else:
out.println('''\
<h2>What is your name?</h2>''')
out.println('''\
<form>
<fieldset>
<legend>About Yourself</legend>
<label for='NAME'>Enter your name:</label>
<input id='NAME' name='NAME' type='text' value='John Doe' />
<br />
<input type='submit' value='Click me!' />
</fieldset>
</form>''')
color = request.getParameter('FAVCOLOR')
if color:
out.println('''\
<h2>Why, {} is my favorite color too!</h2>'''.format(color))
Hello.count += 1
out.println('''\
This page has been hit {} times.'''.format(Hello.count))
out.print('''\
</body>
</html>''')
# Start the web server.
def main():
HttpServlet.debug(True)
HttpServer.main(Hello)
################################################################################
if __name__ == '__main__':
main()
In case anyone is wondering what the purpose of this project is, the original Java program was given as an introductory exercise in freshman-level computer-science course. Since then, it has been about six years since I have worked with Java and am going through the old programs, porting them over to Python for the challenge and learning experience. Porting the servlets are presenting extra difficulties.
My best suggestion is to not write a line by line port. Python is not Java and you're hamstringing yourself if you're just writing Java style code in the Python language.
Here's a starter for recognizing some of the common differences/mistakes: http://dirtsimple.org/2004/12/python-is-not-java.html
If you're lucky enough to be working with a codebase that contains unit tests, a great way to go about this is to port your unit tests from Java to Python, and then write new python to match the unit tests. If that's not something that you have, then it's much more important to recognize what the software does in Java, and then write Python code that does the same thing. It will almost certainly not be in the same way, at least not at the line-by-line level.
Isn't this a translation and not a port? :)
I just googled and found java2python as well as a similar SO question.
Anyway ...
Ideally, i think you should understand what you're translating so you can know what to translate and what you shouldn't need to translate. You need a reasonable understanding of both languages to know how constructs in Java relate to the similar in Python and how libraries play roles in the translations.
A direct translation between languages is often not a good approach. I mention this simply because the translated Python in your question isn't very Pythonic. And also because a fair amount of the Python is concerned with the HTTP Server aspects. That isn't the case with the Java code. So to produce a "fair" translation, i would have relied on a Python framework that does for Python what Servlet containers do for Java. Maybe Tornado/Django. My point being, a Java Servlet is wrapped up in a significant set of standards so it makes sense that the Python version follow a similar route, which, at a minimum, probably means WSGI.
Not a direct answer but, any good reason to not use something like Webware which offers, among other features (see the Overview):
- Servlets. Similar to Java servlets, they provide a familiar basis for construction web applications.
Creating a python webapp in this way is confusing and non pythonic. You might have better success rewriting your app in Django rather than porting it line by line from Java
精彩评论