Java 应用程序的 Web 用户界面
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1283468/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Web User Interface for a Java application
提问by Jo?o Silva
I'm trying to create a web user interface for a Java application. The user interface is going to be very simple, consisting of a single page with a form for users to pose their queries, and a results page -- sort of like Google's search engine or Ask.com.
我正在尝试为 Java 应用程序创建 Web 用户界面。用户界面将非常简单,由一个页面组成,其中包含一个供用户提出查询的表单和一个结果页面——有点像 Google 的搜索引擎或 Ask.com。
I'm quite familiar with the base API of Java, but I don't have much experience in using Java for Web environments (though I've used ASP.NET), so I'm looking for some advice:
我对 Java 的基本 API 非常熟悉,但我在 Web 环境中使用 Java 的经验并不多(虽然我使用过 ASP.NET),所以我正在寻找一些建议:
What web application servershould I use?Note that my interface is very light, and I just want something that is fast, easy to start/reset/stop and (re)deploy my application. Also, I need it to work on multiple environments, namely, GNU/Linux, Mac OS X, and Windows XP/Vista. Additionally, I'm using
ant
andEclipse
, so it would be great if I could easily add someant
targets for server management, and/or manage the server using the IDE. I've looked into Tomcatand Jetty, and the latter seems to be very light and easy to install and deploy. This is ideal, because the GUI is just for demonstration purposes, and I'll probably need to deploy it in different computers. However, Tomcat has been around for a very long time, and it seems more mature.As for the web pages, Java Server Pages look like a good fit, as they seem sufficiently simple for what I'm trying to accomplish (processing a form and outputting the result), but I'm all ears for suggestions.
- I also have another requirement, which requires me to explain the "basic" workflow of the application: Basically, I have a class
Engine
which has a methodrun(String)
which will process the user's input and return the results for display. This class is the coreof the application. Now, I'd like to instantiatethis class only once, as it requires a lotof memory, and takes a very long time to startup, so I'd like to create it when the application/server starts, and store that reference for the entire span of the application (i.e., until I stop the server). Then, for each user request, I'd simply invoke therun
method of theEngine
instance, and display its results. How can this be accomplished in Java?
我应该使用什么Web 应用程序服务器?请注意,我的界面非常轻巧,我只想要快速、易于启动/重置/停止和(重新)部署我的应用程序的东西。此外,我需要它在多种环境下工作,即 GNU/Linux、Mac OS X 和 Windows XP/Vista。此外,我正在使用
ant
andEclipse
,因此如果我可以轻松添加一些ant
用于服务器管理的目标和/或使用 IDE 管理服务器,那就太好了。我研究了Tomcat和Jetty,而后者似乎很轻巧,易于安装和部署。这是理想的,因为 GUI 仅用于演示目的,我可能需要在不同的计算机上部署它。不过Tomcat已经存在很长时间了,而且看起来更加成熟了。至于网页,Java Server Pages 看起来很合适,因为它们对于我想要完成的工作(处理表单并输出结果)来说似乎足够简单,但我非常愿意听取建议。
- 我还有另一个需求,它需要我解释应用程序的“基本”工作流程:基本上,我有一个类
Engine
,它有一个方法run(String)
来处理用户的输入并返回结果以供显示。这个类是应用程序的核心。现在,我只想实例化这个类一次,因为它需要大量内存,并且需要很长时间才能启动,所以我想在应用程序/服务器启动时创建它,并将该引用存储在应用程序的整个范围(即,直到我停止服务器)。然后,对于每个用户请求,我只需调用实例的run
方法Engine
,并显示其结果。这如何在 Java 中实现?
采纳答案by djna
- App Server. You see Tomcat as heavy in terms of runtime footprint, or amount of learning or ...? I would tend to chose something that has well established integration with an IDE. So Eclipse + Tomcat or Apache Geronimo, perhaps in it's WebSphere Community Editionguise would do the job. From what I've seen these are sufficient for what you want, and the learning curves are really pretty manageable.
- Yes JSPs. You may yet find that your presentation needs become a tad more complex. The extra effort of going to JSF might yet pay off - nice widgets such as Date pickers.
- In your processing you will have a servlet (or an action class if you're using JSF) that class can have a member variable of type Engine initialised on startup and then used for every request. The thing to bear in mind is that many users will hit that servlet, and hence that engine at the same time. Is your Engine safe to be used from more than one thread at the same time?
- 应用服务器。您认为 Tomcat 在运行时占用空间、学习量或……方面很重吗?我倾向于选择与 IDE 建立良好集成的东西。所以 Eclipse + Tomcat 或 Apache Geronimo,也许打着WebSphere Community Edition 的幌子可以完成这项工作。从我所见,这些足以满足您的需求,而且学习曲线非常易于管理。
- 是的 JSP。您可能还会发现您的演示需求变得更加复杂。转到 JSF 的额外努力可能会得到回报 - 不错的小部件,例如日期选择器。
- 在您的处理过程中,您将拥有一个 servlet(或一个动作类,如果您使用的是 JSF),该类可以拥有一个在启动时初始化的 Engine 类型的成员变量,然后用于每个请求。需要记住的是,许多用户会同时访问该 servlet,从而访问该引擎。同时从多个线程使用您的引擎是否安全?
To expand in this point. When implementing JSPs, there are two models refered to as (with some inventiveness) as Model 1 and Model 2. See this explanation.
在这一点上展开。在实现 JSP 时,有两个模型被称为(具有一些创造性)模型 1 和模型 2。请参阅此说明。
In the case of model 1 you tend to put code directly into the JSP, it's acting in a controller role. Persoanlly, even when dealing with small, quickly developed apps, I do not so this. I always use Model 2. However if you choose you can just put some Java into your JSP.
在模型 1 的情况下,您倾向于将代码直接放入 JSP,它充当控制器角色。就个人而言,即使在处理小型、快速开发的应用程序时,我也不会这样做。我总是使用模型 2。但是,如果您选择,您可以将一些 Java 放入您的 JSP。
<% MyWorker theWorker = MyWorkerFactory.getWorker();
// theWorker.work();
%>
I woudl favour having a factory like this so that you can control the creation of the worker. The factory would have something like (to give a really simple example)
我喜欢拥有这样的工厂,以便您可以控制工人的创建。工厂会有类似的东西(举一个非常简单的例子)
private static MyWorker s_worker = new MyWorker();
public static synchronized getWorker() {
return s_worker;
}
Alternatively you could create the worker when that method is first called.
或者,您可以在第一次调用该方法时创建工作程序。
In the case of model 2 you naturally have a servlet into which you are going to put some code, so you can just have
在模型 2 的情况下,您自然会有一个 servlet,您将在其中放置一些代码,因此您可以拥有
private MyWorker m_worker = MyWorkerFactory.getWorker();
This will be initialised when the servlet is loaded. No need to worry about setting it to load on startup, you just know that it will be initialsed before the first request is run. Better still, use the init() method of the servlet. This is guranteed to be called before any requests are processed and is the servlet API architected place for such work.
这将在加载 servlet 时初始化。无需担心将其设置为在启动时加载,您只需知道它将在第一个请求运行之前进行初始化。更好的是,使用 servlet 的 init() 方法。保证在处理任何请求之前调用它,并且是用于此类工作的 servlet API 架构位置。
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();
}
回答by Ken Liu
This is a pretty open ended question, and there are a huge number of possible answers depending on your requirements. The standardway to write web applications is using the Java EE platform, which means JSPs, servlets, and EJBs for the business logic. However, there are quite a few popular and valid alternatives such as Spring, Seam, GWT, and even more radical alternatives such as JRuby on Rails. It sounds like your needs are pretty straightforward so you probably want to go with a simple solution like Jetty + Servlets + JSP.
这是一个非常开放的问题,根据您的要求,有大量可能的答案。编写 Web 应用程序的标准方法是使用 Java EE 平台,这意味着业务逻辑使用 JSP、servlet 和 EJB。但是,有很多流行且有效的替代方案,例如 Spring、Seam、GWT,甚至还有更激进的替代方案,例如 JRuby on Rails。听起来您的需求非常简单,因此您可能想要使用简单的解决方案,例如 Jetty + Servlets + JSP。
I am assuming your Engine can handle multiple simultaneous requests? If not, you may want to look at figuring out a way to queue requests, such as JMS.
我假设您的引擎可以同时处理多个请求?如果没有,您可能需要考虑找出一种对请求进行排队的方法,例如 JMS。
回答by Esko
Assuming this isn't a one-off application which doesn't need any kind of updating/maintenance in the future, I'd recommend you do the view layer with Apache Wicketfor the following reasons (read the short infoblurb from the homepage first):
假设这不是一个一次性的应用程序,将来不需要任何类型的更新/维护,我建议您使用Apache Wicket做视图层,原因如下(首先阅读主页上的简短信息模糊):
- Since Wicket separates the view layer and works in the model layer of MVC in a clean way, it can be easily explained that view is completely separated from rest of the application and Wicket's IModel interfaceis used to link the data from controller layer to the view layer in a reliable way. Thus your controller layer maybe a single application singleton as long as you use it that way.
- Wicket code is stunningly easy to maintain, also extending functionality of your web application can be done very easily since it's OOP framework instead of markup mixed with other kind of markup which expresses code.
- 由于 Wicket 将视图层分离,并以干净的方式在 MVC 的模型层中工作,因此可以很容易地解释,视图与应用程序的其余部分完全分离,并且使用 Wicket 的IModel 接口将数据从控制器层链接到视图以可靠的方式分层。因此,只要您以这种方式使用它,您的控制器层就可能是单个应用程序单例。
- Wicket 代码非常容易维护,而且扩展 Web 应用程序的功能也很容易,因为它是 OOP 框架,而不是与其他类型的表示代码的标记混合的标记。
回答by Thorbj?rn Ravn Andersen
The technology you need to learn is the Sun Java Servlet specification since that is what ALL non-trivial java webservers implement. This enables you to write servlets which can do all the things you need server side. You can then develop against any container working well with your iDe, and deploy on any other container working well in production.
您需要学习的技术是 Sun Java Servlet 规范,因为这是所有非平凡的 java web 服务器实现的。这使您能够编写可以在服务器端完成您需要的所有事情的 servlet。然后,您可以针对与您的 iDe 配合良好的任何容器进行开发,并在生产中运行良好的任何其他容器上进行部署。
You also need to learn basic HTML as you otherwise would need to learn JavaServer Faces or similar which is a rather big mouthfull to create the submit button you need with the other entries in a HTML form.
您还需要学习基本的 HTML,否则您将需要学习 JavaServer Faces 或类似的东西,这是一个相当大的内容,可以用 HTML 表单中的其他条目创建您需要的提交按钮。
For your Engine to work you can create a servlet with a singleton in web.xml, which you can then call. Be absolutely certain it is thread safe otherwise you will have a lot of pain. For starters you can declare your invoking servlet synchronized to ensure that at most one call of run() is active at any time.
为了让您的引擎工作,您可以在 web.xml 中创建一个带有单例的 servlet,然后您可以调用它。绝对确定它是线程安全的,否则你会很痛苦。对于初学者,您可以声明您的调用 servlet 是同步的,以确保在任何时候最多只有一个 run() 调用处于活动状态。
回答by janetsmith
- app server: tomcat
- web page: jsp
- You need a class which is Singleton or class with static method. Word of caution: Beware of race condition. You might need to use synchronizedkeyword for those methods involving update/modify operation.
- 应用服务器:tomcat
- 网页:jsp
- 您需要一个单例类或具有静态方法的类。警告:当心竞争条件。对于涉及更新/修改操作的方法,您可能需要使用synchronized关键字。
回答by joeslice
Jetty is a very lightweight container, and perfect for your development scenario.
You might want to look at Wicketfor your rendering side; you seem more comfortable doing code-like tasks as opposed to straight UI.
The pattern you are describing is the Singleton pattern. Take a look at the google results for singleton in java.
Jetty 是一个非常轻量级的容器,非常适合您的开发场景。
您可能希望在渲染方面查看Wicket;与直接 UI 相比,您似乎更愿意执行类似代码的任务。
您所描述的模式是单例模式。看看在 java 中单例的谷歌结果。
回答by Jo?o Silva
EDIT: So far, I've decided on the following:
编辑:到目前为止,我已经决定了以下内容:
- Web Application Server: Jetty;
- Java Server Pagesfor the views;
- Based on the suggestions of @djna, I've read a couple of articles regarding Model 2, and I came up with this solution (which I haven't tested yet, because I need to finish my application before moving into the interface):
- 网络应用服务器:Jetty;
- 视图的Java 服务器页面;
- 根据@djna 的建议,我阅读了几篇关于Model 2的文章,并提出了这个解决方案(我还没有测试过,因为我需要在进入界面之前完成我的应用程序):
form.jsp
表单.jsp
<form action="/servlet/EngineServlet" method="GET">
<input type="text" name="text" />
</form>
EngineServlet.java
引擎Servlet.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() ?
}
}
result.jsp
结果.jsp
<div>The result was: ${result.text}</div>
What do you think of this solution? Any problems that may not be obvious to someone coming from a J2SE background ? I also wrote some doubts that I have in the code as comments. Thanks.
你觉得这个解决方案怎么样?有没有对具有 J2SE 背景的人来说可能不明显的问题?我还写了一些我在代码中的疑问作为注释。谢谢。