1

我对 servlet 相当陌生,如果 uri 与某个路径匹配,我处理来自客户端的响应的方式是:

public class EntryServlet extends HttpServlet
{
  public void doGet (HttpServletRequest request, HttpServletResponse response) 
    throws IOException
  {
    String uri = request.getRequestURI ();

    if (uri.matches ("/1")) {
      do something....
    } else if (uri.matches ("/2")) {
      do something else.....    
    } else {
      throw error message...
    }
  }
}

这仅在我的 Web 服务有几个页面时才有效。但是假设我有 50 个 xml 文档,我想将 exmaple.com/1 映射到一个 xml ...到 example.com/50 到另一个 xml。现在如果有 50 个 if else 语句来处理每个资源,那将是一个糟糕的设计。有什么更好的方法来实现这一点?我试图在没有第三方应用程序/插件/框架的情况下纯粹在 java 中做到这一点

更新:我只使用一个带有后台线程的 servlet。本质上是处理文件的客户端请求,后台线程处理处理并将 xml 文档存储在数据库中。我希望每个 xml 文档都成为 Web 服务上的资源。

4

5 回答 5

4

您给出了“我想映射”的答案,所以让我们使用 Map

你有 2 个选项(我现在看到的)

1:您将“/ 1”作为键并将字符串作为映射到您的 xyz.xml 的值

2:您将“/ 1”作为键并放置一个实现“Executor”接口的对象...

在这两种情况下,您都会查找键的值,然后使用值对象返回有用的东西。

把它放在你的 Servlet 的 init 中并用你的对象填充它:

Map<String,String> myActions = new HashMap<String,String>();
myActions.put("/1","one.xml");
.....

现在你可以这样做:

String uri = request.getRequestURI ();

if (myActions.containsKey(uri)) {
   String value = myActions.get(uri);
   do something with value
} else {
   throw error message...
}

您可以使用实现此功能的对象轻松地将其更改为选项 2:

public interface Action {
    String execute(HttpServletRequest req, HttpServletResponse res) throws ServletException,
            IOException;
}
于 2012-11-18T15:19:32.857 回答
2

答案可能取决于您要如何处理 URI 中的信息。在编写 REST 风格的应用程序时,URI 是将信息传递给应用程序的主要方式之一。因此,如果您可能想重新考虑您对其他软件包的厌恶,因为 REST API 非常受欢迎是有充分理由的。

坚持使用普通的 Servlet,假设我们有 50 个 xml 文档,我们希望根据通过 URL 传递的 id 号来提供这些文档。我们可以在数据库中存储一个表,该表指示 id 号和文档之间的对应关系。或者我们可以将这些数据存储到 CSV 文件中。无论哪种方式,对于这样一个相对较小的表,我都会在 Servlet 启动时将整个表加载到内存中。您可以将代码放在 init() 方法中以将数据加载到您的应用程序中。

然后我们有这样的事情:

static HashMap<Integer, String> fileMap;
public void init() {
    fileMap = new HashMap<> ();
    fileMap.put(1,"thing1.xml");
    fileMap.put(2,"thing2.xml");
    fileMap.put(3,"Otherthingy.xml");
}

现在您可以在 doGet 方法中编写更简洁的代码。

public void doGet (HttpServletRequest request, HttpServletResponse response) 
                               throws IOException  {
        String uri = request.getRequestURI();
        int slash = uri.indexOf("/");
        if(slash+1 == uri.length())
            //throw an error

        String idString = request.getRequestURI().substring(slash+1);
        int id = Integer.parseInt(idString);
        //should put this in a try catch block and throw an error if it is not a number.
        String requestedFile = fileMap.get(id);
        if(requestedFile == null)
            //throw some error.
        // Do whatever you need to do with the file.
}
于 2012-11-18T15:32:37.387 回答
1

你应该

  1. 将每个 URI 特定逻辑移动到不同的 servlet。
  2. 使用 Java Servlet Specification 中的 servlet 映射概念并在 web.xml 中定义以下内容

    <!- Define the servlets here, ofcourse you should use meaningful names -->
    <servlet>
        <servlet-name>servlet-1</servlet-name>
        <servlet-class>com.vikdor.webapps.ServletForURI1</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>servlet-2</servlet-name>
        <servlet-class>com.vikdor.webapps.ServletForURI2</servlet-class>
    </servlet>
    ....
    
    
    <!- Map the servlet to the URL pattern -->
    <servlet-mapping>
        <servlet-name>servlet-1</servlet-name>
        <url-pattern>/1/</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>servlet-2</servlet-name>
        <url-pattern>/2/</url-pattern>
    </servlet-mapping>
    ....
    

这会将路由逻辑推送到 web.xml 并且每个 servlet 执行特定的工作。

于 2012-11-18T15:17:09.513 回答
0

您可以在您的 web.xml uri 模式中指定路由到特定的 servlet 类。原谅我糟糕的 servlet 名称。

<servlet>
    <servlet-name>processUserXml</servlet-name>
    <servlet-class>com.example.server.ProcessUserXml</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>processUserXml</servlet-name>
    <url-pattern>/processuser</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>processItemXml</servlet-name>
    <servlet-class>com.example.server.ProcessItemXml</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>processItemXml</servlet-name>
    <url-pattern>/processitem</url-pattern>
</servlet-mapping>

因此,当用户调用特定的 uri 时,它不会接受来自单个网关的 uri 请求并通过if语句路由它们(就像您现在所做的那样),它会被路由到适合您的 servlet 类。因此,调用 uri/processuser会将调用路由到ProcessUserXmlservlet 类doGet方法(或者doPost,如果它已定义并且这就是用户进行 HTTP 调用的方式)。

于 2012-11-18T15:20:18.267 回答
0

使用框架。这就是他们的目的。我偏爱Spring MVC,但对于像这样的基本用例,任何现代的东西都应该没问题。第一次设置它可能会感觉很痛苦,但是一旦配置好,开发就会更快易于维护。

编辑:我刚刚注意到原始问题说不要使用任何框架/库。我仍然坚持这个答案,尽管大多数时候这是一个坏主意。如果你真的需要,那么你可以按照其他一些人的建议创建地图,但从长远来看,它是不可维护的,所以尽可能避免它。

于 2012-11-18T15:24:46.420 回答