2015-01-18 6 views
0

Я работаю над своим первым веб-проектом, используя tomcat, jsp, сервлеты и log4j, и у меня есть демонстрация использования шаблона проектирования Command, который меня интересует. У меня есть один контроллер, который принимает методы doGet и doPost, а затем выполняет запросы CommandContainer, который находит соответствующую команду, выполняет ее, получает путь к ресурсу и перенаправляет к нему клиента.Как реализовать командный шаблон с PRG в MVC?

public abstract class Command implements Serializable { 
    private static final long serialVersionUID = 8879403039606311780L; 
    public abstract String execute(HttpServletRequest request, HttpServletResponse response) 
      throws IOException, ServletException; 
} 

CommandContainer, который управляет командами:

public class CommandContainer { 
    private static final Logger LOG = Logger.getLogger(CommandContainer.class); 
    private static Map<String, Command> commands = new TreeMap<String, Command>(); 
    static { 
     // common commands 
     commands.put("login", new LoginCommand()); 
     commands.put("logout", new LogoutCommand()); 
     commands.put("viewSettings", new ViewSettingsCommand()); 
     commands.put("noCommand", new NoCommand()); 

     // client commands 
     commands.put("listMenu", new ListMenuCommand()); 

     // admin commands 
     commands.put("listOrders", new ListOrdersCommand()); 

     LOG.debug("Command container was successfully initialized"); 
     LOG.trace("Number of commands --> " + commands.size()); 
    } 

public static Command get(String commandName) { 
    if (commandName == null || !commands.containsKey(commandName)) { 
     LOG.trace("Command not found, name --> " + commandName); 
     return commands.get("noCommand"); 
    } 

    return commands.get(commandName); 
} 

Единственный контроллер у меня есть:

public class Controller extends HttpServlet { 

    private static final long serialVersionUID = 2423353715955164816L; 

    private static final Logger LOG = Logger.getLogger(Controller.class); 

    protected void doGet(HttpServletRequest request, 
      HttpServletResponse response) throws ServletException, IOException { 
     process(request, response); 
    } 

    protected void doPost(HttpServletRequest request, 
      HttpServletResponse response) throws ServletException, IOException { 
     process(request, response); 
    } 

    private void process(HttpServletRequest request, 
      HttpServletResponse response) throws IOException, ServletException { 

     LOG.debug("Controller starts"); 

     // extract command name from the request 
     String commandName = request.getParameter("command"); 
     LOG.trace("Request parameter: command --> " + commandName); 

     // obtain command object by its name 
     Command command = CommandContainer.get(commandName); 
     LOG.trace("Obtained command --> " + command); 

     // execute command and get forward address 
     String forward = command.execute(request, response); 
     LOG.trace("Forward address --> " + forward); 

     LOG.debug("Controller finished, now go to forward address --> " + forward); 

     // if the forward address is not null go to the address 
     if (forward != null) { 
      RequestDispatcher disp = request.getRequestDispatcher(forward); 
      disp.forward(request, response); 
     } 
    } 

} 

I'am с помощью контроллера в JSP следующим способом:

... 
    <form id="login_form" action="controller" method="post"> 
        <input type="hidden" name="command" value="login"/> 
... 
    </form> 

И файл web.xml:

<servlet> 
    <servlet-name>Controller</servlet-name> 
    <servlet-class>com.mycompany.web.Controller</servlet-class> 
</servlet> 

<servlet-mapping> 
    <servlet-name>Controller</servlet-name> 
    <url-pattern>/controller</url-pattern> 
</servlet-mapping> 

Я не понимаю, как реализовать Post-Redirect-Get шаблон с команда, потому что запрос каждый раз, когда приходит к контроллеру он использует process() метод и кажется, что это не имеет значения GET или POST используется в JSP. И тогда вы бы поняли необходимость использования шаблона Command? Что делать, если я буду использовать несколько сервлетов, таких как LoginServlet, LogoutServlet, ViewSettingsServlet вместо одного контроллера. Это будет плохая идея, потому что тогда мне нужно жестко закодировать их в jsp-формах как действия? Все это меня просто путает, потому что я стартер, поэтому, пожалуйста, напиши мне все это.

ответ

1

Ну, в настоящее время ваша команда возвращает строку: имя JSP для пересылки. Если я правильно понимаю, вы также захотите перенаправить, а не переадресовывать. Поэтому вам нужно отправить сервлет, что возвращаемое значение, если не имя представления для пересылки, а URL для перенаправления.

Существуют различные способы сделать это. Например, вы можете вернуть объект, содержащий тип действия (FORWARD или REDIRECT), а также имя или URL-адрес представления. Или вы можете вернуть String как redirect:/foo/bar, что означает, что/foo/bar - это URL-адрес для перенаправления, а не имя представления.

Но лучшее решение, вероятно, позволит избежать повторного использования колеса и использовать существующую инфраструктуру MVC, а не использовать ее самостоятельно: Spring MVC, Stripes, Struts и т. Д. Обеспечивают гораздо больше, чем то, что у вас есть, и в гораздо лучше. В частности, использование параметра запроса для выбора команды - не очень хороший выбор. Использование пути - гораздо лучшая идея.

Вы также можете просто использовать несколько сервлетов, которые были бы лучше, чем ваше текущее решение. Однако вы потеряете фронт-контроллер, который обычно содержит код, который является общим для всех команд: интернационализация, проверки безопасности и т. Д.

+0

Случалось, что мне нужно интернационализировать мой проект, поэтому, если бы это было бы хорошим решением, если бы было несколько контроллеров (и, как вы сказали, я теряю переднюю часть), и я буду использовать библиотеку JSTL способом, предоставленным в ответ на этот вопрос: http://stackoverflow.com/questions/4276061/how-to-internationalize-a-java-web -заявление ? – marknorkin

+0

Потеря фронтального контроллера не очень хорошая вещь. Вот почему я предлагаю использовать реальную структуру MVC, а не использовать свои собственные. –

+0

Вы бы объяснили, почему это важно? может дать мне полезную ссылку – marknorkin

 Смежные вопросы

  • Нет связанных вопросов^_^