在Servlet应用中用XML实现数据包装和用XSLT解析数据
今天写了一个小的网络应用程序:一个简单的登陆界面(html),输入用户的名称和邮箱。然后可以点击提交。提交后的界面为一个欢迎界面—显示用户的名称和邮箱。这个实现过程不涉及数据库的访问。
下面谈谈我的实现思想。
1. 从登陆界面得到用户输入的数据,构造一个javax.servlet.Filter的子类来处理(封装)得到数据,用org.w3c.dom包中的Document实例(DOM)来包装这些数据,并把这些数据放到HttpSession的实例中
2. 在LoginServlet(javax.servlet.http.Servlet的子类)中用事先写好的XSLT文件来解析HttpSession实例中的Document对象(DOM),并把解析结果发到response.getWriter()中,用户看到将是原来的窗口转换成登陆成功的窗口,显示用户刚才输入的信息。
这是一个结合Servlet中Filter,以及XML和XSLT的一个例子。
如下为代码:
Index.html
<html>
<head>
<title>Login - FilterTest</title>
</head>
<body>
<h1>Input your ID and Email</h1>
<hr/>
<form action="/login" method="post">
<table>
<tr>
<td>Name:</td>
<td>
<input name="Name" type="text"/>
</td>
</tr>
<tr>
<td>Email:</td>
<td>
<input name="Email" type="text"/>
</td>
</tr>
<tr>
<td/>
<td>
<input name="Submit" type="submit" value="Save"/>
</td>
</tr>
</table>
</form>
</body>
</html>
InfoFilter.java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
public class InfoFilter implements Filter
{
private FilterConfig fconfig = null;
public InfoFilter(){
}
public void init(FilterConfig fc)throws ServletException{
fconfig = fc;
}
public void destroy(){
fconfig = null;
}
public void doFilter(final ServletRequest request,
final ServletResponse response, FilterChain chain)
throws IOException, ServletException{
HttpServletRequest httprequest = (HttpServletRequest)request;
Enumeration paramNames = httprequest.getParameterNames();
try{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbf.newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element info = doc.createElement("info");
doc.appendChild(info);
while(paramNames.hasMoreElements()){
String paramName = (String)paramNames.nextElement();
String paramValue = (String)(httprequest.getParameterValues(paramName)[0]);
Element elem = doc.createElement(paramName);
elem.appendChild(doc.createTextNode(paramValue));
info.appendChild(elem);
}
HttpSession session = httprequest.getSession(true);
session.setAttribute("doc", doc);
chain.doFilter(httprequest,response);
}catch(ParserConfigurationException e){
PrintWriter pw = response.getWriter();
pw.println("<html><head><title>Error</title></head>");
pw.println("<body><h1>Error happened in Building DOMTree<h1></body></html>");
}
}
}
LoginServlet.java
import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
public class LoginServlet extends HttpServlet
{
protected void doPost(HttpServletRequest request, HttpServletResponse response){
HttpSession session = request.getSession(true);
Document doc = (Document)session.getAttribute("doc");
try{
TransformerFactory transFact = TransformerFactory.newInstance();
String xsltName = "/WEB-INF/xslt/info.xslt";
URL url = getServletContext().getResource(xsltName);
String systemID = url.toExternalForm();
Templates infoTemplate = transFact.newTemplates(new StreamSource(systemID));
Transformer trans = infoTemplate.newTransformer();
response.setContentType("text/html");
PrintWriter pw = response.getWriter();
trans.transform(new DOMSource(doc), new StreamResult(pw));
session.invalidate();
}catch(Exception e){
e.printStackTrace();
session.invalidate();
}
}
}
Info.xslt
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:output method="xml" indent="yes" encoding="UTF-8"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<xsl:template match="/">
<html>
<head>
<title>
<xsl:text>Welcome,</xsl:text>
<xsl:value-of select="/info/Name"/>
</title>
</head>
<body>
<tr>
<h1>
<td><xsl:text>Welcome,</xsl:text></td>
<td><xsl:value-of select="/info/Name"/></td>
</h1>
</tr>
<hr/>
<tr>
<h3>
<td><xsl:text>Your Email is:</xsl:text></td>
<td><xsl:value-of select="/info/Email"/></td>
</h3>
</tr>
<hr/>
<tr>
<p align = "right" />
<a href="/index.html">Back to Homepage</a>
</tr>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<servlet>
<servlet-name>Login</servlet-name>
<servlet-class>LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<filter>
<filter-name>infoFilter</filter-name>
<filter-class>InfoFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>infoFilter</filter-name>
<url-pattern>/login</url-pattern>
</filter-mapping>
</web-app>
部署:
Index.html
src
InfoFilter.java
LoginServlet.java
WEB-INF
web.xml
classes
InfoFilter.class
LoginServlet.class
xslt
info.xslt
后记:在调试的时候,发现了一个问题,web.xml在一个web应用中的作用非常的大。在写代码的时候,把<filter-mapping>中把其中的<filter-name>中的内容误写作”infoFilter>”结果在浏览器中调用index.html就不可访问。可见Tomcat在实现一个web应用中对web.xml要求是很严格的。如果在调试这种程序应用中出现404错误,不妨仔细检查一下web.xml文件。