| 
 | 
 
说明:以下所描述的环境是jdk1.5、tomcat5.5、 jsp2.0、 servlet2.4、JSTL1.1.2  
一、基本配置  
基本的重要的配置在web.xml 文件中。  
 
1、Jsp属性组  
<jsp-property-group>  
<url-pattern>/pages/*</url-pattern>  
<el-ignore>true</el-ignore>  
<page-encoding>UTF-8</page-encoding>  
<include-prelude>/include/header.jspf</include-prelude>  
<include-coda>/include/copyright.jspf</include-coda>  
</jsp-property-group>  
这个设置可以指定页面编码,页头页脚等等。  
设置 <page-encoding>UTF-8</page-encoding> 的好处是不用在每个页面像这样指定编码:<%@page c %>  
而设置 <include-prelude>/include/header.jspf</include-prelude> 使得每个页面都在头部包含header.jspf文件(通常把对标签的包含放在这里)。  
 
2、数据库资源的引用  
<resource-ref>  
<description>CourseDesign JDNI datasource</description>  
<res-ref-name>jdbc/test</res-ref-name>  
<res-type>javax.sql.DataSource</res-type>  
<res-auth>Container</res-auth>  
</resource-ref>  
前提是要在TOMCAT的中配置  
<Context path="/Course" docBase="Course" debug="0" crossc reloadable="true">  
<Resource name="jdbc/test" auth="Container" type="javax.sql.DataSource"  
maxActive="100" maxIdle="30" maxWait="10000"  
username="root" password="123456"  
driverClassName="com.mysql.jdbc.Driver"  
url="jdbc:mysql://localhost:3306/databaseName?useUnicode=true&characterEncoding=UTF-8" />  
</Context>  
在程序中可以这样获取连接  
public static Connection getConnection()  
...{  
Connection conn=null;  
try  
...{  
Context initContext = new InitialContext();  
Context envContext = (Context)initContext.lookup("java:/comp/env");  
DataSource ds = (DataSource)envContext.lookup("jdbc/test");  
conn = ds.getConnection();  
}catch(Exception e)...{ }  
return conn;  
}  
3、过滤器  
一般来说,字符编码的处理,我们会写一个过滤器。这个过滤器的JAVA类在TOMCAT的例子中有提供,可以按需来更改再拿来用。只要在配置文件中设置:  
<filter-name>setCharacterEncoding</filter-name>  
<filter-class>powerwind.filter.SetCharacterEncodingFilter</filter-class>  
<init-param>  
<param-name>encoding</param-name>  
<param-value>UTF-8</param-value>  
</init-param>  
</filter>  
 
<filter-mapping>  
<filter-name>setCharacterEncoding</filter-name>  
<url-pattern>/pages/*</url-pattern>  
</filter-mapping>  
4、标签的URI  
JSTL是个东西,里面提供了很好用的标签(Tag),但也不一定满足我们的要求,就自己写标签了。把 *.tld 文件直接放到WEB-INF下,在自己定义的tld文件中加上<uri>元素,如:<uri> http://powerwind/course</uri> 。  
 
5、日志  
只用过log4j这个日志包。首先是配置文件 log4j.properties (比较完整的配置,应根据情况选择):  
log4j.rootLogger = DEBUG,INFO, A1, A2,A3  
log4j.appender.A1 = org.apache.log4j.ConsoleAppender  
log4j.appender.A1.layout = org.apache.log4j.PatternLayout  
log4j.appender.A1.layout.ConversionPattern = %4p [%t] (%F:%L) - %m%n  
 
log4j.appender.A2 = org.apache.log4j.RollingFileAppender  
log4j.appender.A2.File =../../log/test.log  
log4j.appender.A2.MaxFileSize = 1KB  
log4j.appender.A2.MaxBackupIndex = 3  
log4j.appender.A2.layout = org.apache.log4j.PatternLayout  
log4j.appender.A2.layout.ConversionPattern = %d{yyyy-MM-dd hh:mm:ss}:%p %t %c - %m%n  
 
log4j.appender.A3=org.apache.log4j.jdbc.JDBCAppender  
log4j.appender.A3.URL= jdbc:mysql://localhost:3306/log4jTest  
log4j.appender.A3.driver= com.mysql.jdbc.Driver  
log4j.appender.A3.user= root  
log4j.appender.A3.password= 123456  
log4j.appender.A3.layout = org.apache.log4j.PatternLayout  
log4j.appender.A3.layout.ConversionPattern = INSERT INTO log4j (createDate, thread, level, class, message) values('%d', '%t', '%-5p', '%c', '%m')  
接着写个Servlet来加载log4j:  
 
package powerwind.servlet;  
 
import org.apache.log4j.Logger;  
import org.apache.log4j.PropertyConfigurator;  
 
import javax.servlet.*;  
import javax.servlet.http.*;  
 
public class Log4jInit extends HttpServlet {  
public void init(ServletConfig config) throws ServletException {  
super.init(config);  
String prefix = getServletContext().getRealPath("/");  
String file = getInitParameter("log4j");  
System.out.println("init log4j...");  
if (file != null){  
PropertyConfigurator.configure(prefix+file);  
}else  
{  
PropertyConfigurator.configure(prefix+"log4j.properties");  
}  
}  
}  
然后同时要在web.xml下配置:  
 
<servlet>  
<servlet-name>log4jInit</servlet-name>  
<servlet-class>powerwind.servlet.Log4jInit</servlet-class>  
<init-param>  
<param-name>log4j</param-name>  
<param-value>WEB-INF/classes/log4j.properties</param-value>  
</init-param>  
<load-on-startup>1</load-on-startup>  
</servlet>  
6、国际化  
 
#test_zh_CN.properties  
#login page  
login.title=登录页面  
小型的应用中,我们并不常需要国际化。但是,如果网站要中文版和英文版的话,这个就不错啦。使用时很简单,把资源test_zh_CN.properties文件放到classes目录下,然后用JSTL的fmt标签调用。  
<fmt:setLocale value="zh_CN" scope=”session” />  
<fmt:setBundle basename="test" scope=”session” var=”hehe” />  
<fmt:message key="login.title" bundle=”${hehe}” scope=”session” />  
其中var和scope属性不是必需的。三者结合,就可以实现国际化了。  
 
二、极限与安全  
资源放在WEB-INF下是安全的,因为这个目录对于客户端是不存在的。权限控制并不是仅仅这样就可以了。如果只是简单地判断用户是否登录,可用一个过滤器检查Session对象即可。若需要级别控制的话,就在Session中保存级别信息,然后加以判断。  
一般把权限的控制做成一个标签(tag)。如:  
public int doEndTag() throws JspException {  
HttpSession session = pageContext.getSession();  
if ((session != null) && (session.getAttribute("user") != null)) {  
String t = ((UserBean) session.getAttribute("user")).getType();  
if (t == null || role == null) {  
invalid();  
return (SKIP_PAGE);  
}  
String[] roles = role.split(delimiter);  
for (int i = 0; i < roles.length; i++) {  
if (roles.equalsIgnoreCase(role))  
return (EVAL_PAGE);  
}  
} else {  
invalid();  
return (SKIP_PAGE);  
}  
return (EVAL_PAGE);  
}  
三、上传与下载  
 
上传的话,一般使用已有的组件,如commons-fileupload 或者欧莱礼的cos (可能会遇到中文编码的问题)。而下载,比较简单,就自己写了个Servlet。  
public void handleRequest(HttpServletRequest request,  
HttpServletResponse response) throws IOException, ServletException {  
String name = request.getParameter("name");  
String type = request.getParameter("type");  
String dir = request.getParameter("dir");  
if (name == null || name.length() < 2 || dir == null || dir.length() < 1 || type == null || type.length() < 1) {  
throw new ServletException("Sorry,error occured");  
}  
char ch = dir.charAt(dir.length() - 1);  
if (ch != '/' || ch != '\')  
dir = dir + "/";  
ServletOutputStream os = null;  
BufferedInputStream bis = null;  
try {  
File file = new File(dir + name);  
if (!file.exists() || file.length() >= Integer.MAX_VALUE) {  
logger.error("Invalid file or file to large,file: " + name);  
throw new ServletException(  
"Invalid file or file to large,file: " + name);  
}  
response.setContentType("application/" + type);  
response.addHeader("Content-Disposition", "attachment; filename="+ name);  
response.setContentLength((int) file.length());  
os = response.getOutputStream();  
bis = new BufferedInputStream(new FileInputStream(file));  
int size = -1;  
while ((size = bis.read()) != -1)  
os.write(size);  
} catch (IOException ioe) {  
throw new ServletException(ioe.getMessage());  
} finally {  
if (os != null)  
os.close();  
if (bis != null)  
bis.close();  
}  
}  
以上只是个示例程序,灵活与方便的做法应该是在Servlet初始化参数(<init-param>)设置下载文件所在目录,当然也可以在页面中设置参数。甚至可以做成一个下载标签,方便使用。 |   
 
 
 
 |