Struts1 工作流程

Struts1 工作原理及过程:

1. 初始化Struts1框架的总控制器ActionServlet,ActionServlet抽象类继承了GenericServlet,这个类继承下来的Service()方法外还提供了很多方法:

doGet  doPost 从指定URL中取得数据, doHead获取HTTP header的信息,doPut主要用来向服务器端上传文件(与使用FTP的方法类似),doTrace,doOptions

ActionServlet读取web.xml中的配置信息,为Struts中不同的模块初始化相应的对象,

2. 客户端发送请求,用户提交表单或通过URL向WEB服务器提交请求,请求的数据用HTTP协议传给web服务器,这个HTTP请求被包装成一个HTTPServletRequest对象,并

且自动调用HTTPServlet的service()方法来解析这个HTTP请求,service()方法解析HTTP请求,service()方法根据method来决定是执行doGet还是doPost,HTTP的格式内容

被解析,只要你继承了HttpServlet,并且在web.xml里面配置了相应的servlet和mapping,就能,struts1会去读取struts-config.xml的配置信息,为其提供相应的Action操作

struts-config.xml中的每一个标签<action>元素对应着一个ActionMapping,ActionMapping继承自ActionConfig,<load-on-startup>2</load-on-startup> 

配置信息,这个信息就是说明了但服务器已启动就动态读取struts-config配置文件把配置文件的信息put到ActionMapping中.所以当我们运行服务器的时候,

我们在内存中已经存在对应struts-config配置文件信息对应的ActionMapping,ActionMapping中的name名称查找ActionForm,ActionMapping将请求发送到

具体的Action,对应的formBean一并传给这个Action的execute方法,最后通过ActionMapping的Forward进行页面的跳转。

 

在Strut1中经常用到的技术:

1.类型转换器,String类型可以通过Form正常接收,而例如Date类型等就要自定义类型转换器了,自定义类型转换器实现Converter接口的类,并且实现convert方法,

定义一个servlet来注册自定义类型转换器,在init方法中利用ConvertUtils的register()方法我们自定义类型转换器,注意:load-on-startup的值要大于0,因为这个servlet要求

在tomcat启动时初始化。

2.过滤器,过滤器用来截取客户端给服务器端发的请求,也可以截取服务器端给客户端的响应,Servlet ApI定义了三个接口来供开发人员编写Filter程序,Filter,FilterChain,

FilterConfig,Filter程序实现了一个Filter接口的Java类,与Servlet相似,Filter程序需要在web.xml文件中进行注册和设置所能拦截的资源,Filter程序可以拦截Jsp,Servlet

静态图片文件和静态Html文件,web.xml中可以注册多个Filter程序,此时成为Filter链,Filter链中各个Filter的拦截顺序与他们在应用程序的web.xml中映射的顺序一致。

Web 容器创建 Filter 对象实例后,将立即调用该 Filter 对象的 init 方法。Init 方法在 Filter 生命周期中仅执行一次,web 容器在调用 init 方法时,会传递一个包含 Filter 的配

置和运行环境的 FilterConfig 对象(FilterConfig的用法和ServletConfig类似)。利用FilterConfig对象可以得到ServletContext对象,以及部署描述符中配置的过滤器的初始化参

数。在这个方法中,可以抛出ServletException异常,通知容器该过滤器不能正常工作.destroy(): 在Web容器卸载 Filter 对象之前被调用。该方法在Filter的生命周期中仅执行

一次。在这个方法中,可以释放过滤器使用的资源。

当前 Filter 对象的 doFilter 方法内部需要调用 FilterChain 对象的 chain.doFilter(request,response)方法才能把请求交付给 Filter 链中的下一个 Filter 或者目标 Servlet 程序

去处理,也可以直接向客户端返回响应信息,或者利用RequestDispatcher的forward()和include()方法,以及 HttpServletResponse的sendRedirect()方法将请求转向到其他

资源。这个方法的请求和响应参数的类型是 ServletRequest和ServletResponse,也就是说,过滤器的使用并不依赖于具体的协议。

其配置方式和servlet非常类似,下面是具体的配置代码
<filter>
  <filter-name>testFilterConfig</filter-name>
  <filter-class>cn.itcast.filter.TestFilterConfigFilter</filter-class>
  <!-- 配置当前 Filter 的初始化参数 -->
  <init-param>
  <param-name>name</param-name>
  <param-value>Tom</param-value>
  </init-param>
  <init-param>
  <param-name>password</param-name>
  <param-value>123456</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>testFilterConfig</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

Filter的典型应用  使浏览器不缓存页面的过滤器:有 3 个 HTTP 响应头字段都可以禁止浏览器缓存当前页面,它们在 Servlet 中的示例代码如下

response.setDateHeader("Expires",-1); 

response.setHeader("Cache-Control","no-cache"); 

response.setHeader("Pragma","no-cache"); 

并不是所有的浏览器都能完全支持上面的三个响应头,因此最好是同时使用上面的三个响应头

通过配置参数encoding指明使用何种字符编码,以处理Html Form请求参数的中文问题,具体的实例代码如下:
public void doFilter(ServletRequest arg0, ServletResponse arg1,
  FilterChain arg2) throws IOException, ServletException {
  // TODO Auto-generated method stub
  arg0.setCharacterEncoding(“UTF-8”);
  arg2.doFilter(arg0, arg1); 
}

如果实现对客户端输入信息的过滤?
答:使用过滤器,但是由于request只能获得页面参数,但是却无法修改页面参数的值并返回给页面(也就是说:只有getParameter方法,但是没有 setParameter方法),这个时候我们只能通过继承的方式重写request对象的getParameter方法来实现。这个时候我们提供两种比较常见的方法来实现。


方案1.
继承 javax.servlet.http.HttpServletRequestWrapper这个类
这个类实际上是对request对象的装饰,通过构造方法获得一个request对象,其内部所有HttpServletRequest接口中的方法都是实际调用这个request对象来实现的。
使用这个类,传入request对象,我们就只需要对我们感兴趣的方法进行重写,而其他方法则使用request的默认实现
比如这里我们对其中的 getParameter方法进行重写
@Override 
public String getParameter(String name) {
  String value = super.getParameter(name);
  if(value != null&&value.contains("bad")){
  value = value.replaceAll("bad", "=======");
  }
  return value; 
}

方案2:
使用动态代理,传入一个request对象作为需要被代理的对象,利用动态代理的invoke方法遍历其内部的每个方法,如果发现有名为“getParameter”,就进行

覆盖,其他方法则直接调用其最初的实现。

3.监听器,监听器专门用于对其他对象上发生的事件或状态的改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动,

Servlet 监听器:Servlet 规范中定义的一种特殊类,它用于监听 web 应用程序中的 ServletContext, HttpSession 和 ServletRequest 等域对象的创建

与销毁事件,以及监听这些域对象中的属性发生修改的事件。

ServletContextListener 接口

ServletContextListener 接口用于监听 ServletContext 对象的创建和销毁事件。 

当 ServletContext 对象被创建时,激发contextInitialized (ServletContextEvent sce)方法

当 ServletContext 对象被销毁时,激发contextDestroyed(ServletContextEvent sce)方法

HttpSessionListener 接口

HttpSessionListener 接口用于监听HttpSession对象的创建和销毁

创建一个 Session时,激发sessionCreated (HttpSessionEvent se) 方法

销毁一个Session时,激发sessionDestroyed (HttpSessionEvent se) 方法

ServletRequestListener 接口

ServletRequestListener 接口用于监听ServletRequest 对象的创建和销毁

创建一个ServletRequest 对象时,激发requestInitialized(ServletRequestEvent sre)方法

销毁一个Session时,激发requestDestroyed(ServletRequestEvent sre)方法

HttpSessionBindingListener 接口

实现了HttpSessionBindingListener接口的 JavaBean 对象可以感知自己被绑定到 Session 中和从 Session 中删除的事件

当对象被绑定到 HttpSession 对象中时,web 服务器调用该对象的 void valueBound(HttpSessionBindingEvent event) 方法

当对象从 HttpSession 对象中解除绑定时,web 服务器调用该对象的 void valueUnbound(HttpSessionBindingEvent event)方法

相关文章

最后还有就是ServletRequest和ServletResponse接口中的常用方法

 public java.lang.ObjectgetAttribute(java.lang.String name)
返回以name为名字的属性的值。如果该属性不存在,这个方法将返回null。
 public java.util.EnumerationgetAttributeNames()
返回请求中所有可用的属性的名字。如果在请求中没有属性,这个方法将返回一个空的枚举集合。
 public voidremoveAttribute(java.lang.String name)
移除请求中名字为name的属性。
 public voidsetAttribute(java.lang.String name, java.lang.Object o)
在请求中保存名字为name的属性。如果第二个参数o为null,那么相当于调用removeAttribute(name)。
 public java.lang.StringgetCharacterEncoding()
返回请求正文使用的字符编码的名字。如果请求没有指定字符编码,这个方法将返回null。
 public intgetContentLength()
以字节为单位,返回请求正文的长度。如果长度不可知,这个方法将返回-1。
 public java.lang.StringgetContentType()
返回请求正文的MIME类型。如果类型不可知,这个方法将返回null。
 public ServletInputStreamgetInputStream()
返回一个输入流,使用该输入流以二进制方式读取请求正文的内容。javax.servlet.ServletInputStream是一个抽象类,继承自java.io.InputStream。
 public java.lang.StringgetLocalAddr()
返回接收到请求的网络接口的IP地址,这个方法是在Servlet 2.4规范中新增的。
 public java.lang.StringgetLocalName()
返回接收到请求的IP接口的主机名,这个方法是在Servlet 2.4规范中新增的。
 public intgetLocalPort()
返回接收到请求的网络接口的IP端口号,这个方法是在Servlet 2.4规范中新增的。
 public java.lang.StringgetParameter(java.lang.String name)
返回请求中name参数的值。如果name参数有多个值,那么这个方法将返回值列表中的第一个值。如果在请求中没有找到这个参数,这个方法将返回null。
 public java.util.Enumeration getParameterNames()
返回请求中包含的所有参数的名字。如果请求中没有参数,这个方法将返回一个空的枚举集合。
 public java.lang.String[] getParameterValues(java.lang.String name)
返回请求中name参数所有的值。如果这个参数在请求中并不存在,这个方法将返回null。
 public java.lang.String getProtocol()
返回请求使用的协议的名字和版本,例如:HTTP/1.1。
 public java.io.BufferedReader getReader() throws java.io.IOException
返回BufferedReader对象,以字符数据方式读取请求正文。
 public java.lang.String getRemoteAddr()
返回发送请求的客户端或者最后一个代理服务器的IP地址。
 public java.lang.String getRemoteHost()
返回发送请求的客户端或者最后一个代理服务器的完整限定名。
 public int getRemotePort()
返回发送请求的客户端或者最后一个代理服务器的IP源端口,这个方法是在Servlet 2.4规范中新增的。
 public RequestDispatcher getRequestDispatcher(java.lang.String path)
返回RequestDispatcher对象,作为path所定位的资源的封装。
 public java.lang.String getServerName()
返回请求发送到的服务器的主机名。
 public int getServerPort()
返回请求发送到的服务器的端口号。
 public void setCharacterEncoding (java.lang.String env) throws java.io.Unsupported EncodingException
覆盖在请求正文中所使用的字符编码的名字。
下面我们看一下ServletResponse接口中的常用方法。
 public void flushBuffer() throws java.io.IOException
强制把任何在缓存中的内容发送到客户端。
 public int getBufferSize()
返回实际用于响应的缓存的大小。如果没有使用缓存,这个方法将返回0。
 public java.lang.String getCharacterEncoding()
返回在响应中发送的正文所使用的字符编码(MIME字符集)。
 public java.lang.String getContentType()
返回在响应中发送的正文所使用的MIME类型。
 public ServletOutputStream getOutputStream() throws java.io.IOException
返回ServletOutputStream对象,用于在响应中写入二进制数据。javax.servlet. ServletOutputStream是一个抽象类,继承自java.io.OutputStream。
 public java.io.PrintWritergetWriter() throws java.io.IOException
返回PrintWriter对象,用于发送字符文本到客户端。PrintWriter对象使用getCharacterEncoding()方法返回的字符编码。如果没有指定响应的字符编码方式,默认将使用ISO-8859-1。
 public booleanisCommitted()
返回一个布尔值,指示是否已经提交了响应。
 public voidreset()
清除在缓存中的任何数据,包括状态代码和消息报头。如果响应已经被提交,这个方法将抛出IllegalStateException异常。
 public voidresetBuffer()
清除在缓存中的响应内容,保留状态代码和消息报头。如果响应已经被提交,这个方法将抛出IllegalStateException异常。
 public voidsetBufferSize(int size)
设置响应正文的缓存大小。Servlet容器将使用一个缓存,其大小至少是请求的尺寸大小。这个方法必须在响应正文被写入之前调用,如果内容已经被写入或者响应对象已经被提交,这个方法将抛出IllegalStateException异常。
 public voidsetCharacterEncoding(java.lang.String charset)
设置发送到客户端的响应的字符编码,例如UTF-8。
 public voidsetContentLength(int len)
对于HTTP Servlet,在响应中,设置内容正文的长度,这个方法设置HTTP Content-Length实体报头。
 public voidsetContentType(java.lang.String type)
 设置要发送到客户端的响应的内容类型,此时响应应该还没有提交。给出的内容类型可以包括字符编码说明,例如:text/html;charset=UTF-8。如果这个方法在 getWriter()方法被调用之前调用,那么响应的字符编码将仅从给出的内容类型中设置。这个方法如果在getWriter()方法被调用之后或者在响应被提交之后调用,将不会设置响应的字符编码。在使用HTTP协议的情况中,这个方法设置Content-Type实体报头。

细心的读者可能注意到了,在上面所列举的方法中,有的可能会抛出IllegalStateException异常,然而在函数声明时,却没有声明抛出此异常,这是为什么呢?java.lang.IllegalStateException是java.lang.RuntimeException的子类。我们知道对于RuntimeException及其派生的异常是由Java运行系统自动抛出并自动处理,不需要我们去捕获,所以也就不需要在函数声明时声明抛出异常了。

http://book.2cto.com/201209/3091.html

http://www.doc88.com/p-472112665360.html

http://www.360doc.com/content/10/1020/10/602061_62388680.shtml

http://hi.baidu.com/allen_zzw/item/0e3b552f1a87970572863e86

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值