• 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);

       》   

            }

        }

    }

  • 相关阅读:
    Idea中资源文件的设置和Java中类的权限
    Springboot中slf4j+log4j2的使用
    linux下修改文件查看样式(日期/文件大小)
    maven项目中引入外部jar
    01背包问题
    python爬取千千音乐
    【DataBase】SQL优化案例:其一
    【Uni-App】底部栏踩坑
    【Uni-App】UniApp转微信小程序发布应用
    【Uni-App】API笔记 P2
  • 原文地址:https://www.cnblogs.com/DFX339/p/8535224.html
Copyright © 2020-2023  润新知