避免JSP servlet映射中的无限循环 [英] Avoiding the endless loop in JSP servlet mapping
问题描述
我遇到了这个问题,最近我读到了关于 REST 建设的内容,完美的感觉,所以我想实现一个RESTful Web应用程序。
I've got this issue, recently I read about the REST arquitecture and it makes a perfect sense, so I'd like to achieve a RESTful web application.
现在,我正在关注前端控制器模式这意味着所有的URL映射都转到 controller.java
servlet,我按特定的URL映射,而不是使用 / *
通配符,
控制器实现四种HTTP方法 POST
, GET
, PUT
, DELETE
,每个方法调用控制器 service
方法,我根据 HttpServletRequest
和 pathInfo
确定要执行的操作。
Controller.java
Now, I'm following the Front Controller pattern that means that all of the URL mappings go to the controller.java
servlet, I map the by specific URLs, not by using the /*
wildcard,
the controller implements the four HTTP methods POST
,GET
,PUT
,DELETE
, each method calls the controllers service
method and there I determine based on the HttpServletRequest
and pathInfo
the action to execute.
Controller.java
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
IAction action;
View view;
try {
action = ActionFactory.produceAction(req);
view = action.execute(req, resp);
switch (view.getDispatchMethod()) {
case REDIRECT:
resp.sendRedirect(resp.encodeURL(view.getResource()));
break;
case FORWARD:
req.getRequestDispatcher(view.getResource()).forward(req, resp);
break;
case INCLUDE:
req.getRequestDispatcher(view.getResource()).include(req,resp);
break;
default:
}
} catch (ActionFailedException uae) {
req.setAttribute("ActionName", "Action");
req.setAttribute("FailCause", uae.getMessage());
req.getRequestDispatcher(VIEW_FAIL.getResource()).forward(req, resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.service(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.service(req, resp);
}
@Override
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.service(req, resp);
}
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.service(req, resp);
}
我在通过URI加载特定订单时遇到了一个特定问题 / orders / *
,它被映射到控制器servlet,执行动作并且我加载了相应的命令,动作返回 View.java
class
I've run into a particular issue when loading a specific order by the URI /orders/*
, it is mapped to the controller servlet, the the action is executed and I load the appropriate order the action returns a View.java
class
//ommited accessors and mutators for brevety.
public class View {
public enum DispatchMethod {
INCLUDE, FORWARD, REDIRECT
}
private DispatchMethod dispatchMethod;
private String resource;
public View(DispatchMethod dispatchMethod, String resource) {
this.dispatchMethod = dispatchMethod;
this.resource = resource;
}
}
然后根据 getDispatchMethod调度请求()
返回的视图。
现在,这是循环被触发的地方,我使用以下URL, myapp / orders / 78965
/ orders / *
被映射到 controller.java
执行适当的操作并通过 pathInfo()
找到正确的顺序。返回的视图是 new View(View.DispatchMethod.FORWARD,order_details。 jsp)
问题在于,使用三种可用的调度方法 REDIRECT,FORWARD和INCLUDE
在URL上重新触发请求,依此类推并且我永远不会到达呈现数据的 order_details.jsp
。
Now, here is where the loop gets triggered, I use the following URL, myapp/orders/78965
/orders/*
gets mapped to controller.java
the appropriate action is executed and the correct order is found by the pathInfo()
the returned view is new View(View.DispatchMethod.FORWARD,"order_details.jsp")
the problem is that with the three available dispatch methods REDIRECT,FORWARD and INCLUDE
a request is re-triggered on the URL and so on and on and on I never reach the order_details.jsp
that renders the data.
那么,你会如何避免循环,因为我想保留显示订单号的URI我使用forward方法,我也想用servlet来做,我听说过UrlRewriteFilter可能在futu re,但是现在,如果使用Plain Vanilla,我将如何使用Front Controller模式,是否有必要在 / orders / $ c中添加一个额外的servlet $ c> URI?
So, how would you avoid the looping, as I'd like to preserve the URI displaying the order number I use the forward method, also, I'd like to do it using servlets, I've heard of the UrlRewriteFilter maybe in the future, but right now, how would it be done using "Plain Vanilla" since I'm using the Front Controller pattern, will it be necessary to add an additional servlet in the /orders/
URI ?
真的很感激任何帮助或见解。
Any help or insights is truly appreciated.
编辑1:
粘贴控制器的源代码,非常基本的一个,我怀疑的方式是 service
方法调用servlet的所有覆盖 do [Method]
正在触发循环并且可以解决通过splittig它们。
Pasted the source code of the controller, a very basic one, I have my suspicions that the way the service
method calls all of the overriden do[Method]
of the servlet is triggering the loop and that it may be solved by splittig them.
推荐答案
使用前端控制器向正确的资源发送请求是一种很好的方法,它正好是ap这些JAX-RS框架采用的方法。我担心你可能会通过编写一个定制的URL解析和调度机制来重新发明轮子,这可以在现成的时候进行。
Using a Front Controller to dispatch requests to the right resource is a good approach, it's exactly the approach taken by these JAX-RS frameworks. I fear you may be re-inventing the wheel here by writing a bespoke URL parsing and dispatching mechanism when this can be taken off-the-shelf.
JAX-RS是一种轻量级的方式来公开资源。通过使用几个简单的注释,您可以暴露REST接口,而无需任何管道。例如:
JAX-RS is a lightweight way to expose resources. By using a couple of simple annotations you can expose a REST interface without any plumbing required. For example:
public class Order {
@GET
@Path("/orders/{orderId}")
@Produces("text/html")
public void getOrder(@Context HttpServletResponse response,
@Context HttpServletRequest request,
@PathParam("orderId") String orderId) throws ServletException, IOException {
// ... create view and add to request here
request.getRequestDispatcher("orders.jsp").forward(request, response);
}
}
你可以看到将此类附加到URL路径(使用 @Path
注释)是多么简单,以及使用从URL解析值的难易程度@PathParam
。由于您可以获得现成的所有管道/调度/解析,因此您可以专注于应用程序中特定于您的域的位(例如订单包含的内容)。
You can see how simple it is to attach this class to a URL path (using the @Path
annotation), and how easily you can parse values from the URL using @PathParam
. Since you get all the plumbing/dispatching/parsing off-the-shelf, you can concentrate on the bits of your app that are specific to your domain (such as what an order contains).
这篇关于避免JSP servlet映射中的无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!