ZetCode

Jetty 中的 FastCGI

最后修改于 2024 年 1 月 27 日

Jetty 可以通过 FastCGI 来提供 PHP、Python 或 Ruby 脚本。FastCGI 是一种网络协议,主要由 Web 服务器用来与 FastCGI 服务器通信。FastCGI 服务器用于提供由动态 Web 语言(包括 PHP、Python、Ruby、Perl 等)生成的 Web 内容。

处理 CGI 脚本的 Servlet 称为 org.eclipse.jetty.servlets.CGI。该 Servlet 是异步的,因此,我们必须将 <async-supported>true</async-supported> 添加到 web.xml 文件中。

index.html
<!DOCTYPE html>
<html>
    <body>
        Get environment <a href="cgi-bin/evars.py">variables</a>
    </body>
</html>

当我们的 Web 应用程序启动时,它会显示这个简单的 HTML 文件。一个链接指向一个 Python CGI 脚本,用于获取环境变量。

evars.py
#!/usr/bin/python

import sys
import os
from cgi import escape

print "Content-type: text/html"
print
print "<!doctype html>"
print "<html>"
print "<body>"
print "<pre>"
for k in sorted(os.environ):
    print "<b>%s: </b>%s" %(escape(k), escape(os.environ[k]))
print "</pre>"
print "</body>"
print "</html>"

我们的示例将处理这个 Python 脚本。它创建一个简单的 HTML 页面,其中包含环境变量。

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
             http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
  
    <servlet>
        <servlet-name>CGI</servlet-name>
        <servlet-class>org.eclipse.jetty.servlets.CGI</servlet-class>
        <init-param>
            <param-name>Path</param-name>
            <param-value>/bin:/usr/bin:/usr/local/bin</param-value>
        </init-param>
        <init-param>
            <param-name>cgibinResourceBaseIsRelative</param-name>
            <param-value>true</param-value>
        </init-param>      
        <init-param> 
            <param-name>commandPrefix</param-name> 
            <param-value>/usr/bin/python</param-value> 
        </init-param>         
        <init-param>
            <param-name>cgibinResourceBase</param-name>
            <param-value>WEB-INF/cgi-bin</param-value>
        </init-param>
        <async-supported>true</async-supported>
        <load-on-startup>1</load-on-startup>
    </servlet>
        
    <servlet-mapping>
        <servlet-name>CGI</servlet-name>
        <url-pattern>/cgi-bin/*</url-pattern>
    </servlet-mapping>  
    
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>    
  
</web-app>

这是应用程序的 web.xml 文件。它将 CGI Servlet 映射到 /cgi-bin/* URL 模式。在欢迎文件列表中,我们指定了包含指向 Python 脚本链接的 index.html 文件。cgibinResourceBaseIsRelativecgi-bin 目录的路径设置为相对于 Web 应用程序文档根目录。commandPrefix 参数指定了 Python 解释器的路径。

build.xml
<?xml version="1.0" encoding="UTF-8"?>

<project name="FastCGIServlet" default="archive">
  
    <property name="name" value="cgiexample"/>
    <property environment="env"/>
    <property name="src.dir" value="src"/>
    <property name="web.dir" value="${src.dir}/web"/>
    <property name="dist.dir" location="dist"/>
    <property name="deploy.path" location="${env.JETTY_BASE}/webapps"/>
  
    <target name="init">
        <mkdir dir="${dist.dir}"/>
    </target>     
  
    <target name="archive" depends="init">
        <war destfile="${dist.dir}/${name}.war" 
             webxml="${web.dir}/WEB-INF/web.xml">
            <fileset dir="${web.dir}"/>
        </war>
        <echo>Archive created</echo>
    </target> 
  
    <target name="clean" depends="init">
        <delete dir="${dist.dir}"/>
        <echo>Cleaning completed</echo>
    </target>  
    
    <target name="deploy" depends="archive">
        <copy file="${dist.dir}/${name}.war" overwrite="true" 
              todir="${deploy.path}"/>
        <echo>Archive deployed</echo>
    </target>    
    
</project>

Ant 的 archive 任务创建了一个 Web 归档文件,其中包含 index.html 文件、web.xml 文件以及 WEB-INF/cgi-bin/ 子目录中的 Python 脚本。deploy 任务将 WAR 文件复制到 Jetty 基础的部署目录中。

$ java -jar $JETTY_HOME/start.jar --add-to-start=http,deploy,servlets

假设我们还没有在 Jetty 基础中启用任何模块,我们启用了这三个模块。Jetty CGI Servlet 在 servlets 模块中。

$ java -jar $JETTY_HOME/start.jar

我们启动 Jetty 服务器。现在我们可以导航到 https://:8080/cgiexample/ URL。

Output of the Python script
图:Python 脚本的输出

在本章的 Jetty 教程中,我们使用 Jetty 的 CGI Servlet 执行了一个 Python 脚本。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有Java教程