Предотвращение бесконечного цикла в отображении сервлета JSP - PullRequest
1 голос
/ 14 апреля 2011

У меня есть эта проблема, недавно я прочитал об архитектуре REST , и она имеет смысл, поэтому я хотел бы создать веб-приложение RESTful.

Теперь я следую шаблону Front Controller , что означает, что все сопоставления URL-адресов идут в сервлет controller.java, я сопоставляю их по определенным URL-адресам, а не /* подстановочный знак, контроллер реализует четыре HTTP-метода POST, GET, PUT, DELETE, каждый метод вызывает метод контроллера service, и там я определяю на основе HttpServletRequest и pathInfoдействие для выполнения.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/*, он сопоставлен с сервлетом контроллера, действие выполнено, и я загружаю соответствующийпорядок, в котором действие возвращает View.java класс


//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 and INCLUDE запрос повторно запускается по URL и так далее, и так далее, и я никогда не достигну order_details.jsp, который отображает данные.

Итак, как бы вы избежали зацикливания, как я?Я хотел бы сохранить URI, отображающий номер заказа. Я использую метод forward, также я хотел бы сделать это с помощью сервлетов, я слышал о UrlRewriteFilter, возможно, в будущем, но сейчас, какбудет ли это сделано с помощью «Обычной ванили», так как я использую шаблон Front Controller, будет ли необходимо добавить дополнительный сервлет в /orders/ URI?

Любая помощь или идеи действительно приветствуются.


РЕДАКТИРОВАТЬ 1:

Вставил исходный код контроллера, очень простой, у меня есть подозрения, что метод service вызывает всепереопределенного do[Method] сервлета запускает цикл, и его можно решить, разделив их.

1 Ответ

2 голосов
/ 15 апреля 2011

Реализация интерфейса RESTful HTTP в Java намного проще с использованием реализации JAX-RS, такой как RESTEasy или Джерси .

Использование Front Controller для отправки запросов к нужному ресурсу является хорошим подходом, именно таким подходом пользуются эти платформы JAX-RS. Я боюсь, что вы, возможно, заново изобретаете колесо, написав сделанный на заказ механизм парсинга и отправки URL-адресов, когда его можно будет взять в продаже.

JAX-RS - это легкий способ раскрыть ресурсы. Используя несколько простых аннотаций, вы можете предоставить интерфейс REST без необходимости подключения к сети. Например:

* * 1010

Вы можете видеть, как просто прикрепить этот класс к URL-пути (используя аннотацию @Path), и как легко вы можете анализировать значения из URL, используя @PathParam. Поскольку вы получаете все необходимые сантехнические / диспетчеризирующие / анализирующие материалы, вы можете сосредоточиться на битах вашего приложения, специфичных для вашего домена (например, в том, что содержится в заказе).

...