服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

hibernate+spring+struts扩展struts


  简介:
  我看到很多项目中,开发者实现了自己的mvc框架,并不是因为他们想做同struts根本不同的东西,而是因为他们并没有意识到如何扩展struts。开发自己的mvc框架可以获得全部的控制权,但是这也意味着需要很多资源来实现它(人力物力),在紧张的日程安排下,有时候这是不可能的。
  
  struts不仅仅是一个强大的框架,同时它也是可扩展的。你可以以三种方式来扩展struts。
  
  1、plugin:如果你想在application startup或shutdown的时候做一些业务逻辑的话,那就创建你自己的plugin类。
  
  2、requestprocessor:如果你想在请求被处理的过程中某个时刻做一些业务逻辑的话,那么创建你自己的requestprocessor类。比如说,在每次请求执行之前,你可以扩展requestprocessor来检查用户是否登陆了以及他是否有权限去执行某个特定的action。
  
  3、actionservlet:如果你想在application startup和shutdown的时候以及请求被处理的时候做某些业务逻辑,你也可以扩张actionservlet类。不过你应当在plugin和requestprocessor都不能解决你的需求的时候来使用actionservlet。
  
  在这篇文章中,我们将使用一个struts应用的示例来示范如何使用这三种方式来扩展struts。示例程序的代码可以从http://www.onjava.com/onjava/2004/11/10/examples/sample1.zip下载。两个扩展struts成功的范例是struts自身的validation和tiles框架。
  
  我们假设你已经比较熟悉struts框架并且知道如何使用它创建一个简单的应用。如果你想知道更多关于struts的内容,请参考官方主页。
  
  plugin
  
  plugin是一个接口,你可以创建一个实现该接口的类,当application startup或shutdown的时候做些事情。
  
  比方说,我创建了一个使用hibernate作为持久层的web应用,我想当应用启动的时候就初始化hibernate,这样子当我的web应用受到第一个请求的时候,hibernate就已经是配置好的并且可用的。同时我们想当application关闭的时候关闭hibernate。我们可以用一个hibernate plugin来实现这个需求,通过如下的两步:
  
  1、创建一个类实现了plugin接口:
  
  public class hibernateplugin implements plugin{
  private string configfile;
  // this method will be called at application shutdown time
  public void destroy() {
  system.out.println("entering hibernateplugin.destroy()");
  //put hibernate cleanup code here
  system.out.println("exiting hibernateplugin.destroy()");
  }
  //this method will be called at application startup time
  public void init(actionservlet actionservlet, moduleconfig config)
  throws servletexception {
  system.out.println("entering hibernateplugin.init()");
  system.out.println("value of init parameter " +
  getconfigfile());
  system.out.println("exiting hibernateplugin.init()");
  }
  public string getconfigfile() {
  return name;
  }
  public void setconfigfile(string string) {
  configfile = string;
  }
  }
  
  实现plugin接口的类必须完成两个方法:init()和destroy()。当application startup的时候init()方法被调用,当shutdown的时候destroy()方法被调用。struts还允许给你的plugin类传递初始化参数。为了传递参数,你必须在plugin类中为每一个参数创建javabean式的setter方法。在我们的hibernateplugin类中,我会把configfile的name作为参数传进去,而不是硬编码到程序中。
  
  2、在struts-config.xml中添加如下的代码来通告struts有新的plugin:
  
  <struts-config>
  ...
  <!-- message resources -->
  <message-resources parameter= "sample1.resources.applicationresources"/>
  
  <!-- declare your plugins -->
  <plug-in classname="com.sample.util.hibernateplugin">
  <set-property property="configfile" value="/hibernate.cfg.xml"/>
  </plug-in>
  </struts-config>
  
  属性classname是实现了plugin接口的类的全限定名。对于每一个初始化参数,可以使用<set-property>元素传递参数。在我们的例子中,我要把config文件的名字传进去,所以使用了一个带有配置文件路径的<set-property>。
  
  struts的tiles和validator框架都使用plugin来读取配置文件进行初始化。另外两件plugin可以帮你做到的事情是:
  
  如果你的application依赖于某些配置文件,那么你可以在plugin类中检查它们是否可用,如果不可用的话抛出一个servletexception,这样就可以使actionservlet变为不可用。
  
  plugin接口的init()方法是你可以改变moduleconfig的最后机会,moduleconfig是一组静态配置信息的集合,用来描述基于struts模块。struts将会在所有plugin处理完后释放moduleconfig。
  
  request是如何被处理的
  actionservlet是struts框架中唯一的servlet,它负责处理所有request。无论何时接收到一个request,它都会先尝试为当前的request寻找一个sub-application。一旦一个sub-application被找到,actionservlet就会为那个sub-application创建一个requestprocessor对象,调用这个对象的process()方法并把httpservletrequest和httpservletresponse对象传入。
  
  requestprocessor.process()就是大部分request被处理的地方。process()方法使用了template method模式实现,其中有很多独立的方法来执行请求处理的每一步骤,这些方法将会在process方法中依次被调用。比如,将会有一个独立的方法用来寻找当前request对应的actionform类,一个方法来检查当前用户是否有执行action mapping所必须的权限。这些给与我们极大的灵活性。在发布的struts包中有一个requestprocessor类提供了请求处理每一步骤的默认实现。这就意味着你可以仅仅重写你感兴趣的方法,其它的使用默认的实现。举例来说,默认地struts调用request.isuserinrole()来检查用户是否有权限执行当前的actionmapping;这时如果你想通过查询数据库来实现,你所要做的就是重写processroles()方法,通过查询出的用户是否拥有必须的权限来返回true或false。
  
  首先我们将会看到缺省情况下,process()方法是如何实现的,然后我将会详细解释默认的requestprocessor类中的每一个方法,这样你就可以决定哪一部分是你想要改变的。
  
  public void process(httpservletrequest request,httpservletresponse response)
  throws ioexception, servletexception {
  // wrap multipart requests with a special wrapper
  request = processmultipart(request);
  // identify the path component we will
  // use to select a mapping
  string path = processpath(request, response);
  if (path == null) {
  return;
  }
  if (log.isdebugenabled()) {
  log.debug("processing a '" + request.getmethod() + "' for path '" + path + "'");
  }
  // select a locale for the current user if requested
  processlocale(request, response);
  // set the content type and no-caching headers
  // if requested
  processcontent(request, response);
  processnocache(request, response);
  // general purpose preprocessing hook
  if (!processpreprocess(request, response)) {
  return;
  }
  // identify the mapping for this request
  actionmapping mapping =
  processmapping(request, response, path);
  if (mapping == null) {
  return;
  }
  // check for any role required to perform this action
  if (!processroles(request, response, mapping)) {
  return;
  }
  // process any actionform bean related to this request
  actionform form = processactionform(request, response, mapping);
  processpopulate(request, response, form, mapping);
  if (!processvalidate(request, response, form, mapping)) {
  return;
  }
  // process a forward or include specified by this mapping
  if (!processforward(request, response, mapping)) {
  return;
  }
  if (!processinclude(request, response, mapping)) {
  return;
  }
  // create or acquire the action instance to
  // process this request
  action action =
  processactioncreate(request, response, mapping);
  if (action == null) {
  return;
  }
  // call the action instance itself
  actionforward forward = processactionperform(request, response,action, form, mapping);
  // process the returned actionforward instance
  processforwardconfig(request, response, forward);
  }
  
  1、processmutipart():在这个方法中,struts将会读取request来检查request的contenttype是否是multipart/form-data。如果是的话,将会解析request并且将之包装到httpservletrequest中。当你创建了一个html form用来提交数据,那么request的cont

扫描关注微信公众号