Struts用户和开发指南(前言之二)
0.6 属性(Properties)文件和资源绑定(Resourse Bundles)
很多Java应用程序(包括Web应用程序在内)经常通过 属性文件进行一些配置。属性文件是Struts框架用于给应用程序提供消息资源资源绑定的基础所在。
关于属性文件更多,请参考:
.The Java Tutorial中的Using Properties to Manage Program Attributes
Java资源绑定是根据用户 区域(Locale)通过一个或多个属性文件为用户提供国际化支持。Struts从一建立开始就对应用程序的本地化有很好的支持。
关于本地化和资源绑定的更多,请参考:
.The Java Tutorial 中的About the ResourceBundle Class
0.7 Java Servlet
由于Java是一种面向对象的编程语言,所以Java Servlet平台就把HTTP强制造型(或构造)为面向对象的形式。这一策略使得Java开发人员省下更多的时间去处理自己的应用程序的功能上,而不是放在HTTP的机制处理上。
HTTP提供了一套扩展服务器的基本机制,即公共网关接口(Common Gateway Interface,CGI)。服务器可以传递一个请求给CGI程序,然后CGI程序返回一个响应。同样,一个Java服务器传递一个请求给一个Servlet容器,容器可以对请求作一些处理,也可以把这个请求直接返还给HTTP服务器,容器检查它的Servlet列表来决定是否要对这个请求进行处理,如果请求注册了一个Servlert,那么容器就把这请求转交给这个Servlet。
当一个请求进入时,容器检查该请求是否注册了Servlet,如果找到一个匹配的Servlet,容器就把这个请求传给这个Servlet,如果没有,请求就被返还给HTTP服务器。
容器的职责就是管理Servlet的生命周期,创建Servlet,调用Servlet,最后释放Servlet。
一般情况下一个Servlet是[javax.servlet.http.HttpServlet]的一个子类,一个Servlet必须实现容器需要调用的四个方法:
.public void init(ServletConfig config):当Servlet实例第一次被创建时和执行所有请求之前Servlet容器调用这个方法;
.public void doGet(HttpServletRequest request,HttpServletResponse response)此方法用于处理一个使用HTTP GET 协议的请求,并生成一个相应的动态响应;
.public void doPost(HttpServletRequest request HttpServletResponse response)此方法用于处理一个使用HTTP POST协议的请求,并生成一个相应的动态响应;
.public void destroy() 当Servlet实例中止服务时容器调用这个方法,诸如当Web应用程序正在被undeploy或当整个容器被shut down时;
Struts框架已为我们的应用程序提供一个现成Servlet[org.apache.struts.action.ActionServlet]。作为一个Struts应用程序开发人员,在使用Struts框架的ActionServlet实例的同时,了解Servlet的基础知识和明白它在Web应用程序所扮演的角色也是相当重要。
关于Servlet的更多知识,请参考:
.java.sun.com中的The Java Servlet Technology;
.java.sun.com中的The Servlet 2.2 and 2.3 Specifications;
.The Java Web Service Tutorial的Java Servlet Technology;
.The Java Web Service Tutorial的Web Applications;
0.7.1 Servlet和Thread
为了提高性能,容器支持多线程Servlet。一个具体的Servlet只能创建一个实例,通过同一个对象为注册了这个Servlet的每个请求服务。这一个策略可以使容器充分利用系统资源,与此同时也就必须考虑Servlet的doGet和doPost方法编码的线程安全问题。
关于Servlet与线程安全的更多资料,请参考:
.The Java Web Service Tutorial中的Controlling Concurrent Access to Shared Resourceshttp://java.sun.com/webservices/docs/1.0/tutorial/doc/Servlets5.html#64386;
0.7.2 Servlet上下文(Context)
ServletContext接口[javax.servlet.ServletContext]提供正在运行的Servlet所处的Web应用程序的上下文(或环境)的视图。Servlet可以通过getServletConfig()方法访问,而JSP页面可以通过隐含变量application变量获得。Servlet上下文提供的几个API在创建Struts Web应用程序时是相当有用的。
.访问Web应用程序资源:Servlet可以通过getResource()和getResourceAsStream()方法访问Web应用程序内的静态资源文件;
.Servlet上下文属性:上下文可以用来存储Java对象,通过字符串值的key来识别对象,这些属性对整个Web应用程序都是全局的,Servlet可以通过getAttribute(),getAttributeNames(),removeAtrribute()和setAttribute()方法进行访问。对JSP页面来说,Servlet上下文属性相当于“应用程序作用域Bean”;
关于Servlet上下文的更多信息,请参考:
.The Java Web Services Tutorial中的Accessing the Web Context http://java.sun.com/webservices/docs/1.0/tutorial/doc/Servlets10.html#64724;
0.7.3 Servlet请求
每个Servlet处理的请求用一个Java接口代表,一般是HttpServletRequest接口 [javax.servlet.http.HttpServletRequest]。这个请求接口提供了一套访问包含在底层HTTP请求内的所有信息的面向对象机制,包含:
.Cookie:通过getCookie()方法获得包含在请求中的有效Cookie集;
.头:可以通过名称访问包含在请求中的HTTP头。你可以枚举包含的所有的HTTP头的名称;
.参数:请求参数,可以通过名称访问包含在URL的查询字符串中(doGet)或包含在请求内容中(doPost)的请求参数;
.请求特征:输入HTTP请求的一些其他特征,诸如GET或POST方法使用的协议规格("http" 或"https"),等等;
.请求URI信息:通过getRequestURI()方法可以获得原始的请求URL。另外,Servlet容器把请求URL解析为一些可以单独访问的组成部分(contextPath、 servletPath和 pathInfo);
.用户信息:如果你使用了用户管理的安全,那么你就可以查找一个已认证用户名,获得一个代表当前用户的Principal对象,还有当前用户是否被授权为一个特定角色;
另外,Servlet请求还支持请求属性(在JSP中,就是请求作用域Bean),类似于前面讲到的Servlet上下文属性。请求属性常用于业务逻辑层和视图层之间状态信息通信,业务逻辑层产生这些状态信息,视图层使用这些信息产生相应的响应。
Servlet容器会确保一个具体的请求被一个单独线程的Servlet处理,所以你就不必担心在访问Servlet请求的属性时有关线程安全的问题。
关于Servlet请求的更多,请参考:
.The Java Web Tutorial中的Getting Information from Requestshttp://java.sun.com/webservices/docs/1.0/tutorial/doc/Servlets7.html#64433;
0.7.4 Servlet响应
一个Servlet的主要目的就是处理一个输入的Servlet请求[javax.servlet.http.HttpServletRequest],并生成对应的响应。生成响应的过程是通过调用Servlet响应接口[javax.servlet.http.HttpServletResponse]相应的方法来完成的,可用的方法如下:
.设置HTTP头:你可以设置包含在响应中的HTTP头信息。最重要的HTTP头信息就是Content-Type,它告诉你的客户端包含在响应体中信息是哪种类型的,一般情况下,设为text/html类型就是HTML页面,或设为text/xml类型就是XML文档;
.设置Cookies:你可以向当前的响应中增加Cookie;
.发送错误响应:你可以使用sendErro()发送一个HTTP错误状态信息(代替一般的页面内容);
.重定向到其他资源:你可以使用sendRedirect()方法重定向客户端到你指定的其他URL资源上去;
使用Servlet响应API的一个重要原则就是调用维护头信息和Cookies所有方法都必须在缓存的全部响应内容第一次被更新给客户端之前完成。原因是因为这些信息都是作为HTTP响应最开始部分被传输的,因此试图在头信息已被送出之后再添加头信息,必然是徒劳的。
使用Model 2模式的应用程序的表现层,你可能不直接使用Servlet 响应APIs来生成响应。一般是使用JSP页面来完成,在Servlet容器中JSP页面将被JSP编译器转换为Servlet,由这个JSP Servlet生成响应,其中可能包含一些JSP标签生成的动态信息。
其他的表现系统,诸如Struts工具Velocity框架,可能把生成响应的任务代理给一个专门的Servlet来完成,但是原理是相同的。你创建一个模板,然后动态的响应由模板动态生成。
关于Servlet响应的更多,请参考:
.The Java Web Tutorial中的Constructing Responseshttp://java.sun.com/webservices/docs/1.0/tutorial/doc/Servlets7.html#64531;
0.7.5 过滤器(Filtering)
如果你使用2.3版或更新规范的Servlet容器(如Tomcat4.x),你可以使用新的过滤器APIs[javax.servlet.Filter]组合一些组件来处理请求和生成响应。过滤器其实是一个过滤器链的集合,每个过滤器都可以处理请求和生成响应,然后把处理权交给下一个过滤器,最后调用Servlet。
Struts 1.x系列(1.0,1.1版本等)仅支持2.2版本或更早的Servlet规范的Servlet容器,所以Struts自身并没有使用过滤器。下一代的Struts(2.x系列)是基于Servlet2.3或更新规范的。Struts 2.x版可能会使用到过滤器。
关于过滤器更多,请参考:
.Filtering Requests and Responseshttp://java.sun.com/webservices/docs/1.0/tutorial/doc/Servlets8.html#64572;
0.7.6 会话(Session