SpringMVC

Spring MVC

一、概述

1.使用Java语言基本上都是开发B/S架构的程序,B/S架构又分成了三层架构

2.三层架构

  1. 表现层:WEB层,用来和客户端进行数据交互的。表现层一般会采用MVC的设计模型

  2. 业务层:处理公司具体的业务逻辑的

  3. 持久层:用来操作数据库的

表现层框架(MVC设计模式)

M model 模型 javabean

V view 视图 如jsp

C Controller 控制器 Servlet

二、组件

SpringMVC框架基于组件方式执行流程
1.DispatcherServlet:前端控制器

用户请求到达前端控制器,它就相当于 mvc 模式中的 c,dispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet 的存在降低了组件之间的耦合性。

2.HandlerMapping:处理器映射器

HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的 映射方式,例如:配置文件方式,实现接口方式,注解方式等。

3.Handler:处理器 :

它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由 Handler 对具体的用户请求进行处理。

4.HandlAdapter:处理器适配器

通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理 器进行执行。

5.View Resolver:视图解析器

View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名 即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。

6.View:视图

SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView 等。我们最常用的视图就是 jsp。 一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开
发具体的页面。

7.mvc:annotation-driven说明

在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。 使用mvc:annotation-driven 自动加载 RequestMappingHandlerMapping (处理映射器)和 RequestMappingHandlerAdapter ( 处 理 适 配 器 ) , 可 用 在 SpringMVC.xml 配 置 文 件 中 使 用 mvc:annotation-driven替代注解处理器和适配器的配置。

SpringMVC设计流程原理(图片来源黑马)

三、入门学习

3.1 web.xml 与 Spring.xml配置

web.xml:
<!--配置前端控制器dispatcherServlet-->
<servlet>   
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
		<!--初始化加载SpringMVC.xml-->
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:SpringMVC.xml</param-value>
    </init-param>
    <!--标记容器是否在启动的时候就加载这个servlet,>=0,启动,值越小,优先级越高-->
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
Spring.xml(建立在资源目录下):
<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans"  
       xmlns:mvc="http://www.springframework.org/schema/mvc"  
       xmlns:context="http://www.springframework.org/schema/context"  
       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   
                 http://www.springframework.org/schema/mvc    
                     http://www.springframework.org/schema/mvc/spring-mvc.xsd      
                       http://www.springframework.org/schema/context      
                         http://www.springframework.org/schema/context/spring-context.xsd">

    <!--注解扫描-->
    <context:component-scan base-package="cn.zzz"/>

    <!--配视图解析器-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--开启springMVC注解支持-->
    <mvc:annotation-driven/>
</beans>

3.2 requestMapping注解

可写在方法和类上

写在类上:第一级访问目录

方法上:第二级访问目录

作用:建立请求URL和处理请求方法之间的对应关系,即有请求时就去找带有这个注解的对应的方法。

属性:

value==path :作用用去指定请求的URL
method: 请求方式 get/post
params:指定限制请求参数的条件。
	*如: params="name=hehe" ,即请求参数必须带有name,值也是hehe
headers:注定限制请求消息头的条件

3.3 请求参数绑定

支持的数据类型:

1.基本数据类型
2.JavaBean
3.数组/集合类型

绑定用方法参数实现

例:
@RequestMapping(path = "/saveAccount")
    public String saveAccount(Account account){
        System.out.println(account);
        return "success";
    }

//Account里面还定义了另一个实体类User


jsp表单页面:
<form action="saveAccount" method="post">
  名字:<input type="text" name="accountName"/><br/>
  金额:<input type="text" name="money"/><br/>
  用户名:<input type="text" name="user.userName"/><br/>
  年龄:<input type="text" name="user.age"/><br/>
  <input type="submit" value="Save"/>
 </form>

调用User时使用 user.xxx ,集合类型也大致,如List[0].name

3.4配置过滤器解决post乱码:

在web.xml中加入以下内容
  <filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

注意!内容要加在<servlet>前,不然会报红

3.5 自定义类型转换:

SpringMVC能自动地将传入的String类型(无论定义什么类型,页面传回来的都是String类型)转成对应的类型,但当涉及某些格式,就会出问题。

如 Data类型,他只能识别2020/2/9,当我们写入2020-2-9,便会报错。

定义个方法接上Converter接口

public class StringToDateConverter implements Converter<String,Date> {

    @Override
    public Date convert(String s) {
        if (s == null) {
            throw new RuntimeException("请传入数据");
        }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return df.parse(s);
        } catch (Exception e) {
            throw  new RuntimeException("传入数据有误");
        }
    }
}

在SpringMVC.xml中加上:

 <!--配置自定义类型转换器-->
    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="cn.zzz.utils.StringToDateConverter"/>
            </set>
        </property>
    </bean>
	
 <!-- 开启SpringMVC框架注解的支持和开启类型转换支持 --> 
<mvc:annotation-driven  conversion-service="conversionService"/>

3.6 注解

  1. RequestParam:

    1. 作用:把请求中的指定名称的参数传递给控制器中的形参赋值
    2. 一般用于形参和实参名字不同
  2. RequestBody:

    1. 作用:用于获取请求体的内容(注意:get方法不可以)
  3. PathVariable:

    1. 作用: 拥有绑定url中的占位符的。例如:url中有/delete/{id},{id}就是占位符
    2. Restful风格的URL
      1. 请求路径一样,可以根据不同的请求方式去执行后台的不同方法
      2. restful风格的URL优点
        1. 结构清晰
        2. 符合标准
        3. 易于理解
        4. 扩展方便

    代码如下:

      @RequestMapping(path = "/hello/{id}")
         public String testPathVariable(@PathVariable(value = "id") String id){
             System.out.println(id);
             return "success";
         }
    
     <a href="hello/1">按!</a>
     控制台打印 1 
    
  4. RequestHeader:

    1. 作用:获取指定请求头的值
    2. 属性 value:请求头的名称
  5. CookieValue:

    1. 作用:用于获取指定cookie的名称的值
  6. ModelAttribute:

    1. 作用

      1. 出现在方法上:表示当前方法会在控制器方法执行前线执行。
      2. 出现在参数上:获取指定的数据给参数赋值。
    2. 使用方法

      1. 有返回值
      2. 无返回值,一般用map来存储
  7. SessionAttributes

    1. 作用:用于多次执行控制器方法间的参数共享

    2. 代码:

        /*
       向request域中存值
        */
       @RequestMapping(path = "/testSessionAttributes")
       public String testSessionAttributes(Model model){
           model.addAttribute("username","123");
           model.addAttribute("age",19);
           System.out.println("成功存");
           return "success";
       }
       /*
       取值
        */
       @RequestMapping(path = "/getSessionAttributes")
       public String getSessionAttributes(ModelMap modelMap){
           System.out.println(modelMap.get("username")+";"+modelMap.get("age"));
           return "success";
       }
       /*
       删除
        */
       @RequestMapping(path = "/delSessionAttributes")
       public String delSessionAttributes(SessionStatus sessionStatus){
           sessionStatus.setComplete();
           return "success";
       }
      
       ${requestScope}
       会向request域中存放(Model中设置的属性设置到Request 中)
      

3.7 Servlet原始API

可以在controller方法形参上定义requet和reponse
	@RequestMapping("")
   public void testAPI(HttpServletRequest request, HttpServletResponse response) throws Exception {
    //转发
    request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request, response);
    //重定向 注意:重定向无法找到WEB-INF目录下的页面
    response.sendRedirect(request.getContextPath() + "xxx.jsp");

    response.setCharacterEncoding("UTF-8");
    response.setContentType("text/html;charset=UTF-8");
}

3.8 ModelAndView

  1. ModelAndView对象是Spring提供的一个对象,可以用来调整具体的JSP视图

  2. 使用时将方法的返回值设为 ModelAndView

  3. ModelAndView对象被放置在Request对象中

  4. 代码如下:

      public ModelAndView testMAV(){
         ModelAndView mv = new ModelAndView();
         //设置跳转
         mv.setViewName("success");
         //添加对象
         mv.addObject("msg","hello!!");
    
         //类
         User user = new User();
         user.setAge(18);
         user.setUsername("zzz");
         user.setPassword("1234");
         mv.addObject("user",user);
         
     	//也可以是map/list等
         return mv;
     }
    

3.9 转发与重定向

转发:

controller 方法在提供了 String 类型的返回值之后,默认就是请求转发。我们也可以写成:

public String testForward(){
    return "forward:/WEB-INF/pages/success.jsp";
}

需要注意的是,如果用了 formward:则路径必须写成实际视图 url,不能写逻辑视图。 它相当于“request.getRequestDispatcher("url").forward(request,response)”。使用请求 转发,既可以转发到 jsp,也可以转发到其他的控制器方法。

重定向:
 public String testRedirect(){
       
        return "redirect:index.jsp";
    }

它相当于“response.sendRedirect(url)”。需要注意的是,如果是重定向到 jsp 页面,则 jsp 页面不 能写在 WEB-INF 目录中,否则无法找到。

静态资源拦截问题:

DispatcherServlet 会自动拦截 css,js,img等静态资源,可以在SpringMVC.xml中进行配置。

<!-- 设置静态资源不过滤 -->   
<mvc:resources location="/css/" mapping="/css/**"/>  <!-- 样式 -->   
<mvc:resources location="/images/" mapping="/images/**"/>  <!-- 图片 -->   
<mvc:resources location="/js/" mapping="/js/**"/>  <!-- javascript -->

3.10 json响应:

在pom.xml中加入:

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-annotations</artifactId>
  <version>2.10.2</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.10.2</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.10.2</version>
</dependency>

加入后 json数据可以和javabean对象相互转换。

  $(function(){
            $("#btn").click(function(){
                 alert("hello btn");
                // 发送ajax请求
                $.ajax({
                    // 编写json格式,设置属性和值
                    url:"user/testAjax",
                    contentType:"application/json;charset=UTF-8",
                    data:'{"username":"hehe","password":"123","age":30}',
                    dataType:"json",
                    type:"post",
                });

            });
        });



@RequestMapping(path = "/testAjax")
public  void testAjax(@RequestBody User user){
    System.out.println(user);
}

打印 :User{username='hehe', password='123', age=30}

3.11文件上传:

<!-- 配置文件解析器对象,要求id名称必须是multipartResolver -->   
 <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 
  <property name="maxUploadSize" value="10485760"/>   
 </bean>


  public String testUpload (HttpServletRequest request, MultipartFile upload) throws Exception{
    // 先获取到要上传的文件目录
    String path = request.getSession().getServletContext().getRealPath("/uploads");
    // 创建File对象,一会向该路径下上传文件
    File file = new File(path);
    if (!file.exists()){
        file.mkdirs();
    }

    //获取上传的文件名字
    String filename = upload.getOriginalFilename();
    String uuid = UUID.randomUUID().toString().replace("-"," ").toUpperCase();
    filename = filename + "_" +filename;

    upload.transferTo(new File(file,filename));
    return "success";
}

3.12 拦截器

Spring MVC 的处理器拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。 用户可以自己定义一些拦截器来实现特定的功能。
过滤器是 servlet 规范中的一部分,任何 java web 工程都可以使用。 拦截器是 SpringMVC 框架自己的,只有使用了 SpringMVC 框架的工程才能用。 过滤器在 url-pattern 中配置了/*之后,可以对所有要访问的资源拦截。 拦截器它是只会拦截访问的控制器方法,如果访问的是 jsp,html,css,image 或者 js 是不会进行拦 截的。 它也是 AOP 思想的具体应用。 我们要想自定义拦截器, 要求必须实现:HandlerInterceptor 接口。

配置拦截器:

 <!-- 配置拦截器 -->  
    <mvc:interceptors>      
        <mvc:interceptor>      
            <!-- 哪些方法进行拦截 -->    
            <mvc:mapping path="/user/*"/>          
            <!-- 哪些方法不进行拦截          
               <mvc:exclude-mapping path=""/>-->           
            <!-- 注册拦截器对象 -->            
            <bean class=""/>        
        </mvc:interceptor>    
    </mvc:interceptors>
  1. preHandle方法是controller方法执行前拦截的方法

    1. 可以使用request或者response跳转到指定的页面
    2. return true放行,执行下一个拦截器,如果没有拦截器,执行controller中的方法。
    3. return false不放行,不会执行controller中的方法。
  2. postHandle是controller方法执行后执行的方法,在JSP视图执行前。

    1. 可以使用request或者response跳转到指定的页面
    2. 如果指定了跳转的页面,那么controller方法跳转的页面将不会显示。
  3. postHandle方法是在JSP执行后执行

    1. request或者response不能再跳转页面了
posted @ 2020-02-12 21:17  喜欢悠哉独自在✘  阅读(30)  评论(0编辑  收藏