Of course! Running Python CGI scripts on Apache Tomcat is a less common setup than using a traditional web server like Apache HTTPD or Nginx, but it is absolutely possible. This guide will walk you through the entire process, from understanding the concepts to a complete, step-by-step example.

Understanding the Core Concepts
Before we start, let's clarify the roles of each component:
-
Tomcat: An application server that primarily executes Java Servlets and JavaServer Pages (JSPs). It speaks the HTTP protocol and can serve static files (HTML, CSS, images), but it doesn't have a built-in, native mechanism for executing CGI scripts like older web servers do.
-
Python CGI: The Common Gateway Interface (CGI) is a standard protocol for web servers to execute external programs, like Python scripts. The server passes information to the script (e.g., form data, URL parameters) via environment variables and standard input, and the script is expected to return the HTTP response to the server via standard output.
-
The Bridge (The
CGIServlet): To make these two work together, we need a bridge. Tomcat provides a special servlet called theCGIServlet. This servlet acts as the CGI environment handler. When Tomcat receives a request for a.pyfile (or another extension you configure), it can hand that request off to theCGIServlet. TheCGIServletthen sets up all the necessary CGI environment variables and executes the specified Python script, capturing its output and returning it as the HTTP response.
(图片来源网络,侵删)
Step-by-Step Guide: Running Python CGI on Tomcat
Here is a complete walkthrough. We will:
- Set up a Tomcat server.
- Configure the
CGIServlet. - Write a simple Python CGI script.
- Deploy and test everything.
Prerequisites
- Java Development Kit (JDK): Tomcat requires Java. Install JDK 8 or later.
- Python: Ensure Python is installed on your system and the
python(orpython3) command is available in your system's PATH. - Apache Tomcat: Download the latest binary distribution from the official Apache Tomcat website. We'll use Tomcat 10 for this example.
Step 1: Install and Start Tomcat
-
Extract Tomcat: Unzip the downloaded Tomcat archive to a directory, for example,
C:\apache-tomcat-10.1.x(Windows) or/opt/apache-tomcat-10.1.x(Linux/macOS). -
Start Tomcat: Navigate to the
bindirectory inside the Tomcat folder and run the startup script.- Windows:
startup.bat - Linux/macOS:
./startup.sh
- Windows:
-
Verify: Open your web browser and go to
http://localhost:8080. You should see the Tomcat welcome page.
(图片来源网络,侵删)
Step 2: Configure the CGIServlet in Tomcat
This is the most critical step. We need to tell Tomcat to use the CGIServlet to handle Python scripts.
-
Locate
web.xml: Find the main deployment descriptor file for the default web application. It's located at:TOMCAT_HOME/conf/web.xml -
Add the
CGIServletConfiguration: Add the following XML snippet inside the<web-app>tags inconf/web.xml. This defines the servlet and maps it to handle files with a.pyextension.<!-- conf/web.xml --> <web-app ...> ... other default configurations ... <!-- CGI Servlet Configuration --> <servlet> <servlet-name>cgi</servlet-name> <servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class> <init-param> <param-name>cgiPathPrefix</param-name> <param-value>WEB-INF/cgi</param-value> </init-param> <init-param> <param-name>executable</param-name> <param-value>python</param-value> </init-param> <load-on-startup>5</load-on-startup> </servlet> <servlet-mapping> <servlet-name>cgi</servlet-name> <url-pattern>*.py</url-pattern> </servlet-mapping> ... other default configurations ... </web-app>Explanation of Parameters:
<servlet-class>: The fully qualified name of the Tomcat CGI servlet.cgiPathPrefix: This is very important. It tells Tomcat to look for your CGI scripts inside a specific directory to prevent them from being accessed directly. We will create this directory (WEB-INF/cgi) in our web app.executable: The command used to run the script. We've set it topython. If you need to usepython3, change this value topython3.<url-pattern>*.py</url-pattern>: This maps any request ending in.pyto ourCGIServlet.
-
Restart Tomcat: For the changes to take effect, you must stop and restart Tomcat.
- Windows:
shutdown.batfollowed bystartup.bat - Linux/macOS:
./shutdown.shfollowed by./startup.sh
- Windows:
Step 3: Create the Web Application and Python Script
Now, let's create the files for our web application.
-
Create the Web App Directory: Inside the
TOMCAT_HOME/webappsdirectory, create a new folder for your app, for example,pycgi_app.TOMCAT_HOME/ ├── webapps/ │ ├── pycgi_app/ <-- Our new web application │ │ ├── WEB-INF/ │ │ │ └── cgi/ <-- The directory for our Python scripts (from cgiPathPrefix) │ │ │ └── ... │ │ └── index.html <-- A simple front-end page │ └── ... └── ... -
Create the Python CGI Script: Inside the
pycgi_app/WEB-INF/cgi/directory, create a file namedhello.py.#!/usr/bin/env python # pycgi_app/WEB-INF/cgi/hello.py import cgi import html print("Content-Type: text/html\n") # The mandatory blank line print("<html>") print("<head><title>Python CGI on Tomcat</title></head>") print("<body>") print("<h1>Hello from a Python CGI Script on Tomcat!</h1>") # Check for form data form = cgi.FieldStorage() name = form.getvalue('name') if name: print(f"<p>Hello, {html.escape(name)}!</p>") else: print("<p>Please enter your name in the form below.</p>") print("<hr>") print("<form method='post'>") print(" Name: <input type='text' name='name'>") print(" <input type='submit' value='Submit'>") print("</form>") print("</body>") print("</html>")Key Points for the Python Script:
#!/usr/bin/env python: This is the "shebang". It tells the system to use thepythoninterpreter to run this script. While theexecutableparameter inweb.xmlis the primary method, the shebang is good practice.print("Content-Type: text/html\n"): This is the most crucial line in any CGI script. It prints the HTTP header, telling the browser that the content is HTML. The two newline characters (\n\n) are mandatory to separate the header from the body.cgi.FieldStorage(): This parses any form data sent to the script via GET or POST.
-
Create a Simple HTML Form: In the root of your web app (
pycgi_app/), create anindex.htmlfile to make it easy to access the script.<!-- pycgi_app/index.html --> <!DOCTYPE html> <html> <head> <title>CGI Test Page</title> </head> <body> <h2>Welcome to the Python CGI Demo</h2> <p>Click the link below to run the Python CGI script.</p> <a href="/pycgi_app/WEB-INF/cgi/hello.py">Run Hello Script</a> </body> </html>Note: The URL path is
/pycgi_app/WEB-INF/cgi/hello.pybecause this is the path Tomcat will see for the resource.
Step 4: Test Your Application
-
Make sure Tomcat is running.
-
Open your web browser and navigate to your application's start page:
http://localhost:8080/pycgi_app/ -
You should see the "Welcome" page with a link.
-
Click the link "Run Hello Script".
-
You will now see the output from your
hello.pyscript, displaying "Hello from a Python CGI Script on Tomcat!" and the form. -
Fill in your name in the text box and click "Submit". The page should reload and greet you by name!
Important Considerations and Best Practices
-
Security: Running CGI scripts has security implications. The
WEB-INF/cgidirectory is a good first step as it's protected from direct URL access. However, be mindful of what your scripts do, especially if they handle file I/O or system commands. -
Performance: CGI is an older technology. For every request, Tomcat has to start a new Python process, run the script, and then terminate the process. This is inefficient under heavy load. For modern Python web applications on the JVM, consider using a WSGI server like uWSGI or Gunicorn behind a proxy server (like Nginx), or even better, use a Java-based Python implementation like Jython.
-
File Permissions (Linux/macOS): If you are on Linux or macOS, you may need to make your Python script executable:
chmod +x TOMCAT_HOME/webapps/pycgi_app/WEB-INF/cgi/hello.py
-
Debugging: If your script doesn't work, the first place to look is the Tomcat logs. They are located in
TOMCAT_HOME/logs/catalina.out(orcatalina.YYYY-MM-DD.log). If your Python script has an error, it will often print the error message to this log file.
