践53否值得,这仍取决于个人喜好。
我建议,只有当性能是一个很重要的问题,而且再没有更简单的解决方案时才采用这样的做法。
输出混合字节和字符实际上比想象得要容易。
例3-3 展示了如何使用Servlet-OutputStream及其组合方法writebyte和printlnString来混合输出类型。
例3-3:ValueObjectProxy.javaimport java.io.import java.sql.import java.util.Dateimport javax.servlet.import javax.servlet.http.public class AsciiResult extends HttpServlet public void doGetHttpServletRequest req HttpServletResponse resthrows ServletException IOException res.setContentTypequottext/htmlquotServletOutputStream out res.getOutputStream//ServletOutputStream 中包含println方法用以写字符串//println调用仅适用于单字节字符编码// 如果需要多字节,请确保在Content-Type(内容类型)中设置了字符集// 而且使用了相应的方法,例如,对于日语使用out.write.str.getBytesquotShift_JISquotout.printlnquotContent current as ofquotout.printlnnew Date.toString// 在此获取一个数据库结果集(ResultSet)try InputStream ascii resultSet.getAsciiStream1returnStreamascii outcatch SQLException e throw new ServletExceptionepublic static void returnStreamInputStream in OutputStream outthrows FileNotFoundException IOException byte buf new byte4 1024 //4K 缓冲区int bytesRead54 第三章while bytesRead in.readbuf -1 out.writebuf 0 bytesRead尽管混合字节与字符将带来性能的大幅提升,因为字节可直接传输,我仍建议你少用这种技术,因为这不仅会让读者感到混乱,而且如果你对字符集如何工作并没有搞得滚瓜烂熟,那么就很容易导致错误。
如果还需要ASCII 字符集以外的字符,就要确保你明白自己要做什么。
初学者不要尝试向输出流写非ASCII 字符。
从类路径加载配置文件从Servlet API 1.0 到Servlet API 2.3,Servlet 显然一直缺少一种获取外部配置文件的标准机制。
尽管许多服务器端库需要配置文件,但Servlet 却没有一种大家公认的定位配置文件的方法。
Servlet 在J2EE 下运行时,可得到对JNDI 的支持,而后者可以提供一定的配置信息。
不过,常见的Web服务器配置文件问题仍然存在。
最好的解决方案(我也许应当称之为“危害最小的”解决方案)是利用查找类路径和(或)资源路径定位文件。
这要求服务器管理人员将服务器端配置文件置于Web 服务器的类路径中,或者将每个应用的配置文件置于从资源路径找到的WEB-INF/classes 中。
对于定位置于WAR文件中的配置文件以及(或者)定位已部署在多个后台Servlet 容器上的配置文件,此方法同样有效。
实际上,即便可以使用JNDI,使用用于配置的文件仍有诸多好处。
一个配置文件可以在整个服务器上都有效。
而且最后一点,配置文件对于开发和部署人员都很容易理解。
例3-4 展示了利用一个名为Resource 的类的查找技术。
给定一个资源名,Resource构造函数将搜索类路径和资源路径以定位资源。
一旦找到资源,则资源内容以及其目录位置和最后修改时间均可用(如果可以得到这些信息的话)。
最后修改时间有助于应用了解一些信息,例如,何时再次加载配置数据。
此类使用了特残代码将file:URL 资源转换为File对象。
这的确很方便,因为URL(甚至file:URL)通常并不提供诸如修改时间等特殊特性。
通过查找类路径和资源路径,该类则可以找到服务器端资源和各个应用的资源。
此类的源代码还可以从http://www. servlets.com 下载。
Servlet 最佳实践55例3-4:一个标准Resource 定位器import java.io.import java.net.import java.util./ 用于定位资源、获取其内容并确定其最后修改时间的类。
为了找到资源,此类首先查找CLASSPATH, 然后再执行Resource.class.getResourcequot/quotname。
如果Resource 找到了一个“file:”URL,则此文件路径将被当作一个file 处理。
否则,此路径将被作为一个URL 处理并且最后修改信息有限。
/public class Resource implements Serializable private String nameprivate File fileprivate URL urlpublic ResourceString name throws IOException this.name nameSecurityException exception nulltry // 使用CLASSPATH 查找。
如果找到,设置“file”,并且调用返回true。
// 可能会出现一个SecurityException 异常。
if tryClasspathname returncatch SecurityException e exception e // 保存留用try // 使用classloader getResource查找。
如果作为文件找到,// 则设置“file”;如果作为URL 找到,则设置“url”if tryLoadername returncatch SecurityException e exception e // 保存留用// 如果到此,说明存在问题,报告异常。
String msg quotquot56 第三章if exception null msg quot: quot exceptionthrow new IOExceptionquotResource quot name quot could not be found in quot quotthe CLASSPATH quot System.getPropertyquotjava.class.pathquot quot nor could it be located by the classloader responsible for the quot quotweb application WEB-INF/classesquot msg/ 返回传递给构造函数的资源名/public String getName return name/ 返回一个输入流以读取资源内容/public InputStream getInputStream throws IOException if file null return new BufferedInputStreamnew FileInputStreamfileelse if url null return new BufferedInputStreamurl.openStreamreturn null/ 若此资源为最后修改的,则返回。
如果发现资源使用了一个URL, 那么仅当URL 连接支持最后修改信息时此方法才可正常工作。
如果不支持,将返回long.MAX_VALUE。
也许这应当返回-1,不过基于以下假设应当返回MAX_V.
上一篇:
VC++的路径选择
下一篇:
首鼠两端