在构建简单Java应用程序系列的第二部分,我们将可以看到如何使用servlets 构建web-enable apps。
以前,我们构建了一个基于JDBM的简单Swing程序管理一系列的工作。现在我们开始构建Web激活应用程序的第一步,并且将给出工作报告。
现在,我们不加渲染的处理这件事情。所有必须的东西仅仅是打开套接字侦听等待“获得”页面的请求,然后产生一个HTML回应页面,接着发送响应页面并且关闭套接字。基本上,这不是HTTP服务器处理的所有内容。但这并不是处理事情的很好途径,毕竟生命短暂禁不起折腾,写很多重复代码很浪费。
嵌入一个HTTP服务器和servlet容器是很容易的,可以让他们来管理连接事物。所需要写的就是为servlet写处理请求的代码和回应代码。当人们谈论servlet时,他们谈论最多最详细的部分是HTTPServlet,它是专门产生HTTP请求处理HTTP请求的servlet。
Servlet是个可以缩减响应请求过程的接口。servlet通过ServletConfig的ini方法进行初始化。而请求则由service方法进行处理,service方法是ServletResponse和ServletRequest的一个参数,这两个函数一个用于读请求,而另一个用于写响应。当不再需要servlet时,可以通过管理servlet的容器调用destroy方法进行处理。容器提供了ServletConfig到ini的很多方法,并且为每一个用于查询的servlet维护ServletContext。
GenericServlet类实现servlet接口,添加必须的执行字节。它也添加init和log方法的无参数版本信息,所以可以产生由servlet容器处理的登录信息。HTTPServlet是GenericServlet的一个抽象子类,专门用于处理HTTP协议。它能接受HTTP请求,如GET, POST, PUT或DELETE等请求,并且将它们分派给doGet, doPost, doPut和doDelete方法。下面是一个扩展的用于创建我们自己servlet的HTTPServlet,这里是我们命名为report 的servlet的声明。
public class Report extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
现在,servlet首先要做的事情是访问Tasks。如此,我们假设它已经进行了初始化,并且在servlet的ServletContext中为它保存了一个名为“tasks”的参考。现在我们获得servlet的内容,稍后再保存值:
ServletContext sc=getServletContext();
一旦我们获得这个内容,则可以通过查询其指定的属性找到Tasks。
Tasks tasks=(Tasks)sc.getAttribute("tasks");
现在我们转移到HTML上。HTTPServletResponse对象给出Writer实例让我们写输出的结果,如果得到这个,则可以用下面的语句写HTML回应。
PrintWriter writer=resp.getWriter();
writer.write("<HTML><HEAD><TITLE>All Tasks</TITLE></HEAD>");
writer.write("<BODY><H1>All Tasks</H1>");
writer.write("<TABLE><TR>");
writer.write("<TH>Name</TH><TH>Priority</TH><TH>Done%</TH>");
writer.write("<TH>Due Date</TH><TH>Completed</TH>");
writer.write("</TR>");
现在我们可以反复迭代工作id号写出Task数据。
List<Long> taskids=tasks.getTaskIds();
for(Long l:taskids) {
Task t=tasks.getTask(l);
writer.write("<TR>");
writer.write("<TD>"+format(t.getName())+"</TD>");
...
writer.write("</TR>");
}
在添加HTML输出值之前,我们使用了简单的格式化方法。这个很简单但是可以确保字符串适当溢出。例如,如果一个工作命名为“Wait for order > 500K”,我们将其直接添加到HTML时,HTML将会认为“>”是解释语句的结束符。应用程序要确保“<”“>”替换成“<”和“>”还有其他内容也需要转化。下面是格式化方法:
private static SimpleDateFormat sdf=new SimpleDateFormat("d/M/y");
private static String format(Object o) {
if(o==null) return "";
if(o instanceof Date) return sdf.format(o);
return org.apache.commons.lang.StringEscapeUtils.escapeHtml(o.toString());
}
如果通过空值,则返回空字符串;如果通过数字,则会进行格式化并且返回它。另外,我们保存了很多关于调用StringEscapeUtils类及其escapeHTML方法的很多信息,StringEscapeUtils类是Jakarta Commons commons-lang 包的一部分;StringEscapeUtils包含了HTML, Java, JavaScript, SQL 和 XML的处理溢出和非溢出字符串方法,并且包含了保存手工处理溢出代码时间的方法。
回到doGet方法,我们所要做的是包装HTML和关闭复写器。
writer.write("</TABLE></BODY></HTML>");
writer.close();
}
这是个很简单的servlet,我们将它保存在com.builder.uk.todotasks.servlets包中。