Spring MVC简单入门

Spring MVC简单入门

  1. 概述

    1. Spring MVC是Spring框架的web层的解决方案

    2. Spring MVC框架提供了MVC(模型 - 视图 - 控制器)架构和用于开发灵活和松散耦合的Web应用程序的组件。 MVC模式导致应用程序的不同方面(输入逻辑,业务逻辑和UI逻辑)分离,同时提供这些元素之间的松散耦合。

      1. M: model(模型):封装了程序数据,通常是一些POJO类组成的。
      2. V: view(视图):负责绚烂模型数据,生成浏览器可以解析的HTML。
      3. C:controller(控制器):负责处理用户请求并构建相应的数据模型,然后将其传递给视图进行数据渲染。
    3. 引用Spring官方文档的话:

      • Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, “Spring Web MVC,” comes from the name of its source module (spring-webmvc), but it is more commonly known as “Spring MVC”.
        
      • 意思是Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就包含在Spring Framework中。正式名称“Spring Web MVC”来自其源模块(spring-webmvc)的名称,但它通常被称为“Spring MVC”。

  2. 使用配置的方式构建一个Spring MVC项目

    1. 编写pom文件:

      •  <dependencies>
             <dependency>
                 <groupId>org.springframework</groupId>
                 <artifactId>spring-context</artifactId>
                 <version>4.3.21.RELEASE</version>
             </dependency>
             <dependency>
                 <groupId>org.springframework</groupId>
                 <artifactId>spring-context-support</artifactId>
                 <version>4.3.21.RELEASE</version>
             </dependency>
             <dependency>
                 <groupId>org.springframework</groupId>
                 <artifactId>spring-web</artifactId>
                 <version>4.3.21.RELEASE</version>
             </dependency>
             <dependency>
                 <groupId>org.springframework</groupId>
                 <artifactId>spring-webmvc</artifactId>
                 <version>4.3.21.RELEASE</version>
             </dependency>
             <dependency>
                 <groupId>javax.servlet</groupId>
                 <artifactId>servlet-api</artifactId>
                 <version>2.5</version>
                 <scope>provided</scope>
             </dependency>
             <dependency>
                 <groupId>javax.servlet.jsp</groupId>
                 <artifactId>jsp-api</artifactId>
                 <version>2.2</version>
                 <scope>provided</scope>
             </dependency>
             <dependency>
                 <groupId>javax.servlet</groupId>
                 <artifactId>jstl</artifactId>
                 <version>1.2</version>
             </dependency>
         </dependencies>
         <build>
           <finalName>SpringMVC01</finalName>
           <plugins>
             <plugin>
               <groupId>org.apache.tomcat.maven</groupId>
               <artifactId>tomcat7-maven-plugin</artifactId>
               <version>2.2</version>
               <configuration>
                 <uriEncoding>UTF-8</uriEncoding>
                 <path>/SpringMVC01</path>
                 <port>8080</port>
               </configuration>
             </plugin>
           </plugins>
         </build>
        
    2. 编写web.xml文件

      •  <!DOCTYPE web-app PUBLIC
          "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "http://java.sun.com/dtd/web-app_2_3.dtd" >
         <web-app>
           <display-name>Archetype Created Web Application</display-name>
           <servlet>
             <servlet-name>springmvc</servlet-name>
             <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
           </servlet>
           <servlet-mapping>
             <servlet-name>springmvc</servlet-name>
             <url-pattern>*.action</url-pattern>
           </servlet-mapping>
         </web-app>
        
    3. 准备Spring MVC的配置文件

      • 默认情况下必需放在WEB-INF下

      • 该文件的命名是-servlet.xml。(但是该文件的名称和路径都可以更改)

      • 如我这里配置文件名字就是springmvc-servlet.xml

    4. 编写后端控制器

      • package com.fxyh.springmvc.web;
        
        import org.springframework.web.servlet.ModelAndView;
        import org.springframework.web.servlet.mvc.Controller;
        
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        
        public class HelloController implements Controller {
            @Override
            public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
                ModelAndView modelAndView = new ModelAndView();
                modelAndView.addObject("info", "Hello World Spring Mvc");
                modelAndView.setViewName("success");
                return modelAndView;
            }
        
        }
        
    5. 编写JSP文件(success.jsp)

      • <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
        <html>
        <head>
            <title>Title</title>
        </head>
        <body>
        ${info}
        </body>
        </html>
        
    6. 编写Spring MVC配置文件

      • <?xml version="1.0" encoding="UTF-8"?>
        <beans xmlns="http://www.springframework.org/schema/beans"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        
            <!-- 映射处理器 -->
            <bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
        
            <!-- 映射适配器 -->
            <bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
        
            <!-- 视图解析器 -->
            <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="prefix" value="/WEB-INF/pages/"/>
                <property name="suffix" value=".jsp"/>
            </bean>
        
            <!-- 后端控制器 -->
            <bean id="helloController" name="/hello.action" class="com.fxyh.springmvc.web.HelloController"/>
        </beans>
        
    7. 目录结构图

      • 在这里插入图片描述
  3. Spring MVC默认配置

    • 在这里插入图片描述

    • # Default implementation classes for DispatcherServlet's strategy interfaces.
      # Used as fallback when no matching beans are found in the DispatcherServlet context.
      # Not meant to be customized by application developers.
      
      org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
      
      org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
      
      org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
      org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
      
      org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
      org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
      org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
      
      org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
      org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
      org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
      
      org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
      
      org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
      
      org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
      
    1. 映射处理器(HandlerMapping)

      • 在这里插入图片描述

      • BeanNameUrlHandlerMapping(配置方式)

      • DefaultAnnotationHandlerMapping(注解方式)

    2. 映射适配器(HandlerAdapter)

      • 在这里插入图片描述

      • SimpleControllerHandlerAdapter(配置方式)

      • HttpRequestHandlerAdapter(配置方式)

      • AnnotationMethodHandlerAdapter(注解方式)

    3. 视图解析器(ViewResolver)

      • 在这里插入图片描述

      • InternalResourceViewResolver(配置和注解方式)

    4. 异常处理(HandlerExceptionResolver)

      • 在这里插入图片描述

      • DefaultHandlerExceptionResolver(配置方式)

      • AnnotationMethodHandlerExceptionResolver(注解方式)

      • ResponseStatusExceptionResolver(注解方式)

  4. 关于Spring MVC配置文件重命名问题:

    1. 默认情况下为WEB-INF下的-servlet.xml

    2. 真实开发中:

       <servlet>
         <servlet-name>springmvc</servlet-name>
         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
         <init-param>
           <param-name>contextConfigLocation</param-name>
           <param-value>classpath*:springmvc.xml</param-value>
         </init-param>
       </servlet>
       <servlet-mapping>
         <servlet-name>springmvc</servlet-name>
         <url-pattern>*.action</url-pattern>
       </servlet-mapping>
      
      1. 在servlet配置的时候添加初始化参数,指定contextConfigLocation参数
  5. 关于映射处理器问题

    • 多个映射路径映射到了同一个后端控制器

      • <bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
           <bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
               <property name="mappings">
                   <props>
                       <prop key="/abc.action">handlerMappingController</prop>
                       <prop key="/handlerMapping.action">handlerMappingController</prop>
                   </props>
               </property>
             <!--<property name="order" value="1"/>-->
           </bean>
        <bean id="handlerMappingController" name="/handlerMapping.action" class="com.fxyh.springmvc.web.HandlerMappingController"/>
        
      • 上述场景下,会执行handlerMapping处理器,因为从上而下执行,先找到上面的handlerMapping的处理器,所以直接解析了,所以两个处理器换一个位置就可以换一个处理器执行。

      • 处理器也可以设置order,数值越小的优先级越高,配置方式如上注释的property。

      • 如果多个映射处理器中配置了order的优先级比没有配置order的高,从上而下执行的情况只有所有的处理器都没有配置order属性的时候才有效。

      • 怎么看是执行哪个处理器?
        • org.springframework.web.servlet.DispatcherServlet的doDispatch方法里面

        • 在这里插入图片描述

        • 在这里打上断点,然后查看mappedHandlerd的值

        • 在这里插入图片描述

  6. 关于映射适配器问题

    • 后端控制器的执行方法(handleRequest)是由适配器调用。

    • 适配器来适配后端控制器实现的接口

      • 如:HelloController实现Controller接口,那么使用SimpleControllerHandlerAdapter适配器可以成功调用

      • 如:

        • package com.fxyh.springmvc.web;
          
          import org.springframework.web.HttpRequestHandler;
          
          import javax.servlet.ServletException;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          import java.io.IOException;
          
          public class HandlerAdapterController implements HttpRequestHandler {
           @Override
           public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
               request.setAttribute("info", "http request handler");
               request.getRequestDispatcher("/WEB-INF/pages/adapter/success.jsp").forward(request, response);
           }
          }
          
          
        • 这个Controller实现的是HttpRequestHandler接口,使用SimpleControllerHandlerAdapter那么就会报错误

          • javax.servlet.ServletException: No adapter for handler [com.fxyh.springmvc.web.HandlerAdapterController@517db47a]
        • 如果要让这个正常使用,必须要改适配器

          • <!-- 映射适配器 -->
            <bean id="handlerAdapter1" class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
            <bean id="handlerAdapter2" class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
            
          • 使用HttpRequestHandlerAdapter适配器来适配,这里测试的时候这样玩,实际开发中是不会的,最好统一风格

  7. 关于跳转问题

    1. 服务器端跳转(转发)

      1. modelAndView.setViewName("forward/success");
        
      2. modelAndView.setViewName("forward:/WEB-INF/pages/forward/success.jsp");
        
      3. // 第三种: 只适合在后端控制器实现了HttpRequestHandler接口的时候
        request.getRequestDispatcher("/WEB-INF/pages/forward/success.jsp").forward(request,response);
        
      4. View view = new JstlView("/WEB-INF/pages/forward/success.jsp");
        modelAndView.setView(view);
        
    2. 重定向

      1. public class RedirectController implements Controller {
         @Override
         public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
             ModelAndView modelAndView = new ModelAndView();
             modelAndView.addObject("info", "redirect");
             modelAndView.setViewName("redirect:/redirectResult.action");
             return modelAndView;
         }
        }
        
      2. public class RedirectResultController implements Controller {
         @Override
         public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
             ModelAndView modelAndView = new ModelAndView();
             modelAndView.setViewName("redirect/success");
             return modelAndView;
         }
        }
        
      3. 属性值取不到了,但是会做成http://localhost:8787/SpringMVC01/redirectResult.action?info=redirect

  8. 后端控制器

    1. MultiActionController

      • package com.fxyh.springmvc.web;
        
        import org.springframework.web.servlet.ModelAndView;
        import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
        
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        
        public class UserController extends MultiActionController {
        
            public ModelAndView add(HttpServletRequest request, HttpServletResponse response) {
                System.out.println("add");
                return null;
            }
        
            public ModelAndView delete(HttpServletRequest request, HttpServletResponse response) {
                System.out.println("delete");
                return null;
            }
        
            public ModelAndView update(HttpServletRequest request, HttpServletResponse response) {
                System.out.println("update");
                return null;
            }
        
            public ModelAndView list(HttpServletRequest request, HttpServletResponse response) {
                System.out.println("list");
                return null;
            }
        }
        
      • <bean id="methodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
            <property name="paramName" value="method"/>
        </bean>
        
        <bean id="userController" name="/user.action" class="com.fxyh.springmvc.web.UserController">
            <property name="methodNameResolver" ref="methodNameResolver"></property>
        </bean>
        
      • http://localhost:8787/SpringMVC02/user.action?method=update 会调用UserController的update方法

      • http://localhost:8787/SpringMVC02/user.action?[paramName]=方法名 的方式来通过不同的参数值来调用不同的方法

    2. ServletForwardingController

      • package com.fxyh.springmvc.servlet;
        
        import javax.servlet.ServletException;
        import javax.servlet.ServletRequest;
        import javax.servlet.ServletResponse;
        import javax.servlet.http.HttpServlet;
        import java.io.IOException;
        
        public class DemoServlet extends HttpServlet {
            private static final long serialVersionUID = 2206792018849975111L;
        
            @Override
            public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
                System.out.println("进来了");
            }
        }
        
      • <servlet>
          <servlet-name>demoServlet</servlet-name>
          <servlet-class>com.fxyh.springmvc.servlet.DemoServlet</servlet-class>
        </servlet>
        
      • <bean id="servletForwardingController" name="/servlet.action" class="org.springframework.web.servlet.mvc.ServletForwardingController">
            <property name="servletName" value="demoServlet"/>
        </bean>
        
      • 这里在web.xml中配置的servlet可以不配置servlet-mapping,这里请求servlet.action就会转发到DemoServlet。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值