`

spring mvc 简单解析

阅读更多
由于急需这方面的知识,所以暂时先囫囵吞枣,记下来,有时间再来分享自己的感想,这里先转载下:
关于spring mvc 浅解!

       刚接触spring mvc!看了看内部流程。浅浅的记一下。

       当url为“person.do?do=toEditPage”时程序的走向:
       1,程序会根据后面的person.do后面的do转入spring的控制器

              <servlet>
                <servlet-name>   appfuse</servlet-name>
                 <servlet-class>
                        org.springframework.web.servlet.DispatcherServlet
                 </servlet-class>
                 <load-on-startup>1</load-on-startup>
         </servlet>
           <servlet-mapping>
                    <servlet-name> appfuse</servlet-name>
                    <url-pattern>*.do</url-pattern>      //处理以什么方式结尾的动作
          </servlet-mapping>

       2,根据appfuse 找到 appfuse-servlel.xml 。这个是spring mvc非常重要的配置文件。注明了每一次跳转动作进入的控制器,注入相应的dao层,业务层,以及commond层
   程序会根据/person.do 找到相应的控制器:com.nbw.test.web.action.PersonController。
      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver">
   <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>  
   <property name="prefix" value="/WEB-INF/jsp/"/>   //这个是跳转页面的路径
   <property name="suffix" value=".jsp"/>                   //指定跳转路径下以什么结尾的文件
</bean>

<bean class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver" id="paramResolver">
   <property name="paramName" value="do"/>   //这个在指定当控制器有多方法的时候,使用什么样的参数名来获得方法 例如:person.do?do=toEditPage
</bean>
  
//下面当url为person.do的时候请求进入PersonController控制器。
<bean class="com.nbw.test.web.action.PersonController" name="/person.do">
   <property name="methodNameResolver">
    <ref bean="paramResolver"/>         //这是当控制器需要实现多个方法的时候,指定使用哪个方法名,引用上面
   </property>
   <property name="sessionForm">    //是否把form放入session,如果选true,会将form存入session,当再次实例form的时候会根据名字从session取,如果选false则会重新新建一个
    <value>false</value>                        
   </property>
   <property name="commandClass">    //使用哪个command存储页面传过来的参数
    <value>com.nbw.test.domain.Person</value>
   </property>
</bean>
   3,进入com.nbw.test.web.action.PersonController控制器。PersonController     extends AbstractMultiActionFormController extends AbstractFormController extends BaseCommandController
这几个类是spring的核心类,他们会根据appfuse-servlel.xml 里面的配置信息,处理相应的参数,验证以及返回到哪个页面!
   程序会进入AbstractFormController类的handleRequestInternal方法。

   /**
* Handles two cases: form submissions and showing a new form.
* Delegates the decision between the two to {@link #isFormSubmission},
* always treating requests without existing form session attribute
* as new form when using session form mode.
* @see #isFormSubmission
* @see #showNewForm
* @see #processFormSubmission
*/
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
    throws Exception {

   // Form submission or new form to show?
   //这里会判断是不是post请求如果是就进行判断,如果不是就新建一个

   if (isFormSubmission(request)) {
    // Fetch form object from HTTP session, bind, validate, process submission.
    try {
   // 开始绑定参数,程序会根据appfuse-servlel.xml 指定的 sessionform为ture或者false来决定是从session里面去还是新建一个实例,如果为false进入 formBackingObject 方法,然后程序会调用createCommand方法,在createCommand方法spring会使用 BeanUtils.instantiateClass(this.commandClass)来将参数注入form
     Object command = getCommand(request);
     ServletRequestDataBinder binder = bindAndValidate(request, command);
     BindException errors = new BindException(binder.getBindingResult());
//因为spring不支持 属性为日期型的转换 需要改写这个方法
   //this.convertStringToDate(request, command);
   //在这个方法里程序会根据?do=toEditPage的toEditPage,方法使用反射调用这个方法

     return processFormSubmission(request, response, command, errors);
    }
    catch (HttpSessionRequiredException ex) {
     // Cannot submit a session form if no form object is in the session.
     if (logger.isDebugEnabled()) {
      logger.debug("Invalid submit detected: " + ex.getMessage());
     }
     return handleInvalidSubmit(request, response);
    }
   }

   else {
    // New form to show: render form view.
    return showNewForm(request, response);
   }
}

/**
* Return the form object for the given request.
* <p>Calls {@link #formBackingObject} if not in session form mode.
* Else, retrieves the form object from the session. Note that the form object
* gets removed from the session, but it will be re-added when showing the
* form for resubmission.
* @param request current HTTP request
* @return object form to bind onto
* @throws org.springframework.web.HttpSessionRequiredException
* if a session was expected but no active session (or session form object) found
* @throws Exception in case of invalid state or arguments
* @see #formBackingObject
*/
protected final Object getCommand(HttpServletRequest request) throws Exception {
   // If not in session-form mode, create a new form-backing object.
//假如不从session里取
   if (!isSessionForm()) {
    return formBackingObject(request);
   }

   // Session-form mode: retrieve form object from HTTP session attribute.
   HttpSession session = request.getSession(false);
   if (session == null) {
    throw new HttpSessionRequiredException("Must have session when trying to bind (in session-form mode)");
   }
   String formAttrName = getFormSessionAttributeName(request);
   Object sessionFormObject = session.getAttribute(formAttrName);
   if (sessionFormObject == null) {
    throw new HttpSessionRequiredException("Form object not found in session (in session-form mode)");
   }

   // Remove form object from HTTP session: we might finish the form workflow
   // in this request. If it turns out that we need to show the form view again,
   // we'll re-bind the form object to the HTTP session.
   if (logger.isDebugEnabled()) {
    logger.debug("Removing form session attribute [" + formAttrName + "]");
   }
   session.removeAttribute(formAttrName);

   return currentFormObject(request, sessionFormObject);
}

protected final Object createCommand() throws Exception {
if (this.commandClass == null) {
throw new IllegalStateException( "Cannot create command without commandClass being set - " +
"either set commandClass or (in a form controller) override formBackingObject ");
}
if (logger.isDebugEnabled()) {
logger.debug( "Creating new command of class [ " + this.commandClass.getName() + "] ");
}
return BeanUtils.instantiateClass(this.commandClass);//就这里!!!
}


//利用反射机制调用控制器里的方法
protected ModelAndView processFormSubmission(HttpServletRequest request,
                                                 HttpServletResponse response, Object command, BindException errors)
            throws Exception
            {

                if (errors.hasErrors()) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Data binding errors: " + errors.getErrorCount());
                    }
                    return showForm(request, response, errors);
                } else {
                    String methodName = methodNameResolver.getHandlerMethodName(request);
                    Method method = null;
                    Method[] methods = this.getClass().getMethods();
      for(int i = 0; i <methods.length ; i++){
       if(methods[i].getName().equals(methodName)){
        method = methods[i];
       }
      }
                  //java
      //Class dd= (Class<T>)((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
      //method = getClass().getMethod(methodName,new Class[]{HttpServletRequest.class, HttpServletResponse.class, (Class<T>)((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0], BindException.class});
                  // method = getClass().getMethod(methodName,new Class[]{HttpServletRequest.class, HttpServletResponse.class, getCommandClass(), BindException.class});

      List params = new ArrayList(4);
      params.add(request);
      params.add(response);
      //Java 5.0
      params.add(getCommandClass().cast(command));
      //Java 1.4
      //params.add(command);
      params.add(errors);
      try{
       return (ModelAndView) method.invoke(this, params.toArray(new Object[params.size()]));
      }
      catch (InvocationTargetException e){
            //找到实际的异常,并抛出
            throw (Exception)e.getTargetException();
      }
      catch(Exception e){
       throw e;
      }
                }
            }

//然后调用 PersonController类的toEditPage方法command已经设置好
//new ModelAndView("test/personEdit","person",command);这个会根据在appfuse-servlel.xml 文件里面的
//<property name="prefix" value="/WEB-INF/jsp/"/>获得路径 /web-inf/jsp/text/
//再根据<property name="suffix" value=".jsp"/>得到返回文件后缀名personEdit.jsp
//所以总的路径是/web-inf/jsp/text/personEdit.jsp
//将command放到person里。person是model名字,command是object。实际是map。在页面根据person取。
/**
* 转向编辑页面
*
* @param request
* @param response
* @param command
* @param errors
* @return
*
* @throws ServletException, IOException
*/
public ModelAndView toEditPage(HttpServletRequest request,
    HttpServletResponse response, Person command, BindException errors)
    throws ServletException, IOException {
   String id = request.getParameter("objectId");
   command = this.personmanager.findById(id);
   return new ModelAndView("test/personEdit","person",command);
}

分享到:
评论

相关推荐

    spring MVC简单示例

    这个"spring MVC简单示例"是为了帮助初学者理解Spring MVC的基本工作原理和配置,通过实践这个例子,你可以了解到如何创建一个简单的Controller、配置视图解析器并建立一个基本的请求处理流程。随着对Spring MVC的...

    Spring MVC 简单Demo

    这个"Spring MVC 简单Demo"旨在帮助初学者理解如何设置和运行一个基本的Spring MVC项目。下面,我们将深入探讨Spring MVC的核心概念、工作原理以及如何创建一个简单的示例。 1. **Spring MVC 概述** Spring MVC是...

    Spring MVC jar包

    - **基本概念**:Spring MVC提供了一个灵活的MVC实现,包括请求映射、视图解析、模型绑定等功能。它通过DispatcherServlet作为前端控制器,负责接收请求并分发到相应的处理器。 - **组件**:主要包括Model、View、...

    Spring MVC简单例子

    Spring MVC 是一个强大的Java web...通过这个简单的例子,初学者可以全面地了解Spring MVC的工作原理和流程,为更深入的Web开发打下基础。实践中遇到的问题和解决方法也会加深对Spring MVC的理解,有助于提升开发技能。

    spring mvc 简单demo

    这个简单的Spring MVC Demo展示了如何使用基本的控制器、视图解析和模型数据交换。随着深入学习,你可以了解到更多高级特性,如拦截器、异常处理、国际化、Ajax支持以及使用模板引擎等。这个Demo只是一个起点,帮助...

    spring mvc简单的例子和教程

    在本教程中,我们将深入探讨Spring MVC的基本概念、配置、以及如何创建一个简单的示例。 首先,Spring MVC的核心概念包括DispatcherServlet、Controller、Model、View和ViewResolver。DispatcherServlet是Spring ...

    Spring MVC 4.2.3

    7. **多视图解析器**:Spring MVC支持多种视图解析器,如JSP、FreeMarker、Thymeleaf等,可以根据项目需求灵活选择。 8. **模板引擎集成**:例如,与Thymeleaf的集成使得开发者能编写声明式逻辑的模板,提高了视...

    最全最经典spring-mvc教程

    Spring MVC 是一款强大的Java Web开发框架,用于构建高效、可维护和模块化的Web应用程序。它作为Spring框架的一部分,提供了一种优雅的方式来处理HTTP请求和响应,使得开发者可以专注于业务逻辑而不是底层实现。在这...

    Spring MVC 教程快速入门 深入分析

    Spring MVC简单易用,可以快速提高开发效率,且性能优秀,社区活跃,文档丰富。由于支持注解配置,使得框架更加易用。相较于Struts2,Spring MVC避免了一些可能导致性能下降的特性,如值栈、OGNL表达式等。 二、...

    Spring.MVC-A.Tutorial-Spring.MVC学习指南 高清可复制版PDF

    另外,Spring Boot的出现简化了Spring MVC的配置,通过自动配置和起步依赖,使得搭建Spring MVC项目变得更加简单。 除此之外,Spring MVC还支持数据绑定、验证、本地化、主题、异常处理等功能。例如,使用@...

    Spring MVC简单示例

    在压缩包`spring_mvc_01`中,可能包含了基本的Spring MVC项目结构,如`web.xml`配置文件、Spring MVC配置类、控制器类以及简单的JSP视图。通过分析这些文件,你可以更直观地学习如何配置和运行一个基本的Spring MVC...

    spring mvc 4.0

    7. **视图解析**:Spring MVC 4.0支持多种视图技术,如JSP、FreeMarker、Thymeleaf等,视图解析器可以根据配置自动选择合适的视图技术。 8. **异步处理**:Spring MVC 4.0引入了异步请求处理,通过@...

    Mastering Spring MVC 4(2015.09)源码

    视图解析器是Spring MVC中用于确定视图名对应的实际资源路径的组件。例如,InternalResourceViewResolver可以将视图名转换为JSP页面的URL。 依赖注入(Dependency Injection, DI)是Spring框架的核心特性之一。在...

    学习Spring MVC,关于注解的Spring MVC,简单例子,关于控制器的Spring MVC,学习Spring,简单Spring MVC实例

    在本教程中,我们将深入探讨Spring MVC的核心概念,特别是关于注解的使用以及简单的控制器实现。 首先,Spring MVC的核心组件包括DispatcherServlet、Controller、ModelAndView、ViewResolver等。DispatcherServlet...

    Spring MVC简单案例

    本案例将带您深入理解Spring MVC的基本概念和核心组件,并通过一个简单的实例来演示其工作流程。 1. **Spring MVC架构** Spring MVC的架构主要包括DispatcherServlet、Controller、Model、View和ViewResolver等...

    spring mvc框架依赖全面jar

    `org.springframework.web.servlet-3.1.1.RELEASE.jar` 是Spring MVC的主要组件,它负责处理HTTP请求,提供模型-视图-控制器的实现,包括控制器、视图解析和模型数据绑定等功能。 `org.springframework.web-3.1.1....

    Spring MVC所需jar包

    2. **Spring MVC 模块**:`spring-webmvc.jar` 是 Spring MVC 的核心组件,它实现了 MVC 设计模式,提供请求处理、视图解析等功能。这个 jar 包是构建基于 Spring 的 Web 应用必不可少的。 3. **Spring Web 模块**...

    spring mvc jar包

    以上这些库构成了 Spring MVC 开发的基础环境,开发者可以利用它们来创建控制器、定义模型、配置视图解析器,以及实现事务管理、数据访问等复杂功能。通过 Spring MVC,开发者能够以声明式的方式组织应用程序,提高...

Global site tag (gtag.js) - Google Analytics