zoukankan      html  css  js  c++  java
  • Struts1的基础知识

    struts1.0的配置

    在web.xml文件中的配置

    <servlet>

    <!--配置ActionServlet类,一启动就创建该类对象-->

    <servlet-name>action</servlet-name>

    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

    <!--配置struts-config.xml文件的位置,默认从WEN-INF/下找文件名为struts-config.xml文件 如果是按照默认路径和默认文件名存放的配置文件,就可以不用配置,但是建议配置-->

          <init-param>

               <param-name>config</param-name>

               <param-value>/WEB-INF/struts-config.xml<param-value>

          </init-param>

         

          <!-- 错误日志配置,一旦出错会自动生成错误日志 -->

          <init-param>

               <param-name>debug</param-name>

               <param-value>2<param-value>

          </init-param>

         

          <!-- 对xml文件的解析日志 -->

          <init-param>

               <param-name>detail</param-name>

               <param-value>2<param-value>

          </init-param>

         

          <!--配置为:tomcat一启动就创建ActionServlet类的对象 这个一定要记得配置-->

          <load-on-startup>1</load-on-startup>

    </servlet>

    <servlet-mapping>

          <!--处理所有的.do请求-->

          <servlet-name>action</servlet-name>

          <url-pattern>*.do</url-pattern>

    </servlet-mapping>

    在struts-config.xml文件中的配置

    <action-mappings>

          <!--

            action标签 每个请求对应一个action配置,

           path:请求路径 与发送请求的表单的action=””对应,只是多了个斜杠

           name:对应的表单bean name,与 form-bean标签中的name属性相同

           scope:存储的域  默认为session 建议存储在request域中

           type:指明Action子类的全路径名 (包名+类名)

          -->

          <action path="" name="" scope="" type="">

          <!--

               forward标签是指定跳转信息

               name:跳转的名字,通过名字找到path

               path:指定要跳转到的jsp页面

    redirect:指定跳转方式,默认为false 为true的时候表示客户端跳转,为false的时候表示服务端跳转

          -->

          <forward name="" path="" redirect=""></forward>

          </action>

    </action-mappings>

          <!--

               form-bean标签对应form对象 继承ActionForm的子类

               name:指定收集表单数据的对象名

               type:指定ActionForm子类的全路径名(包名+类名)

          -->

    <form-beans>

          <form-bean name="" type=""></form-bean>

    </form-beans>

    自己对于struts1.0执行流程的理解:

    tomcat服务器一启动,就创建ActionServlet对象 ModuleConfig对象 ModuleConfig对象中封装了三个Map集合

    1、  : Map  actionConfigs = new HashMap();//用来存储ActionMapping对象的集合, action标签中的path属性的属性值作为该集合的key,ActionMapping对象作为集合的value

          actionConfigs.put(path,new ActionMapping());//往集合中添加数据

          ActionMapping mapping=actionConfigs.get(path);//通过path取出ActionMapping对象 path作为actionConfigs集合的key,ActionMapping对象作为actionConfigs集合的value

          mapping.getName();//通过ActionMapping对象得到<action>标签中的name属性对应的属性值 (与form-bean标签的name值相同,formBeans正好使用这个值取得FormBeanConfig对象)

          mapping.getScope();//通过ActionMapping对象得到<action>标签中的scope属性对应的属性值 (确定ActionForm对象的存储域,一般是session 或 request)

          mapping.getType();//通过ActionMapping对象得到<action>标签中的type属性对应的属性值 --(类的全路径名,通过这个值来创建Action对象)

          mapping.getValidate();//通过ActionMapping对象得到<action>标签中的validate属性对应的属性值, (确定是否对收集的表单数据做验证,默认为true ,设值为false的时候不验证)

    2、 Map formBeans = new HashMap();//用来存储FormBeanConfig对象的集合,form-bean标签中的name属性作为该集合的key,FormBeanConfig对象作为集合的value

          formBeans.put(name,new FormBeanConfig());//往集合中添加数据

          FormBeanConfig form=formBeans.get(name);//通过《action》标签中的name属性值取出FormBeanConfig对象,name是map集合formBeans中的key,FormBeanConfig对象为formBeans集合的value

          form.getType();//通过FormBeanConfig对象得到<form-bean>标签中的type属性对应的属性值 (类的全路径名,用来创建ActionFrom对象)

    3、 : Map forwards = new HashMap();//用来存储ActionForward对象的集合,forward标签中的name属性作为该集合的key,ActionForward对象作为该集合的value。

         forwards.put(name,new ActionForward());//往集合中添加数据

         ActionForward forward = forwards.get(name);//通过name属性得到ActionForward对象,name为forwards集合中的key,ActionFoward对象为forwards集合中的value

          forwards.getRedirect();//通过ActionForward对象得到<froward>标签中的redirect属性对应的属性值, (确定跳转方式,默认为false 服务端跳转,设值为true的时候为客户端跳转)

          forwards.getPath();//通过ActionForward对象得到<forward>标签中的path属性对应的属性值(得到跳转路径,确定跳转的目的jsp页面)

    执行流程

    ActionServlet对象一创建,就将struts-config.xml文件读到内存中,ModuleConfig对象存在整个配置文件中的信息

    用户发*.do请求时,tomcat会自动把请求交给ActionServlet对象处理(也可以说是交给struts处理),

    ActionServlet会调用根据发送请求的方式调用本身的doGet()或者doPost()方法。

         

          //ActionServlet类中的doGet()方法

          public void doGet(HttpServletRequest request,HttpServletResponse response)throws IOException,ServletException{

               process(request,response);//调用ActionServlet类中的process方法处理请求

          }

         

          //ActionServelt类中的doPost()方法

          public void doPost(HttpServletRequest request,HttpServletResponse response)throws IOException,ServletException{

               process(request,response);//调用ActionServlet类中的process方法处理请求

          }

         

    //ActionServlet类中的process方法(在这个process方法中完成对请求的处理全部流程,从请求字符串的截取(processPath)—>ActionMapping对象的创建(processMapping)—>ActionForm对象的创建(processActionForm)—>表单数据的收集(processPopulate)—>Action对象的创建(processActionCreate)—>Action对象的execute的方法的执行(processActionPerform)—>完成跳转(processForwardConfig

     

    protected void process(HttpServletRequest request,HttpServlet

    Response response)throws IOException, ServletException {

     ModuleConfig config = getModuleConfig(request);//config为ModuleConfig对象

        RequestProcessor processor = getProcessorForModule(config);//通过ModuleConfig对象创建RequestProcessor对象

              

         processor.process(request, response);//调用RequestProcessor类的process()方法

        }

       

        //RequestProcessor类中的process()方法

        public void process(HttpServletRequest request,  HttpServletResponse response)throws IOException, ServletException {

    String path=processPath(request,response); //调用RequestProcessor类的processPath ()方法

    //RequestProcessor类中的processPath()方法,返回path

    protected String processPath(HttpServletRequest request,HttpServletResponse response)  throws IOException {

    String url=request.getContextPath();//获取除项目名以外的项目全路径名

    (例如:请求路径  http://localhost:8080/struts1.0/login.do? username="dfx"&  password="123"  url="  /login.do?username="dfx" &password="123" 这里就算是post请求,表单中的参数名和参数值都会发送过来,只是被封装在协议体中,不显示而已 ")

                   

          int index=url.lastIndexOf(".");//找到从请求字符串从最后一个位置开始反向搜索,第一次出现(.)的位置  ,这里index=6;

          int start=ur.lastIndexOf("/");//找到请求字符串中从最后一个位置开始反向搜索,第一次出现(/)的位置,这里start=0;

          //截取请求 作为path

          String path=url.substring(start,index);//这里的  path= “/login” ;

        } 

    //调用RequestProcessor类中的processMapping()方法得到ActionMapping对象

           ActionMapping mapping = processMapping(request, response, path);

          

           //RequestProcessor类中processMapping()

      protected ActionMapping processMapping(HttpServletRequest request, HttpServletResponse response, String path)throws IOException {

              

            //调用ModuleConfig接口中的findActionConfig()方法取得ActionMapping对象

          ActionMapping mapping = (ActionMapping)moduleConfig.findActionConfig(path);

        }

        //ModuleConfig实现类中的findActionConfig()方法 (该方法中的actionConfigs是Map集合,该map集合的key为path,value为ActionMapping对象)

         public ActionConfig findActionConfig(String path) {

            ActionConfig config = (ActionConfig) actionConfigs.get(path);//通过key (path)取出map集合中的value值(ActionMapping对象)

            return config;//返回ActionConfig对象(ActionMapping是ActionConfig的子类)

        }

        //取出ActionMapping对象后,调用RequestProcessor类中的processActionForm()方法得到ActionForm对象

         ActionForm form = processActionForm(request, response, mapping);

        

         //RequestProcessor类中的processActionForm()方法

         protected ActionForm processActionForm(HttpServletRequest request,HttpServletResponse response,  ActionMapping mapping) {

    //调用RequestUtils类中的静态方法 createActionForm()创建ActionForm对象

            ActionForm instance = RequestUtils.createActionForm(request, mapping, moduleConfig, servlet);

                return instance;//返回ActionForm对象

            }

        

         //RequestUtils类中的静态方法 createActionForm()

          public static ActionForm createActionForm(HttpServletRequest request,ActionMapping mapping, ModuleConfig moduleConfig, ActionServlet servlet) {

            String name = mapping.getName();//通过ActionMapping对象得到<action>标签中name属性对应的属性值(这个name属性和《form-bean》标签中的name属性是一样的)

           

    //通过name属性值,调用ModuleConfig接口中的moduleConfig.findFormBeanConfig()方法得到FormBeanConfig对象

            FormBeanConfig config = moduleConfig.findFormBeanConfig(name);

           

            《

            //ModuleConfig接口实现类中的方法findFormBeanConfig()

            public FormBeanConfig findFormBeanConfig(String name) {

    //formbeans为map集合,该集合中的key为<form-bean>标签中的name属性值,value为FormBeanConfig对象

            return ((FormBeanConfig) formBeans.get(name));//所以这里可以通过formBeans.get(name)取得value FormBeanConfig对象

           }

            》

      //调用RequestUtils类中的lookupActionForm()方法,得到ActionForm对象

    ActionForm instance = lookupActionForm(request, attribute, mapping.getScope());

           

        《

        // RequestUtils类中的lookupActionForm()方法

         private static ActionForm lookupActionForm(HttpServletRequest request, String attribute, String scope)

    {

    //ActionForm类型变量用来接收ActionForm对象

              ActionForm instance = null;

            HttpSession session = null;

            if ("request".equals(scope)) {//判断ActionForm对象是否被指定存储在request域中

    /*判断是request域的时候,就从request域中取出ActionForm对象

    注:这里的getAttribute()方法是指从request中取出属性值,

     attribute作为默认属性名,如果attribute属性不存在就从name属性中取值 name属性中存放的是ActionForm对象存储在内置对象中的属性名,内置对象的属性值为 ActionForm对象

    例如: request.setAttribute("loginForm",new LoginForm()); //这里 name="loginform" ,getAttribute(name),取出来的便是ActionForm对象

    */

                instance = (ActionForm) request.getAttribute(attribute);

            } else {

                session = request.getSession();//如果ActionForm对象是否被指定存储在session域中,

                instance = (ActionForm) session.getAttribute(attribute);//这里的解释和request域雷同

            }

            return (instance);

        }

        》

    //调用RequestUtils类中的createActionForm()方法创建ActionForm对象

            return createActionForm(config, servlet);

           

            《

            //RequestUtils类中的createActionForm()方法

            public static ActionForm createActionForm(FormBeanConfig config, ActionServlet servlet){

          

            ActionForm instance = null;

            try {

                //通过FormBeanConfig对象,调用FormBeanConfig类的createActionForm()方法创建ActionForm对象

                instance = config.createActionForm(servlet);

               

                《

            //FormBeanConfig类的createActionForm()方法

            public ActionForm createActionForm(ActionServlet servlet) throws IllegalAccessException, InstantiationException {

            Object obj = null;

          //调用FormBeanConfig类中的formBeanClass()方法创建 Object类型的对象

            obj = formBeanClass().newInstance();

            

            《

            //FormBeanConfig类中的formBeanClass()方法

          protected Class formBeanClass() {

    ClassLoader classLoader =  Thread.currentThread().getContextClassLoader();//加载该对象

             try {

                return (classLoader.loadClass(getType()));//<form-bean>标签中的type属性(类全路径名)对应的类对象,暂时定义为Object类型

           } catch (Exception e) {

                return (null);

        }

     }

            》

            ActionForm form = null;

            if (obj instanceof ActionForm) {

                form = (ActionForm)obj;//将FormBeanConfig类中的formBeanClass()方法得到的type指定的类对象造型为ActionForm类型

            }

            form.setServlet(servlet);

            return form; //返回ActionForm对象

        } 

                》

            } catch(Throwable t) {

                log.error(servlet.getInternal().getMessage("formBean", config.getType()), t);

            }

            return (instance);

        }

            》

        }

       

             //调用RequestProcessor类中的processPopulate()方法,将表单中的数据封装到表单bean中 (ActionForm对象中)

            processPopulate(request, response, form, mapping);

           

           // RequestProcessor类中的processPopulate()方法

    protected void processPopulate(HttpServletRequest request, HttpServletResponse response, ActionForm form, ActionMapping mapping)  throws ServletException {

        if (form == null) {

                return;

     }

            form.setServlet(this.servlet);

            form.reset(mapping, request);//在收集表单中的数据到表单bean中之前,调用reset()方法,初始化数据

           

            //调用RequestUtils类中的populate()方法,收集表单数据

            RequestUtils.populate(form, mapping.getPrefix(), mapping.getSuffix(), request);

           

            《

            //RequestUtils类中的populate()方法

             public static void populate(Object bean,String prefix,String suffix, HttpServletRequest request) throws ServletException {

            HashMap properties = new HashMap();//创建map集合,表单中的参数名和参数值分别作为key和value存储在该集合中

            Enumeration names = null;//创建Enumeration集合,迭代出request内置对象(域)中的所有参数名和参数值

           

             names = request.getParameterNames();//迭代出封装在request内置对象中的所有参数名

            while (names.hasMoreElements()) {

                String name = (String) names.nextElement();//迭代取得request内置对象中参数名  (假若是个登录表单:第一个取出 username ,第二次取出password)

                String stripped = name;//将参数名保存在临时变量中,作为map集合的key

               

                Object parameterValue = null;

                //得到request内置对象的参数名对应的参数值(假若是个登录表单:参数名为 username对应的参数值为“admin” ,参数名password对应的参数值为“123”)

                parameterValue = request.getParameterValues(name);

               

                 properties.put(stripped, parameterValue);//将参数名和参数值分别作为key和value存储到map集合中

            }

            try {

                //调用BeanUtils中的populate()方法

                BeanUtils.populate(bean, properties);

               

                      《

    //BeanUtils中的populate()方法

                 public static void populate(Object bean, Map properties)throws IllegalAccessException, InvocationTargetException {

                       if ((bean == null) || (properties == null)) {

                          return;

                       }

    //先将map集合转换成Set集合,然后调用iterator()方法进行迭代输出(map集合中存放的是request内置对象中的参数名和参数值)

                       Iterator names = properties.keySet().iterator();

                      while (names.hasNext()) {

    String name = (String) names.next();//得到request内置对象中的参数名 username

                          Object value = properties.get(name);//参数名name作为key,map.get(name)得到value值,request内置对象中的参数值 "admin"

    /*bean:为ActionForm对象,name为参数名 (username),value为参数值(admin)//这句代码的意思就是将request内置对象中的参数名和参数值设置到ActionForm对象(bean)中。

    */

               setProperty(bean, name, value);      

    注:表单bean ActionForm对象 bean会从表单中找到和它属性名相同的参数名进行收集,并且只收集属性名相同的表单参数,和属性名不同参数名的不会被收集。找到对应的属性名的参数,调用set方法,设值(这里会找到与name对应的表单bean的属性进行设值。比如:当name为username时,bean.setUsername(value); 当name为password时,bean.setPasswrod(value); value的值和name值一 一对应

                       }

              }

               

                      》

            } catch(Exception e) {

                throw new ServletException("BeanUtils.populate", e);

            } finally { }

        }

          》

            //在RequestProcessor类中的process()方法中调用processActionCreate()方法创建Action对象(使用map单例+同步方法创建保证安全性

            Action action = processActionCreate(request, response, mapping);

            《

            //RequestProcessor类中的processActionCreate()方法

            protected Action processActionCreate(HttpServletRequest request,HttpServletResponse response, ActionMapping mapping)  throws IOException {

            String className = mapping.getType();//得到type属性值,也就是继承Action类的类全路径名(cn.action.LoginAction)

            Action instance = null;

            synchronized (actions) {         

    //actions是一个map集合 ,HashMap actions=new HashMap();//该map集合的key为type属性值(cn.action.LoginAction),value为type类名对应的类对象

                instance = (Action) actions.get(className);//先从map中type对应的类对象,取到了就直接返回(保证单例)

                if (instance != null) {

                    return (instance);

                }

                try {

                //从map集合中没有取到Action对象时,就通过反射创建该对象

                    instance = (Action) RequestUtils.applicationInstance(className);

                } catch (Exception e) {

                }

               

                instance.setServlet(this.servlet);

                actions.put(className, instance);//将继承Action类的类名和类对象分别作为key和value存入map集合中

            }

            return (instance);

        }

            》

    //在RequestProcessor类中的process()方法中调用processActionPerform()方法创建ActionFoward对象

            ActionForward forward = processActionPerform(request, response, action, form, mapping);

           

            《

            //RequestProcessor类中的processActionPerform()方法

            protected ActionForward processActionPerform(HttpServletRequest request, HttpServletResponse response, Action action, ActionForm form,

                    ActionMapping mapping) throws IOException, ServletException {

            try {

                return (action.execute(mapping, form, request, response));//执行Action对象的execute()方法,返回值为ActionForward对象

            } catch (Exception e) {

                return (processException(request, response,  e, form, mapping));

            }

        }

        》

              

    //在RequestProcessor类中的process()方法中调用processForwardConfig()转向信息方法

            processForwardConfig(request, response, forward);

           

            《

       //RequestProcessor类中的processForwardConfig()方法,完成跳转

        protected void processForwardConfig(HttpServletRequest request, HttpServletResponse response,ForwardConfig forward)

            throws IOException, ServletException {

            if (forward == null) {//先判断转向对象是否为null,为null的时候表示不是要struts提供的转向方法,使用自己写的跳转信息

                return;

            }

            String forwardPath = forward.getPath();//通过ForwardConfig对象获得<forward>标签中的path  转向路径 例如 “/success.jsp”

            String uri = null;

           

            if (forward.getRedirect()) {//判断跳转方式,为true的时候表示客户端跳转

                response.sendRedirect(response.encodeRedirectURL(uri));

            } else {

            //这里调用RequestProcessor类中的doForward()方法完成服务端跳转

                doForward(uri, request, response);//为false的时候表示服务端跳转(默认为false 服务端跳转)

               《

                //RequestProcessor类中的doForward()方法

     protected void doForward( String uri, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

               

           RequestDispatcher rd = getServletContext().getRequestDispatcher(uri);

           rd.forward(request, response);

       》   

            }

        }

    }

  • 相关阅读:
    HDU 5585 Numbers
    HDU 3308 LCIS
    POJ 2991 Crane
    POJ 1436 Horizontally Visible Segments
    POJ 3667 Hotel
    HaiHongOJ 1003 God Wang
    【SDOI 2008】 递归数列
    5月19日省中提高组题解
    【HDU 1588】 Gauss Fibonacci
    【POJ 3233】Matrix Power Series
  • 原文地址:https://www.cnblogs.com/DFX339/p/8535224.html
Copyright © 2011-2022 走看看