2009-08-16 2 views
15

Я пытаюсь создать веб-интерфейс для приложения Java. Пользовательский интерфейс будет очень простым, состоящим из одной страницы с формой для представления пользователями своих запросов и страницы результатов - вроде поисковой системы Google или Ask.com.Веб-интерфейс пользователя для Java-приложения

Я знаком с базовым API Java, но у меня нет большого опыта использования Java для веб-сред (хотя я и использовал ASP.NET), поэтому я ищу несколько советов:

  • Что веб-сервер приложений я должен использовать? Обратите внимание, что мой интерфейс очень легкий, и я просто хочу что-то быстрое, легко начать/перезагрузить/остановить и (повторно) развернуть мое приложение. Кроме того, мне нужно, чтобы он работал на нескольких средах, а именно GNU/Linux, Mac OS X и Windows XP/Vista. Кроме того, я использую ant и Eclipse, поэтому было бы здорово, если бы я мог легко добавить целые ant цели для управления сервером и/или управлять сервером с помощью IDE. Я просмотрел Tomcat и Jetty, и последний кажется очень легким и простым в установке и развертывании. Это идеально, потому что GUI предназначен только для демонстрационных целей, и мне, вероятно, придется развернуть его на разных компьютерах. Тем не менее, Tomcat существует очень долго, и он кажется более зрелым.

  • Что касается веб-страниц, Java Server Pages выглядеть хорошо подходят, так как они кажутся достаточно простыми для того, что я пытаюсь выполнить (обработки формы и вывода результата), но я все уши для предложений.

  • У меня также есть другое требование, которое требует от меня объяснения «базового» рабочего процесса приложения: В принципе, у меня есть класс Engine, который имеет способ run(String), который будет обрабатывать ввод пользователя и возвращать результаты для отображения. Этот класс является ядром приложения. Теперь я хотел бы создать экземпляр этого класса только один раз, так как он требует лота памяти и занимает очень много времени для запуска, поэтому я хотел бы создать его при запуске приложения/сервера , и сохраните эту ссылку для всего диапазона приложения (т. е. до тех пор, пока я не остановлю сервер). Затем для каждого пользовательского запроса я просто вызываю метод run экземпляра Engine и покажу его результаты. Как это можно сделать на Java?

ответ

10
  1. App Server.Вы видите, что Tomcat тяжелый с точки зрения времени выполнения, или объема обучения или ...? Я бы предпочел выбрать что-то, что имеет хорошо установленную интеграцию с IDE. Таким образом, Eclipse + Tomcat или Apache Geronimo, возможно, в этом WebSphere Community Edition. Из того, что я видел, этого достаточно для того, чего вы хотите, и кривые обучения действительно довольно управляемы.
  2. Да JSPs. Вы еще можете обнаружить, что ваша презентация становится немного сложнее. Дополнительные усилия, связанные с поездкой в ​​JSF, могут все же окупиться - хорошие виджеты, такие как сборщики даты.
  3. В вашей обработке у вас будет сервлет (или класс действия, если вы используете JSF), этот класс может иметь переменную-член типа Engine, инициализированную при запуске, а затем использоваться для каждого запроса. Следует иметь в виду, что многие пользователи будут удалять этот сервлет и, следовательно, этот движок в одно и то же время. Является ли ваш движок безопасным для использования из нескольких потоков одновременно?

Расширение в этом пункте. При реализации JSP существует две модели, которые называются (с некоторой изобретательностью) как Модель 1 и Модель 2. См. this explanation.

В случае модели 1 вы склонны вводить код непосредственно в JSP, он действует в роли контроллера. Персоанли, даже когда речь идет о небольших, быстро разработанных приложениях, я не так. Я всегда использую модель 2. Однако, если вы выберете, вы можете просто поместить некоторую Java в свой JSP.

<% MyWorker theWorker = MyWorkerFactory.getWorker(); 
    // theWorker.work(); 
%> 

У меня есть такая фабрика, чтобы вы могли контролировать создание рабочего. Завод будет иметь что-то вроде (дать очень простой пример)

private static MyWorker s_worker = new MyWorker(); 
public static synchronized getWorker() { 
     return s_worker; 
} 

В качестве альтернативы вы можете создать рабочий, когда этот метод называется первым.

В случае модели 2 вы, естественно, есть сервлет, в который вы собираетесь поместить код, так что вы можете просто

private MyWorker m_worker = MyWorkerFactory.getWorker(); 

Это будет инициализирован, когда сервлет загружается. Не нужно беспокоиться о том, чтобы настроить загрузку при запуске, вы просто знаете, что он будет инициализирован до того, как будет запущен первый запрос. Еще лучше использовать метод init() сервлета. Это гарантирует, что вызывается до того, как будут обработаны какие-либо запросы, и является сервлет-сервером, предназначенным для такой работы.

public class EngineServlet extends HttpServlet { 

private Engine engine; 

// init is the "official" place for initialisation 
public void init(ServletConfig config) throws ServletException { 
    super.init(config); 
    engine = new Engine(); 
} 
+1

Спасибо за комментарии. 1) Тяжелый в том смысле, что, похоже, у него много функций, которые мне не нужны, и для его установки также требуется несколько дополнительных шагов. С другой стороны, из того, что я видел с Jetty, все, что нужно для запуска, - запустить java -jar start.jar. Также есть хороший проект Contrib, который позволяет мне запускать мое приложение, просто используя java -jar jetty-runner.jar application.war', что довольно круто, поскольку я хочу запустить веб-интерфейс для демонстрационных целей, на разных компьютерах , Тем не менее, Tomcat, похоже, имеет прочную репутацию, поэтому это сложный выбор. –

+0

2) Это действительно простой интерфейс для (довольно) сложного приложения, и я не думаю, что мне действительно нужны более продвинутые виджеты, но спасибо за предложение. В конце концов, мне нужно будет интегрировать некоторые API (такие как Карты Google) на странице результатов, но я, вероятно, просто закодирую javascript на странице JSP для этого. –

+0

3) Можете ли вы предоставить мне пример для этого, используя JSP? Из того, что я прочитал до сих пор, мне нужно «активировать» загрузку на загрузку конфигурации сервлета, чтобы она загружалась при запуске сервера. Но как именно я могу получить доступ к переменной-члену 'Engine' сервлета, изнутри JSP? В принципе, у меня есть страница 'A.jsp' с текстовым полем ввода, содержимое которого будет передано с помощью' GET' на страницу 'B.jsp'. На этой странице мне нужно получить экземпляр 'Engine', вызывать метод, используя содержимое строки запроса, и выводить результаты. –

0

Это довольно открытый вопрос, и существует огромное количество возможных ответов в зависимости от ваших требований. Стандарт способ писать веб-приложения - это использование платформы Java EE, что означает JSP, сервлеты и EJB для бизнес-логики. Однако существует немало популярных и актуальных альтернатив, таких как Spring, Seam, GWT и еще более радикальные альтернативы, такие как JRuby on Rails. Похоже, ваши потребности довольно просты, поэтому вы, вероятно, захотите пойти с простым решением, таким как Jetty + Servlets + JSP.

Я предполагаю, что ваш Двигатель может обрабатывать несколько одновременных запросов? Если нет, вы можете посмотреть, как найти способ запросов на очередь, например JMS.

1

Предполагая, что это не одноразовое приложение, которое не нуждается в каком-либо обновлении/обслуживание в будущем, я рекомендую вам сделать вид слой с Apache Wicket по следующим причинам (чтения короткий infoblurb с домашней страницы первыми):

  • Поскольку калитка отделяет вид слой и работает в модельном слое MVC в чистом виде, это можно легко объяснить, что точка зрения полностью отделена от остальной части приложения и Wicket's IModel interface используется для связывания данных с уровня контроллера с уровнем представления надежным способом. Таким образом, ваш уровень контроллера может быть одним одиночным приложением, если вы используете его таким образом.
  • Wicket-код потрясающе прост в обслуживании, а также расширить функциональность вашего веб-приложения можно очень легко, так как это OOP-структура вместо разметки, смешанная с другим видом разметки, которая выражает код.
+0

Спасибо за комментарии. Это кажется аккуратным, но мне просто нужно иметь «form => submit => process => показать результаты», поскольку это просто для демонстрационных целей приложения. –

3

Технология, которую вам нужно изучить, это спецификация сервлета Sun Java, поскольку это то, что реализует ВСЕ нетривиальные веб-серверы Java. Это позволяет вам писать сервлеты, которые могут выполнять все, что вам нужно на стороне сервера. Затем вы можете разработать против любого контейнера, хорошо работающего с вашим iDe, и развертывать на любом другом контейнере, хорошо работающем на производстве.

Вам также необходимо изучить базовый HTML, поскольку вам в противном случае понадобится изучить JavaServer Faces или подобное, что является довольно большим привкусом для создания кнопки отправки, которая вам нужна, с другими элементами в форме HTML.

Для работы вашего двигателя вы можете создать сервлет с singleton в web.xml, который вы можете вызвать. Будьте абсолютно уверены, что это потокобезопасно, иначе у вас будет много боли. Для начала вы можете объявить ваш вызывающий сервлет синхронизированным, чтобы гарантировать, что в любой момент активен не более одного вызова функции run().

+1

Спасибо за комментарии. Да, именно так я и думал. Моя цель - иметь легкий контейнер, где я могу легко развернуть приложение для демонстрационных целей. Тем не менее, в конечном итоге мне может понадобиться разместить приложение на постоянной основе, возможно, используя другой контейнер. Я знаю HTML и другие веб-технологии (CSS/Javascript и т. Д.), Поскольку я использовал их раньше с ASP.NET. Тем не менее, я новичок в разработке веб-приложений на Java. –

+1

Какой контейнер почти не имеет значения, если вы пишете соответствующее веб-приложение Java. У Tomcat обычно есть отличная поддержка IDE, которая неоценима при разработке. Прямо сейчас, я сожалею, что у вас есть чему поучиться :-) –

+1

Да, я знаю, я читал некоторые статьи по этому вопросу, не нужно сожалеть;). Кроме того, если вы можете, прокомментируйте код, который я добавил в вопрос. –

0
  1. сервер приложений:
  2. кот
  3. веб-страница: JSP
  4. Вам нужен класс, который Singleton или класс со статическим методом. Осторожно: Остерегайтесь состояния гонки. Возможно, вам потребуется использовать синхронизированное ключевое слово для этих методов, связанных с операцией обновления/изменения.
+0

Вы должны окончательно разрешить веб-контейнеру знать и управлять небезопасным сервлетом. Synchhonized позволяет JVM делать это вместо этого, что может привести к невосприимчивому веб-контейнеру. –

1
  1. Jetty очень легкий контейнер, и идеально подходит для вашего сценария развития.

  2. Возможно, вам стоит взглянуть на Wicket для вашей стороны рендеринга; вам кажется, что вам удобнее делать кодовые задачи, а не прямой пользовательский интерфейс.

  3. Образец, который вы описываете, - это шаблон Singleton. Взгляните на результаты Google для singleton in java.

3

EDIT: До сих пор, я решил на следующее:

  • Web Application Server: Jetty;
  • Страницы сервера Java для просмотров;
  • Основываясь на предложениях @djna, я прочитал пару статей, касающихся Model 2, и я придумал это решение (которое я еще не тестировал, потому что мне нужно закончить свое приложение перед перемещением в интерфейс):

form.jsp

<form action="/servlet/EngineServlet" method="GET"> 
    <input type="text" name="text" /> 
</form> 

EngineServlet.java

public class EngineServlet extends HttpServlet { 
    private Engine engine = new Engine(); 
    // does this make sure engine only gets instantiated one time in the entire lifespan of the web application; from what I've read from the servlet lifecycle, it seems like it, but I'd like to hear opinions 

    public void doGet(HttpServletRequest request, 
        HttpServletResponse response) { 
    String text = request.getParameter("text"); 
    ResultBean result = engine.run(text); 
    request.setAttribute("result", result); 
    RequestDispatcher dispatcher = request.getRequestDispatcher("result.jsp"); 
    dispatcher.forward(request, response); 
    // what's the difference between forward, and request.sendRedirect() ? 
    }  
} 

результат.JSP

<div>The result was: ${result.text}</div> 

Что вы думаете об этом решении? Любые проблемы, которые могут быть неочевидны для кого-то из фона J2SE? Я также написал некоторые сомнения, которые у меня есть в коде как комментарии. Благодарю.

+1

Инициализационный движок: «очиститель», если это сделано в методе init() сервлета, я внесла поправки в свой ответ, чтобы сказать это. Жизненный цикл сервлета обсуждается в http://www.j2ee.me/j2ee/tutorial/1_3-fcs/doc/Servlets4.html. Вы увидите, что в любой момент будет ровно один экземпляр класса сервлета, поэтому в вашем коде будет один экземпляр Engine ** за один раз **. Сервер приложений может решить завершить и перезапустить сервлет. Я никогда не видел, чтобы сервер приложений делал это, но, чтобы быть уверенным на 100%, ответственность за то, что он синглтон с движком. См. Следующий комментарий. – djna

+2

Возможно, что не более одного экземпляра двигателя.Или это может быть очень желательно с точки зрения потребления памяти. В любом случае я бы сказал, что вы не должны полагаться на клиента (сервлет в этом случае) на полицию, чтобы существовал один случай. Вместо этого используйте завод, как показано в моем ответе. Серлвет говорит: «Дайте мне двигатель», фабрика говорит «используйте это» и может взять на себя ответственность за то, чтобы использовать Singleton Engine. Это решение устойчиво к необычным событиям жизненного цикла сервлета, а также к будущему обслуживанию, что произойдет, если у вас есть два сервлета? – djna

+1

Вперед: сервлет выполняет некоторую работу, собирает некоторые данные и затем передает ** тот же ** запрос на JSP для рендеринга. Браузер видит URL сервлета. Перенаправление: сервлет отправляет ответ браузеру: «Не показывать это, вместо этого отправляйте запрос на ** эту ** страницу», другой URL-адрес. Вы используете последнее, когда исходный запрос выполнил некоторую работу, которую вы не хотите случайно повторять (например, заплатите немного денег). Отправляя переадресацию, история браузера может иметь последовательность запросов «GET», без каких-либо действий «POST», которые, если повторная отправка повторяют работу. – djna

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