详解Java的Struts框架以及相关的MVC设计理念

struts简介
Struts是Apache软件基金会(ASF)赞助的一个开源项目。它最初是jakarta项目中的一个子项目,并在2004年3月成为ASF的顶级项目。它通过采用JavaServlet/JSP技术,实现了基于JavaEEWeb应用的MVC设计模式的应用框架,是MVC经典设计模式中的一个经典产品。
Struts发展历史
Struts是作为ApacheJakarta项目的组成部分,项目的创立者希望通过对该项目的研究,改进和提高JavaServerPages、servlet、标签库以及面向对象的技术水准。
Struts这个名字的来源于在建筑和旧式飞机中使用的支持金属架。之所以这个框架叫做“struts”,是为了提醒我们记住那些支撑我们房屋,建筑,桥梁,甚至我们踩高跷的基础支撑。这也是解释struts在开发web应用程序中所扮演的角色的精彩描述。
Struts的含义是”支柱,枝干”,它的目的是为了减少程序开发的时间,项目的创建者认为JSP,servlet的存在虽然可以帮助用户解决大部分问题,但是由于它们的编码对项目的开发带来了许多的不方便,可重用性也差,所以struts应运而生,帮助用户在最短的时间内解决这些问题。Struts框架提供如下服务:
(1)作为控制器的Servlet。
(2)提供大量的标签库。
(3)提供了用于国际化的框架,利用不同的配置文件,可以帮助用户选择合适自己的语言。
(4)提供了JDBC的实现,来定义数据源和数据库连接池。
(5)XML语法分析工具。
(6)文件下载机制。
 
Struts原理
Struts是对JSPModel2设计标准的一种实现,下面分别从模型(Model)、视图(view)和控制器3个部分介绍Struts的体系结构和工作原理。调用流程如下所示。

(1)视图(view)
在Struts中,视图层包含两个部分,JSP页面和ActionForm。
ActionForm封装了用户提交的表单信息,其实ActonForm本质上就是JavaBean,这些JavaBean中没有业务逻辑,只提供了所有属性的getter和setter方法,这些属性和用户表单中的输入项是一一对应的。在Struts中就是通过ActionForm把用户表单信息提交给控制器。
JSP页面是经典MVC中主要的视图组件,主要是信息显示和控制器处理结果显示的功能。
除了以上,struts还提供了一个强大的struts标签库,来帮助用户解决显示逻辑,并且利用ActonForm组件将信息传递到控制层。
(2)控制器(Controller)
在控制层,struts提供了一个控制器组件ActionServlet,它继承自HttpServlet,并重载了HttpServlet的doGet(),doPost()方法,可以接受HTTP的响应,并进行转发,同时还提供了使用XML进行转发Mapping(映射)的功能。
(3)模型(Model)
模型表示状态和业务逻辑的处理,在一般的web应用程序中,用JavaBean或者EJB来实现系统的业务逻辑。在Struts中,struts提供Action对象,来管理业务逻辑的调用,帮助用户分离业务逻辑,也就是说struts本身不实现业务逻辑,但可以调用已完成的业务逻辑。

Struts工作流程
Struts工作流程如下所示。

ActionServlet是struts中核心的控制器,所有的用户请求都必须通过ActionServlet的处理,而struts-config.xml是struts中核心的配置文件,在这个文件中配置了用户请求URL和控制器Action的映射关系,ActionServlet通过这个配置文件把用户的请求发送到对应的控制器中。
在struts web应用程序中,当web应用程序启动的时候,就会初始化ActionServlet在初始化ActionServlet的时候会加载struts-config.xml配置文件,在加载成功后会把这些URL和控制器映射关系存放在ActionMapping对象或者其他对象中。当ActionServlet接收到用户请求的时候,就会按照下面的流程对用户请求进行处理。
(1)ActionServlet接收到用户的请求后,会根据请求URL寻找匹配的ActionMapping对象,如果匹配失败,说明用户请求的URL路径信息有误,所以返回请求路径无效的信息,当找到匹配的ActionMapping的时候,进入到下一步。
(2)当ActionServlet找到匹配的ActionMapping对象的时候,会根据ActionMapping中的映射信息判断对应的ActionForm对象是否存在,如果不存在对应的ActionForm对象就创建一个新的ActionForm对应,并把用户提交的表单信息保存到这个ActionForm对象中。
(3)在struts-config.xml中这个配置文件,可以配置表单是否需要验证,如果需要验证,就调用ActionForm中的validate()方法对用户输入的表单进行验证。
(4)如果ActionForm的validate()方法返回了ActionErrors对象,则表明验证失败,ActionServlet把这个页面返回到用户输入的界面,提示用户重新输入。如果方法的返回值为null,就表明验证已经通过,可以进入下一步处理。
(5)ActionServlet可以根据ActionMapping对象查找用户请求转发给哪个控制器Action,如果对应的Action对象不存在,就创建这个对象,并调用这个Action的excute()方法。
(6)业务逻辑控制器Action的execute()方法就会返回一个ActionForward对象,ActionServlet把控制器处理的结果转发到ActionForward对象指定的JSP页面。
(7)ActionForward对象指定的JSP页面根据返回的处理结果,用合适形式把服务器处理的结果展示给用户,到这里为止,一个客户请求的整个过程完毕。

以上初步struts框架进行了介绍,和对原理进行了简单的分析。至于struts是如何实现MVC的,ActionServlet属于Controller部分,Action和ActionForm属于Model层,还是Action属于Controller层,不同的人对struts有不同的理解。接下来真正的运用到实践中,在实践中深刻去体会,原理固然重要,重要的是运用,是能驾驭和使用这个框架。就像学习开车一样,不是一蹴而就的。

MVC向struts MVC框架演变过程
版本一 基本的MVC
首先是创建一个jsp索引页面index.jsp,index.jsp创建一个表单。
如果我们完成添加用户的模块,我们提交表单的时候要把这个表单提交给一个servlet,于是我们在src自己的包中建立自己的servlet继承HttpServlet,TestServlet同时覆盖父类的doGet和doPost方法。
提交的的表单信息,我们可以在TestServlet中通过request.getParameter(“username”);取出来。之后把从表单中的数据提交到数据库,我们的servlet作为控制器没有添加到数据库的职责,于是我们把访问数据库的业务逻辑放到UserManager.java类中。在这个类中实现添加用户的任务。

package com.bjpowernode.servlet; 

public class UserManager { 

               public void add(String username)
               {
               System.out.println("UserManager.add()-->>"+ username);
               }
}

在TestServlet中调用UserManager中的方法。同时让页面转向到添加成功的页面add_success.jsp。
TestServlet代码以及在web.xml中配置TestServlet.

<servlet>
          <servlet-name>TestServlet</servlet-name>
          <servlet-class>com.bjpowernode.servlet.TestServlet</servlet-class>
 </servlet> 

 <servlet-mapping>
          <servlet-name>TestServlet</servlet-name> 

          <url-pattern>/servlet/TestServlet</url-pattern>
 </servlet-mapping>

Testservlet代码如下所示:

package com.bjpowernode.servlet; 

import java.io.IOException;
import java.util.List; 

import javax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse; 

public class TestServlet extendsHttpServlet { 

                @Override
                protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
                   String username = request.getParameter(“username”);
                   UserManager userManager = new UserManager();
                   userManager.add(username);
                   request.getRequestDispatcher(“/add_success.jsp”).forward(request,response);
} 

                @Override
                protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException { 

                  doGet(request,response);
                        }
}

索引页面index.jsp代码,通过servlet/TestServlet来转到TestServlet。

<form action="servlet/queryUser.action" method="post">
      姓名:<input type="text" name="username"><br>
      <input type="submit" value="提交"><br>
   </form>

这样采用MVC完成了用户的添加任务。
版本二 通过判断标识变量
当我们不仅要完成用户的添加而是要完成用户的增删改查的时候我们可以在servlet中进行判断,是添加还是删除等。并且在传递字符串的时候要加上一个标识表示相应的操作。这样在servlet中会有很多的if和else语句。
版本三 servlet模式匹配 截取字符串判断
我们可以在配置servlet的时候配置成为匹配模式<url-pattern>*.action</url-pattern>任何的*.action的都会转到到TestServlet,这样我们可以截取URL来判断转到哪个页面。但在TestServlet中仍然有很多的ifelse语句进行判断。这样我们的TestServlet代码如下所示。

import java.io.IOException;
import java.util.List; 

importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse; 

public class TestServlet extendsHttpServlet { 

                        @Override
                        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                            throws ServletException, IOException {
                         //截取url.
                         String requestURI = request.getRequestURI();
                         //System.out.println("requestURI="+ requestURI); 

                         //截取http://localhost:8080/test_servlet/servlet/addUser.action test_servlet后面的东西。
                         String path = requestURI.substring(requestURI.indexOf("/", 1),requestURI.indexOf("."));
                         //截取得到虚目录。/servlet/addUser
                         System.out.println("path="+ path); 

                         String username = request.getParameter("username");
                         UserManager userManager = new UserManager(); 

                         String forward = "";
                         //判断截取的path和哪个要加载的页面相等.
                         if("/servlet/delUser".equals(path))
                         {
                            userManager.del(username);
                            forward = "del_success.jsp";
                            //request.getRequestDispatcher("/del_success.jsp").forward(request,response);
                         }else if("/servlet/addUser".equals(path))
                         {
                            userManager.add(username);
                            forward= "add_success.jsp";
                            //request.getRequestDispatcher("/add_success.jsp").forward(request,response);
                         }else if("/servlet/modifyUser".equals(path))
                         {
                            userManager.modify(username);
                            forward= "modify_success.jsp";
                                                //request.getRequestDispatcher("/modify_success.jsp").forward(request,response); 

                         }else if("/servlet/queryUser".equals(path))
                         {
                            List userList = userManager.query(username);
                            request.setAttribute("userList",userList); 

                            forward= "query_success.jsp"; 

                                                //request.getRequestDispatcher("/query_success.jsp").forward(request,response);
                         }else
                         {
                            throw new RuntimeException("请求失败!");
                         } 

                         request.getRequestDispatcher(forward).forward(request,response); 

                         }
                        @Override
                        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                            throwsServletException, IOException { 

                         doGet(request,response);
                        } 

}

UserManager代码如下所示:

package com.bjpowernode.servlet; 

import java.util.ArrayList;
import java.util.List; 

public class UserManager { 

                        public void add(String username)
                        {
                         System.out.println("UserManager.add()-->>"+ username);
                        } 

                        public void del(String username)
                        {
                         System.out.println("UserManager.del()-->>"+ username);
                        } 

                        public void modify(String username)
                        {
                         System.out.println("UserManager.modify()-->>"+ username);
                        } 

                        public List query(String username)
                        {
                         System.out.println("UserManager.query()-->>"+ username); 

                         List userList = new ArrayList();
                         userList.add("a");
                         userList.add("b");
                         userList.add("c"); 

                         return userList;
                        } 

}

同时建立查询成功,删除成功,修改成功jsp页面。
这样在index.jsp页面中通过表单的action属性来转到相应的页面。

<body> 

                        <form action="servlet/queryUser.action" method="post">
                         姓名:<input type="text" name="username"><br>
                         <input type="submit" value="提交"><br>
                        </form>
</body>

版本三的缺点是if太多,不稳定,当我们添加或者删除一个if的时候还需要重新编译源程序。这样无法适应变化的需求。所以我们在此基础上进行改进就需要去掉if语句,可以把改变的部分分离出来,变成可配置的,这样就变得灵活的,需要改动jsp的文件名,在配置文件中配置一下就可以了。
版本四 if else抽象出接口和类+配置文件
首先我们把转到的地址字符串放到一个字符串变量中,这样TestServlet中的doGet方法,代码如下。

String username = request.getParameter("username");
                       UserManager userManager = new UserManager(); 

                       String forward = "";
                       //判断截取的path和哪个要加载的页面相等.
                       if("/servlet/delUser".equals(path))
                       {
                          userManager.del(username);
                          forward= "del_success.jsp";
                       }else if("/servlet/addUser".equals(path))
                       {
                          userManager.add(username);
                          forward= "add_success.jsp";
                              }elseif("/servlet/modifyUser".equals(path))
                       {
                          userManager.modify(username);
                          forward= "modify_success.jsp"; 

                       }else if("/servlet/queryUser".equals(path))
                       {
                          List userList = userManager.query(username);
                          request.setAttribute("userList",userList); 

                          forward= "query_success.jsp"; 

                       }else
                       {
                          thrownew RuntimeException("请求失败!");
                       }
                      request.getRequestDispatcher(forward).forward(request,response);

统一完成了转向。当if语句是满足某种条件,条件不同的时候转到不同的页面,添加有添加的逻辑,修改有修改的逻辑,这样我们可以抽象出接口。对添加的action操作添加,对删除的action做出删除任务,对修改的action做出修改。把每一个if语句中的变成为类去实现,抽象出一个Action接口,接口中方法execute()方法,返回转向路径字符串。类图如下所示。

共同的Action接口,不同的实现。
Action接口代码。

package com.bjpowernode.servlet; 

importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse; 

public interface Action { 

                        public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception; 

}

AddUserAction代码。

package com.bjpowernode.servlet; 

importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse; 

public class AddUserActionimplements Action { 

                        @Override
                        public String execute(HttpServletRequest request,HttpServletResponse response) throws Exception {
                         String username = request.getParameter("username");
                         //Stringsex = request.getParameter("sex");
                         //...........
                         //调用业务逻辑. 

                         UserManager userManager = new UserManager();
                         userManager.add(username); 

                         return"/add_success.jsp"; 

                        } 

}

DelUserAction代码。

package com.bjpowernode.servlet; 

importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse; 

public class DelUserActionimplements Action { 

                        @Override
                        public String execute(HttpServletRequest request,HttpServletResponse response) throws Exception {
                         String username = request.getParameter("username");
                         //String sex = request.getParameter("sex");
                         //...........
                         //调用业务逻辑.
                         UserManager userManager = new UserManager();
                         try
                         {
                            userManager.del(username);
                         }catch(Exceptione)
                         {
                            return"del_error.jsp";
                         } 

                         return"/del_success.jsp"; 

                        } 

}

ModifyUserAction代码。

package com.bjpowernode.servlet; 

importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse; 

public class ModifyUserActionimplements Action { 

                        @Override
                        public String execute(HttpServletRequest request,HttpServletResponse response) throwsException {
                         String username = request.getParameter("username");
                         //String sex = request.getParameter("userId");
                         //...........等其他... 

                         //调用业务逻辑. 

                         UserManager userManager = new UserManager();
                         userManager.modify(username); 

                         return"/modify_success.jsp"; 

                        } 

}

QueryUserAction代码。

package com.bjpowernode.servlet; 

import java.util.List; 

importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse; 

public class QueryUserActionimplements Action { 

                        @Override
                        public String execute(HttpServletRequest request,HttpServletResponse response) throwsException {
                         String username = request.getParameter("username");
                         //Stringsex = request.getParameter("userId");
                         //其他查询条件.
                         //...........等其他... 

                         //调用业务逻辑. 

                         UserManager userManager = new UserManager();
                         List userList = userManager.query(username);
                         request.setAttribute("userList",userList); 

                         return"/query_success.jsp";//转向路径都可以通过配置文件读取。 

                        } 

}

这样使用多态方式调用不同的Action,转向代码如下所示。

//用多态的方式.
                         Action action = null;
                         if("/servlet/delUser".equals(path))
                         {
                            action= new DelUserAction();
                         }else if("/servlet/addUser".equals(path))
                         {
                            action= new AddUserAction();
                         }else if("/servlet/modifyUser".equals(path))
                         {
                            action= new ModifyUserAction(); 

                         }else if("/servlet/queryUser".equals(path))
                         {
                            action= new QueryUserAction(); 

                         }else
                         {
                            throw new RuntimeException("请求失败!");
                         }
                         //取得action后传递过去。动态调用ACtion中的execute方法。
                          String forward = null;
                         try{
                            forward= action.execute(request,response);
                         }catch (Exception e) {
                            e.printStackTrace();
                         } 

                          //根据路径完成转向。
                         request.getRequestDispatcher(forward).forward(request, response);

上述调用不同的action,我们可以把不同的请求和对应的action配置到自己的xml文件中。配置哪个请求对应哪个Action。

<action-config>
      <action path="/servlet/delUser" type="com.bjpowernode.servlet.DelUserAction">
         <forward name="success">/del_success.jsp</forward>
         <forward name="error">/del_error.jsp</forward>
      </action> 

 <action path="/servlet/addUser" type="com.bjpowernode.servlet.AddUserAction">
         <forward name="success">/add_success.jsp</forward>
         <forward name="error">/add_error.jsp</forward>
      </action> 

 <action path="/servlet/modifyUser" type="com.bjpowernode.servlet.ModifyUserAction">
         <forward name="success">/modify_success.jsp</forward>
         <forward name="error">/modify_error.jsp</forward>
      </action> 

 <action path="/servlet/queryUser" type="com.bjpowernode.servlet.QueryUserAction">
         <forward name="success">/query_success.jsp</forward>
         <forward name="error">/query_error.jsp</forward>
      </action>
 </action-config>

这样我们就可以读取配置文件来进行相应的操作。每个action对应着一些信息,它的class,执行成功以及执行失败的配置。我们在读取配置文件的时候可以把这些放到Map对象中。代码如下所示。

ActionMapping
                          {
                               private String path;
                               private String type;
                               Map forwardMap;
                          } 

                         forwardMap
                          {
                               key="success";
                               value="/del_success.jsp"
                               key="error";
                               value="/del_error.jsp";
                          } 

                         Map map = new HashMap();
                          map.put("/servlet/delUser",);
                          map.put("/servlet/addUser",);
                          map.put("/servlet/modifyUser",);
                          map.put("/servlet/queryUser",); 

                          //如果是删除的ActionMapping存储如下:
                          actionMapping
                          {
                               path="/servlet/delUser";
                               type="com.bjpowernode.servlet.DelUserAction";
                               forwardMap
                               {
                                  key="success",value="/del_success.jsp";
                                  key="error",value="/del_error.jsp";
                               }
                         }
                          String path ="/servlet/delUser"; 

                          //根据截取的URL请求,到Map中取得本次请求对应的Action。
                          ActionMapping actionMapping =(ActionMappint)map.get(path); 

                         // 取得本次请求对应的Action类的完成路径。
                          String type =actionMappint.getType();//com.bjpowernode.servlet.DelUserAction 

                         //通过反射动态实例化Action
                          Aciton action =(Action)class.forName(type).newInstance(); 

                          //取得action后传递过去。动态调用ACtion中的execute方法。
                          String forward =action.execute(request,response); 

                          //根据路径完成转向。
                          request.getRequestDispatcher(forward).forward(request,response);

我们用时序图来描述上述调用过程(如图)。

Struts就是采用上述思路。Struts框架是把上图中前端控制器servlet进行了封装,我们只要继承struts的Action去调用业务逻辑和转向。读取配置文件的工作也是封装到了struts框架中。前篇讲解了struts框架的应用实例,我们可以进行对比。

(0)

相关推荐

  • Java的Struts框架中的主题模板和国际化设置

    主题模板 如果不指定一个主题,然后Struts2中会使用默认的XHTML主题.例如Struts 2中选择标签: <s:textfield name="name" label="Name" /> 生成HTML标记: <tr> <td class="tdLabel"> <label for="empinfo_name" class="label">Name:<

  • 在Java的Struts中判断是否调用AJAX及用拦截器对其优化

    Strut2判断是否是AJAX调用 1.   AJAX与传统Form表单 实际上,两者一般都是通过HTTP的POST请求.区别是浏览器提交Form表单后,期望服务器返回一个完整的HTML页面.而AJAX调用是由XMLHttpRequest对象(不同浏览器可能不一样)发出,浏览器期望服务器返回HTML片段即可,具体是JSON.XML等都没有要求.返回到浏览器后如何使用,也是由JS脚本自己决定的.   2. 请求是不是AJAX 那么对于服务器端,如何判断一个HTTP请求是不是AJAX调用?这需要看H

  • 深入解析Java的Struts框架中的控制器DispatchAction

    Struts中的表单处理器为ActionForm,而struts中的控制器主要是Action,以及DispatchAction控制器等. Action 在struts中,所有的用户都会经过ActionServlet的处理,而实际的工作是交给Action对象来处理的,ActionServlet可以从配置文件中创建ActionMapping对象,从ActionMapping对象中找到对应使用的Action,然后将用户请求转交给Action. 对Struts一个ActionMapping只能生成一个A

  • 详解Java的Struts2框架的结构及其数据转移方式

    Struts2的结构 1.为什么要使用框架? (1)框架自动完成了很多琐屑的任务 对于Struts2来说,它帮助我们方便地完成了数据类型转换.数据验证.国际化等等 Web开发中常见的任务.还有Spring中大量使用的Template模式,都是在让我们的开发 过程更加自动化.智能化.使用框架就是避免重新发明轮子,重新复制这些模板代码. 框架让我们将精力更多地放在更高级别的问题上,而不是常见工作流和基础任务上. (2)使用框架就是优雅地继承了框架背后的架构 框架背后的架构通常定义了一系列的工作流程,

  • Java的Struts框架中登陆功能的实现和表单处理器的使用

    实现Struts登录 1.jar包拷贝 首先是建立java web项目,之后打开我们我们下载好strtus框架,Struts-1.2.9-bin文件夹和struts-1.2.9.src源文件文件夹.在bin文件夹中的lib文件中拷贝struts的jar包,拷贝到我们自己项目struts_login –>lib文件夹下. 2.web.xml文件配置 找到Struts-1.2.9-bin中Struts-1.2.9-bin-->webapps下的struts实例struts-blank中的strut

  • Java的Struts框架中配置国际化的资源存储的要点解析

    1.资源文件命名 国际化资源文件命名格式如下: basename_language_country.properties basename_language.properties basename.properties 其中basename为资源文件的基本名称,language和country必须是java支持的语言和国家.获取java支持的语言和国家代码如下: Locale[] locales = Locale.getAvailableLocales(); for(Locale locale:

  • 详解在Java的Struts2框架中配置Action的方法

    在Struts2中Action部分,也就是Controller层采用了低侵入的方式.为什么这么说?这是因为在Struts2中action类并不需要继承任何的基类,或实现任何的接口,更没有与Servlet的API直接耦合.它通常更像一个普通的POJO(通常应该包含一个无参数的execute方法),而且可以在内容定义一系列的方法(无参方法),并可以通过配置的方式,把每一个方法都当作一个独立的action来使用,从而实现代码复用. 例如: package example; public class U

  • java struts2学习笔记之线程安全

    在说struts2的线程安全之前,先说一下,什么是线程安全?这是一个网友讲的. 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码.如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的. 就是说,在一个进程中有多个线程并发执行,每个线程执行过程中,变量值是相同的,执行结果也是相同的,就是线程安全的.否则就是线程不安全的. 然后回顾一下servlet的线程安全问题,由于servlet是单例模式的,只会产生一个实例,当多个用户同

  • Java的Struts2框架配合Ext JS处理JSON数据的使用示例

    最近尝试用extjs来展示树状菜单.着实花了一番功夫.树状菜单的菜单项需要动态加载,而目前版本的extjs中只支持JSON格式的数据.查了一些资 料,决定使用struts2的json-plugin.首先按照例子做了一个,但是结果就是不成功,界面上只出来了一个js中生成的root节点,不能加 载从后台生成的数据.研究后发现是数据格式有问题.使用json-plugin生成的数据格式如下: {"cls":"folder","id":10,"l

  • 详解Java的Struts框架以及相关的MVC设计理念

    struts简介 Struts是Apache软件基金会(ASF)赞助的一个开源项目.它最初是jakarta项目中的一个子项目,并在2004年3月成为ASF的顶级项目.它通过采用JavaServlet/JSP技术,实现了基于JavaEEWeb应用的MVC设计模式的应用框架,是MVC经典设计模式中的一个经典产品. Struts发展历史 Struts是作为ApacheJakarta项目的组成部分,项目的创立者希望通过对该项目的研究,改进和提高JavaServerPages.servlet.标签库以及面

  • 详解Java的Struts框架中上传文件和客户端验证的实现

    文件上传 Struts 2框架提供了内置支持处理文件上传使用基于HTML表单的文件上传.上传一个文件时,它通常会被存储在一个临时目录中,他们应该由Action类进行处理或移动到一个永久的目录,以确保数据不丢失. 请注意,服务器有一个安全策略可能会禁止写到目录以外的临时目录和属于web应用的目录. 在Struts中的文件上传是通过预先定义的拦截文件上传拦截器这是可通过org.apache.struts2.interceptor.FileUploadInterceptor类的defaultStack

  • 详解Java的Struts框架中注释的用法

    要开始在你的项目中使用注释,确保WebContent/WEB-INF/lib文件夹中的jar文件包括以下: struts2-convention-plugin-x.y.z.jar asm-x.y.jar antlr-x.y.z.jar commons-fileupload-x.y.z.jar commons-io-x.y.z.jar commons-lang-x.y.jar commons-logging-x.y.z.jar commons-logging-api-x.y.jar freemar

  • 详解Java的Struts框架中栈值和OGNL的使用

    值栈: 值栈是一个集合中的几个对象保持下列对象提供的顺序: 值栈可以通过JSP,Velocity或者Freemarker的标签.有各种不同的标签在单独的章节中,我们将学习,用于获取和设置Struts 2.0 的值栈. ValueStack的对象里面可以得到动作如下: ActionContext.getContext().getValueStack() 一旦拥有了值对象,就可以用下面的方法来操纵该对象: OGNL: 对象图形导航语言(OGNL)是一个功能强大的表达式语言是用来参考值栈上的数据和操纵

  • 详解Java的Spring框架中的事务管理方式

    数据库事务是被当作单个工作单元的操作序列.这些操作要么全部完成或全部不成功.事务管理是面向企业应用程序,以确保数据的完整性和一致性RDBMS中的重要组成部分.事务的概念可以用下面的描述为ACID四个关键属性来描述: 原子性: 一个事务应该被视为单个操作单元表示的操作的任一整个序列是成功的或不成功的. 一致性: 这代表了数据库的参照完整性,在桌等唯一主键的一致性 隔离性: 可能有很多事务处理相同的数据集的同时,每个事务都应由他人隔离,以防止数据损坏. 持久性: 一旦事务完成,本次事务的结果必须作出

  • 详解Java的Spring框架中bean的定义以及生命周期

    bean的定义 形成应用程序的骨干是由Spring IoC容器所管理的对象称为bean.bean被实例化,组装,并通过Spring IoC容器所管理的对象.这些bean由容器提供,例如,在XML的<bean/>定义,已经看到了前几章的形式配置元数据创建. bean定义包含所需要的容器要知道以下称为配置元数据的信息: 如何创建一个bean Bean 生命周期的详细信息 Bean 依赖关系 上述所有配置元数据转换成一组的下列属性构成每个bean的定义. Spring配置元数据 Spring IoC

  • 详解Java的Hibernate框架中的注解与缓存

    注解 Hibernate注解是一个没有使用XML文件来定义映射的最新方法.可以在除或替换的XML映射元数据使用注解. Hibernate的注解是强大的方式来提供元数据对象和关系表的映射.所有的元数据被杵到一起的代码POJO java文件这可以帮助用户在开发过程中同时要了解表的结构和POJO. 如果打算让应用程序移植到其他EJB3规范的ORM应用程序,必须使用注解来表示映射信息,但仍然如果想要更大的灵活性,那么应该使用基于XML的映射去. 环境设置Hibernate注释 首先,必须确保使用的是JD

  • 详解Java单元测试Junit框架实例

    问题: 1.目前测试存在的问题 2.Junit注意的细节 3.Junit使用规范 4.断言 5.案例 junit(单元测试框架) 1.目前存在的问题 1.目前的测试方法如果需要测试,都需要在main方法上调用 2.目前的结果都需要我们人工比对 2.Junit 注意的细节 1.如果使用junit测试一个方法的时候,在junit窗口上显示绿色那么表示测试正确,如果显示了红色,则代表该方法测试出现了异常不通过 2.如果点击方法名.类名.包名.工程名运行junit分别测试的是对于的方法,类.包中的所有类

  • 详解Java的Hibernat框架中的Map映射与SortedMap映射

    Map映射 Map映射是一个java集合存储在键 - 值对的元素,并且不允许在列表中重复的元素. Map接口提供三种collection视图,允许Map内容看作是一组键-值集合,或者设置键 - 值映射关系. Map被映射到映射表中一个<map>元素和无序的地图可以在java.util.HashMap中被初始化. 定义RDBMS表: 考虑一个情况,我们需要员工记录存储在EMPLOYEE表,将有以下结构: create table EMPLOYEE ( id INT NOT NULL auto_i

随机推荐