处理Java Servlet中的URL

时间:2012-11-18 15:11:23

标签: java http url servlets

我对servlet相当新,而且我处理来自客户端的repsonses的方式正在使用,如果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...
    }
  }
}

仅当我的网络服务有几页时才有效。但是说我有50个xml文档,我想将exmaple.com/1映射到xml ...到example.com/50到另一个xml。现在有50个if else语句来处理每个资源是不好的设计。有什么更好的方法来实现它?我试图在没有第三方应用程序/插件/框架的java中完全执行此操作

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

5 个答案:

答案 0 :(得分:4)

您给出了答案“我想要映射”,所以让我们使用地图

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

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

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

在这两种情况下,您都可以查找键的值,然后使用value对象返回有用的内容。

将它放在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;
}

答案 1 :(得分:2)

答案可能取决于您要对URI中的信息执行的操作。编写REST样式应用程序时,URI是将信息传递给应用程序的主要方式之一。因此,如果您可能想重新考虑对其他软件包的厌恶,因为REST API非常受欢迎。

坚持使用普通的Servlet,假设我们要根据通过URL传递的ID号来提供50个xml文档。 我们可以在数据库中存储一个表,用于指示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.
}

答案 2 :(得分:1)

你应该

  1. 将每个URI特定逻辑移动到不同的servlet中。
  2. 使用Java Servlet规范中的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>
    ....
    
  3. 这会将路由逻辑推送到web.xml,每个servlet都会执行特定的工作。

答案 3 :(得分: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请求并通过if语句(正如您现在所做的那样)路由它们,当用户调用特定的uri时,它将被路由到相应的servlet类为了你。因此,调用uri /processuser会将调用路由到ProcessUserXml servlet类doGet方法(或doPost,如果已定义,那就是用户进行HTTP调用的方式)。

答案 4 :(得分:0)

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

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