我对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服务的资源。
答案 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)
你应该
使用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>
....
这会将路由逻辑推送到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,但对于像这样的基本用例,任何现代都应该没问题。首先进行设置可能会感觉很痛苦,但一旦配置开发,多更快 更易于维护。
编辑:我刚才注意到原来的问题是不要使用任何框架/库。我仍然坚持这个答案,尽管大多数时候这是一个坏主意。如果你真的需要那么你可以按照其他一些人的建议创建地图,但从长远来看它是不可维护的,所以尽可能避免它。