首页 > 解决方案 > 如何在一个 servlet 中有多个端点并在 web.xml 中声明它们

问题描述

我正在学习 servlet,我想在一个 servlet 中创建两个不同的端点。我的意思是,我想让 /hello 和 /test 它们中的每一个都应该执行或引用不同的类,如下所示。

换句话说,我希望能够访问:

http://localhost:8080/HelloServlet/hello
and
http://localhost:8080/HelloServlet/Test

以便必须调用相应的或相应的类并显示相应的内容

HelloWorld 示例:

@WebServlet(name = "HelloServlet", urlPatterns = {"/sayHello", "/hello", "/helloWorld"})
public class HelloWorld extends HttpServlet{

    private String responseContentType = null;
    
    public HelloWorld() {
        super();
    }
    
    public void init() throws ServletException {
        responseContentType = "text/html;charset=UTF-8";
    }
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
                   throws IOException, ServletException {
          // Set the response message's MIME type
          response.setContentType(responseContentType);
          // Allocate a output writer to write the response message into the network socket
          PrintWriter out = response.getWriter();
     
          // Write the response message, in an HTML page
          try {
             out.println("<!DOCTYPE html>");
             out.println("<html><head>");
             out.println("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>");
             out.println("<title>Hello, World</title></head>");
             out.println("<body>");
             out.println("<h1>Hello, world!</h1>");  // says Hello
             // Echo client's request information
             out.println("<p>Request URI: " + request.getRequestURI() + "</p>");
             out.println("<p>Protocol: " + request.getProtocol() + "</p>");
             out.println("<p>PathInfo: " + request.getPathInfo() + "</p>");
             out.println("<p>Remote Address: " + request.getRemoteAddr() + "</p>");
             // Generate a random number upon each request
             out.println("<p>A Random Number: <strong>" + Math.random() + "</strong></p>");
             out.println("</body>");
             out.println("</html>");
          } finally {
             out.close();  // Always close the output writer
          }
       }
}

测试示例:

@WebServlet(name = "HelloServlet", urlPatterns = {"/test"})
public class Test extends HttpServlet{
    
private String responseContentType = null;
    
    public Test() {
        super();
    }
    
    public void init() throws ServletException {
        responseContentType = "text/html;charset=UTF-8";
    }
    
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
   // Set the response message's MIME type
   response.setContentType(responseContentType);
   // Allocate a output writer to write the response message into the network socket
   PrintWriter out = response.getWriter();

   // Write the response message, in an HTML page
   try {
      out.println("<!DOCTYPE html>");
      out.println("<html><head>");
      out.println("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>");
      out.println("<title>Hello, World</title></head>");
      out.println("<body>");
      out.println("<h1>TEST</h1>");  // says Hello
      // Echo client's request information

      // Generate a random number upon each request
      out.println("<p>A Random Number: <strong>" + Math.random() + "</strong></p>");
      out.println("</body>");
      out.println("</html>");
   } finally {
      out.close();  // Always close the output writer
   }
}
}

web.xml:

    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>HelloServlet</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
      <servlet-name>HelloServlet</servlet-name>
      <servlet-class>com.examples.HelloWorld</servlet-class>
      <servlet-class>com.examples.Test</servlet-class>
   </servlet>
   
 <servlet-mapping>
      <servlet-name>HelloServlet</servlet-name>
      <url-pattern>/sayHello</url-pattern>
      <url-pattern>/hello</url-pattern>
      <url-pattern>/helloWorld</url-pattern>
   </servlet-mapping>
   
 <servlet-mapping>
      <servlet-name>HelloServlet</servlet-name>
      <url-pattern>/test</url-pattern>
   </servlet-mapping>

</webapp>

标签: javaservlets

解决方案


如果你真的想在同一个类中创建两个不同的端点,不管出于什么奇怪的原因,这里有两个我能想到的解决方案:

  1. 尝试使用 @WebServlet 注释实现一个内部类。我不知道它是否会被拾取并安装,但值得一试
  2. 有两个班级,但让第二个班级(带有第二个地址)调用第一个班级。当我有多个页面需要的任务时,这就是我经常做的(静态)。

我自己曾经写过一个库来解析地址的注释,我想“啊,我比那些愚蠢的 JEE 东西要好......我也会允许对单个方法进行注释”。这一点也不难实现。但是:我很遗憾这样做,因为使用的软件变得非常笨拙和奇怪,一个文件可能是多个端点的根......所以当我重新设计那个库时,我删除了那个函数,现在只允许端点类级别的注释。坚持这一点的项目更加清洁和易于维护。

嗯......所以这两个选项都适用于 JEE。但最重要的问题是:你为什么想要你所要求的?这似乎是一个 XY 问题:https ://meta.stackexchange.com/questions/66377/what-is-the-xy-problem 。


推荐阅读