zoukankan      html  css  js  c++  java
  • JAVA框架-SpringMVC1(配置和入门程序)

    Spring入门

    SpringMVC框架概述

    Spring Web MVC是基于Servlet API构建的传统Web框架,并且从一开始就已包含在Spring框架中

    与Spring Web MVC并行,Spring Framework 5.0引入了一个新的反应式Web框架,其名称“ Spring WebFlux;

    理解:

    首先SpringMVC 是一个MVC构架模式的web框架,是基于Servlet的,从Spring第一个版本就一起推出了,

    传统web框架,指的是SpringMVC依然使用多线程同步并发的方式来处理请求,现如今大家都在鼓吹异步并发多么多么好,从测试数据来看异步并发效率的确更好,但是其并不成熟,极大多数公司项目还没有更新到异步技术,盲目的进行重构可能会引发更多的问题, 并且异步编程在代码结构上会产生较大的变化,对于初学者而言,掌握难度是较大的;

    构架图:

    SpringMVC在系统中的位置:

    可以看出

    SpringMVC 并没有代替Servlet,它只是在Servlet上提供了一套封装好的组件,提高开发效率;

    还使得开发出的项目更加规范;否则每个人可能有每个人不同的MVC;

    SpringMVC核心组件

    思考:

    若没有SpringMVC框架,我们该如何去编写一个较大的web项目呢,可以发现在选课系统中出现了大量的Servlet,因为一个请求地址就需要一个Servlet,使得项目体积变大,且Servlet是长期存在内存的;

    第一步,我们希望用一个Servlet来处理多个请求甚至是所有请求,就需要实现能根据请求路径查找处理请求方法的逻辑,这也是SpringMVC要做的第一件事情;

    • DispatcherServlet:前端控制器
      用户请求首先到达前端控制器,它就相当于mvc模式中的c,DispatcherServlet是整个流程控制的调度中心,由它调用其它组件处理用户的请求,DispatcherServlet的存在降低了组件之间的耦合性。
    • Handler:处理器
      Handler是继DispatcherServlet前端控制器的后端控制器,DispatcherServlet会将请求发送至对应的Handler来进行处理。Handler是处理业务逻辑的地方,需要我们自己来编写具体代码,等同于之前的Service层
    • HandlerMapping:处理器映射器
      HandlerMapping负责根据用户请求路径找到Handler,springmvc提供了不同的映射器实现不同的映射方式,例如:BeanName映射,配置文件映射,注解映射等。
    • HandlAdapter:处理器适配器
      通过HandlerAdapter来执行Handler,因为Handler有不同形式,意味着调用方式是不同的,这是适配器模式的应用,我们也可以扩展适配器来实现新的Handler;
    • ViewResolver:视图解析器
      ViewResolver负责从Handler中获取数据和视图,根据逻辑视名称查找物理视图文件,并查找View对象,再生成View对象;
    • View:视图
      View的职责就是装配数据,SpringMVC框架提供了很多的View视图类型的支持,包括:jstlView、freemarkerView、pdfView等。常用视图就是jsp。我们需要根据业务需求,通过页面标签或页面模版技术将模型数据展示给用户

    当然还有一些其他的

    类型 说明
    HandlerExceptionResolver Handler异常处理器
    LocaleResolver 提供国际化的视图。根据不同地区显示不同内容
    ThemeResolver 根据不同地区提供个性化的布局
    MultipartResolver 解析multipart请求数据,如浏览器表单文件上传
    FlashMapManager 常用于通过重定向将属性从一个请求传递到另一个请求

    可以用一张图来整合上述关系

    入门程序

    编写两个简单的页面:

    第一个:indel.jsp

    <%--
      Created by IntelliJ IDEA.
      User: 17390
      Date: 2020/7/3
      Time: 11:16
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    
    
    <h1>${1+4}</h1>
    </body>
    </html>
    
    

    第二个info.jsp

    这个页面用于反馈我们后端提供的信息。

    <%--
      Created by IntelliJ IDEA.
      User: 17390
      Date: 2020/7/3
      Time: 14:10
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    
    <h1> username:${username}</h1>
    
    </body>
    </html>
    
    

    pom依赖

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>org.example</groupId>
      <artifactId>MVC01</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>war</packaging>
    
      <name>MVC01 Maven Webapp</name>
      <!-- FIXME change it to the project's website -->
      <url>http://www.example.com</url>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
      </properties>
    
      <dependencies>
        <!--   SpringMVC -->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>5.2.2.RELEASE</version>
        </dependency>
    
        <!--JEE相关的-->
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>jstl</artifactId>
          <version>1.2</version>
        </dependency>
        <dependency>
          <groupId>javax.servlet.jsp</groupId>
          <artifactId>javax.servlet.jsp-api</artifactId>
          <version>2.3.3</version>
          <scope>provided</scope>
        </dependency>
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>4.0.1</version>
          <scope>provided</scope>
        </dependency>
      </dependencies>
    </project>
    
    

    XML配置:

    与在web项目中使用Spring中相同的是,我们也需要让SpringMVC随着web项目启动,SpringMVC的做法是利用DIspatcherServlet;

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
    
        <!--        注意要更改打包的方式-->
        <packaging>war</packaging>
        
        <servlet>
            <!--   配置mvc的核心控制器 -->
            <servlet-name>DispatcherServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<!--  指定Spirng配置文件-->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc.xml</param-value>
            </init-param>
            <!-- 在应用程序启动时候,自动加载控制器-->
            <load-on-startup>0</load-on-startup>
        </servlet>
    
    <!--    要交给SpringMVC处理的请求-->
        <servlet-mapping>
            <servlet-name>DispatcherServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>
    
    

    DispatcherServlet做了两个事情,1:初始化一个Spring容器,2:注册一个Servlet

    SpringMVC本质上也是一个Spring容器,在不涉及WEB时使用方法和Spring没有任何区别;ß

    Url-patten

    只有请求地址能够匹配到到被DispatcherServlet的url-pattern的请求才会被SpringMVC处理,那么那些请求要交给SpringMVC处理呢,通常是除静态资源以外的请求;

    常用pattern:

    pattern 说明
    / 除了.jsp 以外的所有请求
    /* 所有请求
    *.action 所有 以action结尾的请求

    需要说明的是action并不是固定的不同公司可能不同,但无论是点什么,其目的都是为了和静态资源加以区分

    创建控制器类:

    package controller;
    
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.mvc.Controller;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * Created by Jeason Luna on 2020/7/3 14:07
     */
    public class UserController implements Controller {
        @Override
        public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
    
            httpServletRequest.setCharacterEncoding("UTF-8");
            System.out.println("aaaaaaaaaaaa!!!");
            ModelAndView modelAndView = new ModelAndView();
            //设置页面需要的数据
            modelAndView.addObject("username","jeason");
            //设置视图的文件名称
            modelAndView.setViewName("info.jsp");
    		//返回模型和视图给dispatcherServlet
            return modelAndView;
        }
    }
    
    

    ModelAndView,其实就是把视图资源和数据打包到一起,然后视图名称交给视图解析器,Object放到请求中;

    注册控制器到容器中:

    <?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">
    
    
        <!-- 通过映射名称(name)来告诉Spring这个Bean能处理哪个url
     		默认就是把请求映射到handle上面-->
        <bean name="/userInfo" class="controller.UserController"/>
    </beans>
    

    DispatcherServlet是按照请求路径来查找Handler,我们必须告诉SpringMVC,这个控制器是用来处理哪个请求地址的,默认情况下,SpringMVC会查找beanName与请求地址相同的Handler来处理;

    测试:

    打开网址:http://localhost:8080/day41_SpringMVCDemo1/ 可以得到我们的indel.jsp

    打开网址:http://localhost:8080/day41_SpringMVCDemo1/userInfo 可以得到我们的indel.jsp

    使用注解

    虽然我们通过上述的方式实现了基本的功能,但是我们发现了一个问题,我们的SpringMVC的框架是帮助我们去整合各种请求操作的,我们现在并没有达成现在这样的需求,依然要一个url请求对应一个controller调用。即使我们让多个url请求去对应一个controller调用,因为controller类中只有一个方法,我们也不可能去实现不同调用对应不同的功能。

    所以我们需要一种更为明晰的url和controller的对应关系,注解的方式可以帮助来实现这个需求。

    我们重新建立一个控制类文件:

    package controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.ModelAndView;
    
    /**
     * Created by Jeason Luna on 2020/7/4 22:54
     */
    
    
    @Controller
    public class AnnotionController {
    
        @RequestMapping("/UserInfo")
        public ModelAndView UserInfo(){
            System.out.println("UserInfo is working!!!!!!");
            ModelAndView t = new ModelAndView();
            t.addObject("username","UserInfo is working!!!!!!");
            t.setViewName("info.jsp");
            return t;
    
        }
    
        @RequestMapping("/UserLogin")
        public ModelAndView UserLogin(){
            System.out.println("UserLogin is working!!!!!!");
            ModelAndView t = new ModelAndView();
            t.addObject("username","UserLogin is working!!!!!!");
            t.setViewName("info.jsp");
            return t;
        }
    }
    
    

    首先添加注解@Controller,在这个类中我们通过@RequestMapping的参数来指定url和调用方法间的映射关系,从而实现多个url映射不同的调用方法

    注意,这里我们要注释原来放入Spring容器中的Bean对象,并且开启注解扫描,故配置文件修改如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
    <!--    <bean name="/useInfo" class="controller.UserController"/>-->
    
        <!-- 启动扫描注解-->
        <context:component-scan base-package="controller"/>
    </beans>
    

    测试:

    打开网址:http://localhost:8080/day41_SpringMVCDemo1/UserInfo 可以得到我们的indel.jsp

    打开网址:http://localhost:8080/day41_SpringMVCDemo1/UserLogin 可以得到

    需要注意的是:
    viewName路径若不带/时则从当前请求的位置查找文件,带/则表示从根路径查找

    视图解析器配置

    视图解析器用于查找视图文件,及生成视图对象,我们不用过多关注,唯一会用到的就是,为视图名称配置前缀和后缀从而简化,Handler中的书写

    在一个实际项目中页面文件可能比较多,可以用文件夹管理,但是这导致我们在编写视图名称时更加繁琐,例如:

    handler中:

    这时就可在配置中对视图解析器进行相关设置;

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      <!--指定视图类型-->
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
      <!--指定前缀-->
        <property name="prefix" value="/pages/jsp/"/>
      <!--指定后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
    

    处理器中:

    @RequestMapping("/getMsg")
    public ModelAndView getMsg(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("index");
        modelAndView.addObject("msg","hello SpringMVC annotation!");
        return modelAndView;
    }
    

    视图解析器会自动在viewName前后分别拼接前缀和后缀;如:/pages/jsp/index.jsp

  • 相关阅读:
    数据库使用--MySQL: InnoDB 还是 MyISAM?
    数据库使用3--索引系列
    数据库使用1--注意事项
    数据库使用2--索引系列
    学习FFmpeg API
    几种常见 容器 比较和分析 hashmap, map, vector, list ...hash table
    tiny中文乱码问题,不过仅适用于windows,所以xml不可以出现中文
    【NumPy】numpy数组类型
    【1.1】Scrapy抓取4步走、新建项目
    django+markdown
  • 原文地址:https://www.cnblogs.com/JeasonIsCoding/p/13237861.html
Copyright © 2011-2022 走看看