SpringMVC

1. SpirngMVC

1.1 概述

SpringMVC它是一种基于Java实现的MVC设计模型的请求驱动类型的轻量级Web框架.
它是通过一套注解,让一个简单的pojo类成为处理请求的控制器,基于pojo类中的方法,
一个方法就是之前的一个Servlet,无需实现任何接口,同时支持RESTful风格编程的请求. 
本质就是一个Servlet
MVC : Model View Controller
           Model : 主要用于数据的封装,=>pojo=>JavaBean
           View : 解析jsp,生成html页面=>jsp
           Controller : 控制器,用于服务器和客户端交互 一个Servlet
请求驱动类型 : 
    请求-相应类型

1.2 优势

1. 清晰的角色划分,分工明确
2. SpringMVC可以和Spring框架实现无缝衔接
3. 支持RESTful风格,简单的文件上传
4. 约定大于配置的契约式编程支持
5. 基于注解的零配置支持
6. 功能强大的数据验证,格式,绑定机制等等

1.3 快速入门

  • 导包
    Spring核心包,日志包,aop,web+webmvc+jstl,servlet,jsp
  • 创建数据库和表,创建controller包和类,在类上添加@Controller注解
  • 创建springMVC配置文件
  • 在web.xml配置前端控制器

        //假设已经从数据库查询到信息
        List<Role> list = new ArrayList<>();
        list.add(new Role(1,"学生","学习", new Date()));
        list.add(new Role(2,"老师","教课", new Date()));
        list.add(new Role(3,"副教授","研究", new Date()));
        list.add(new Role(4,"教授","研究", new Date()));
        list.add(new Role(5,"院士","研究", new Date()));
        list.add(new Role(6,"国士","荣誉,偶像", new Date()));
        ModelAndView modelAndView = new ModelAndView();
        //使用ModelAndView封装数据
        modelAndView.addObject("list",list);
        //使用ModelAndView跳转页面
        modelAndView.setViewName("/WEB-INF/view/role/roleList.jsp");
        return  modelAndView;
    }
}

配置文件applicationContext-mvc.xml

<context:component-scan base-package="com.zy"/>

web.xml

 <!--配置前端控制器 , 与servlet的一样-->
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--加载配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext-mvc.xml</param-value>
        </init-param>
        <!--加载时机,数字越小越先加载-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <!--建议使用扩展名进行配置-->
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>

1.4 SpringMVC架构

在这里插入图片描述

  • DispatcherServlet 前端控制器
    它是整个流程的控制中心,由它来调用其他组件处理用户的请求
    作用 : 降低组件之间的耦合性

  • HandlerMapping 处理器映射器
    负责根据用户url请i去找到Handler(处理器)
    springMVC提供了不同的映射器实现机制 : 配置文件方式,实现接口方式,注解方式等
    @RequestMapping(),就是采用注解方式,也是目前最流行的方式

  • Handler处理器
    handler是继前端控制器的后端控制器,在前端控制器调配下Handler对具体的用户进行请求处理

  • HandlerAdapter 处理器适配器
    通过HandlerAdapter对处理器进行解析执行. 主要是一种适配器模式的匹配

  • ViewResovler 视图解析器
    将处理结果生成View视图

  • View组件
    springMVC提供了很多个View视图,如jstlView,freemarkView,pdfView等,对于java开发来说,最常用的是jspView

  • 说明
    在springMVC各个组件中,处理器适配器, 处理器映射器, 视图解析器,我们称之为springMVC的三大组件. 可以认为一个中心三个基本点. 需要用户开发的组件有Handler和View

执行流程

  1. 项目启动,加载web.xml,开始加载DispatcherSerlvet(前端控制器),读取配置文件,创建spring容器,生成DispatcherServlet对象,存储在Spring容器中;通过组件扫描,把controller扫进spring容器中.
  2. 当客户端请求发送过来时,首先经过前端控制器,前端控制器根据请求的资源映射调用处理器映射器组件HandleMapping,匹配url,当匹配到url之后,把结果返回给前端控制器.
  3. 前端控制器收到结果后调用处理器适配器,来匹配具体是哪一个方法,当方法被匹配到后,如果方法上有参数,调用HttpMessageConverter,进行数据格式校验、数据封装。数据校验之后,开始把数据绑定到参数上,调用处理器来执行具体的方法业务内容.
  4. 处理器处理完,把结果返回给处理器你适配器,处理器适配器再把结果(ModelAndView)返回给前端控制器.
  5. 前端控制器根据结果来调用视图解析器,同时把view视图(String字符串表示的)传输给视图解析器ViewResovler视图解析器根据视图匹配服务器中到底哪一个视图(JSP视图)找到之后,把视图再返回给前端控制器.
  6. 前端控制器根据视图调用视图组件View,同时把视图信息传输给View组件,View组件开始解析,把逻辑视图转换成为物理视图,生成html页面,返回给前端控制器.前端控制器把html静态页面和model数据一块通过响应的方式发送给客户端.

1.5 相关组件的配置

为什么前面没有配置相关组件也可以正常使用呢?
因为在spring-webmvc的jar中有一个DispacherServlet.properties配置文件,当我们没有配置组件时,它会默认使用该配置文件的组件
  • 配置处理器映射器,处理器适配器
    <!--配置处理器映射器-->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
    <!--处理器映射器-->
    <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
  • 注解驱动
    在springMVC中提供了注解驱动加载处理器映射器和处理器适配器,所以上面的两行配置可以注释
    <!--注解驱动  涵盖处理器映射器和处理器适配器-->
    <mvc:annotation-driven/>
  • 视图解析器
    在这里主要用来做资源跳转
    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"/><!--前缀-->
        <property name="suffix" value=".jsp"/><!--后缀-->
    </bean>
  • 静态资源放行
    如果前端控制器在中采用缺省配置(/),就意味着要拦截当前的静态资源,需要开发者自己配置
    如果应用当中需要使用静态资源,此时就需要静态资源放行
    注意 : 此处有缓存,需要先清除浏览器的Cookie
  1. 方式一
    前端控制器本质就是Servlet, 在tomcat服务器内部配置对缺省配置有单独的处理,它采用的是静态资源放行.
    想要使用tomcat默认对缺省配置的处理,需要开启tomcat的缺省配置
    <!--方式一 采用tomcat默认的处理方式  开启tomcat的缺省配置-->
    <mvc:default-servlet-handler/>

2. SSM

开发步骤

  1. 导包
  2. 在resources资源文件夹下面新建两个目录。一个是spring(Spring的核心配置),一个是mybatis(核心配置)
  3. 把db.properties文件和log4j.properties文件导入到resources目录下。
  4. 在spring目录下创建springmvc.xml文件
    设置处理器映射器和处理器适配器的注解驱动
    开启扫描controller组件
    配置视图解析器 添加前后缀
    <!--开启注解驱动 配置 处理器映射器和处理器适配器-->
    <mvc:annotation-driven/>

    <!--开启扫描controller组件-->
    <context:component-scan base-package="com.zy.web.controller"/>

    <!--配置视图解析器 添加前后缀-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--静态资源放行配置-->
   <!-- <mvc:default-servlet-handler/>--
  1. 在spring目录下创建applicationContext-dao.xml

2.1参数绑定

  • @RequestParam注解使用
    请求参数绑定说明
    绑定机制:
    1. 表单提交数据都是以key-value的方式
    2. springMVC绑定过程是把表单提交的参数,作为控制器中方法的参数进行绑定的
    3. 要求提交的表单的name属性和参数名称必须一致

  • name属性 : 映射表单中提交的参数名称

  • required属性
    默认为true,一旦使用该注解,就必须指定name属性

  • defaultValue属性
    设定方法参数的默认值,如果表单中请求参数没有传输具体值,那么此时方法参数使用配置的默认值

public ModelAndView test03RequestParam(@RequestParam(name = "id")Integer rid){}
  • 中文乱码
    在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>*.action</url-pattern>
    </filter-mapping>
  • 参数绑定pojo
    如果表单中的name属性名称与pojo的属性名称一致,可以使用pojo进行接收表单数据
  • 参数绑定pojo包装类
    OGNL表达式
    如果表单中的name属性名称和包装类中的属性名称产生映射,则可以采用OGNL表达式的方式进行映射
    格式 :
    包装类的属性名称.pojo中的属性名称 就可以实现name属性值往pojo包装类装配
  • 数组类型参数绑定
    如果表单中的name属性只有多个,此时可以在pojo类中定义为数组类型,让它们产生关联映射
  • 集合类型参数绑定
    当表单中需要提交多条记录时,可以采用多记录提交
    实现方式 : 在pojo类中定义集合属性,请求方法参数可以直接使用pojo
    每一行都是一个对象,每一列都是pojo的属性
    仅仅适用于pojo不能直接把值传入相应的方法参数上
  • 格式类型转换(日期)
    只有yyyy/MM/dd的日期格式才能往Date里装配,否则报参数非法
    表达提交的数据基本都是字符串类型.后台接收的时候,如果有整形类型Integer,此时数据也可以封装上去,因为spring框架内部提供了很多默认的数据类型转换类
    如果要自定义转换类型,可以实现Converter接口,重写conver()方法
    <!--自定义日期格式转换器-->
    <bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean" id="conversionService">
        <property name="converters" >
            <list>
                <bean class="com.converter.StringToDate"/>
            </list>
        </property>
    </bean>
      <!--开启注解驱动 配置 处理器映射器和处理器适配器-->
    <mvc:annotation-driven conversion-service="conversionService"/>

@DateTimeFormat()
可以在pojo的日期属性上打上该注解

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date r_rTime;

2.2 @RequestMapping

  • 多个路径匹配
    //多个路径映射
    @RequestMapping(path = {"/test05","/test055"})
    public String test05() {
       return "role/addRole";
    }
  • 窄化路径
    在类上打上该注解,写上公共的资源路径,以后该类只接受**/role/**的请求
@RequestMapping("/role")
  • 限定请求方法
    可以通过method属性限定请求的方式,类型是RequestMethod
    一般使用GET或POST
@RequestMapping(path = {"/test05","/test055"},method = {RequestMethod.GET,RequestMethod.POST})

还有另一种方法: 不使用RequestMapping注解,用其他注解
@GetMapping
@PostMapping
@DeleteMapping
@PutMapping

2.3 controller的方法的返回值

  • ModelAndView
    返回数据和视图,内部封装的数据实现的原理,是使用了servlet中的Request对象,也就是说数据实质上存进了request域对象中,可以使用addobject()传输数据,使用setViewName()方法指定视图地址
   @RequestMapping("/roleList.action")
   public ModelAndView test() {
       ModelAndView modelAndView = new ModelAndView();
       modelAndView.setViewName("/role/roleList");
       return modelAndView;
   }
  • void空返回值
    如果返回值是void,那就不需要指定视图地址,即无需跳转页面.
    void的空返回值主要用于Ajax功能,Ajax只需要返回数据,不需要指定视图
  • String字符串返回值
    如果方法的返回值为String,相当于modelAndView.setViewName("/role/roleList");
    本质就是指定的视图地址,可以搭配视图解析器使用(前后缀)
    @RequestMapping("/test055")
    public String test05(Model model) {
       model.addAttribute("list",lists)
       return "role/addRole";

    }

假设所需要跳转的jsp页面不在视图解析器的范围,则需要进行内部转发或重定向

return "forward:/admin.jsp";//内部转发
return "redirect:/admin.jsp"

按以前的说法重定向是需要拼接虚拟目录的request.getContextPath(),但是在这里不需要,springMVC的组件会自动匹配
重定向不可以访问WEB-INF下的资源,内部转发可以访问
重定向无法传输Model的数据,本质是一个request对象

2.3 全局异常处理器

  • 开发步骤
    (1). 定义一个异常处理类,实现HandlerExceptionResolver接口,重写抽象方法
    (2). 在xml配置文件中配置
public class GlobalExceptionsHandler implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("friend");
        modelAndView.addObject("o",o);
        modelAndView.addObject("e",e);
        return modelAndView;
    }
}
 <bean class="com.exception.GlobalExceptionsHandler"/>

2.4 文件上传

    @RequestMapping("/uploadFile.action")
    public String fileUpload(String username, MultipartFile photoFile) throws IOException {
        //文件重命名
        String filename = photoFile.getOriginalFilename();
        String fileNewName = UUID.randomUUID().toString()+System.currentTimeMillis()+filename;
        //mvc实现上传
        photoFile.transferTo(new File("D:\\picture\\新建文件夹\\"+fileNewName));
        return null;
    }
    <!--配置文件上传解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize">
            <value>1048576</value>
        </property>
    </bean>

2.5 RESTful编程风格的支持

它是一个资源定位和资源操作的风格.它不是标准也不是协议,只是一种风格.
RESTful风格请求使用: "url+请求方式",表示一次请求的目的
代码更简洁,更有层次感,更易于实现**缓存机制**
  • 需要借助注解@PathVariable
  • 在@RequestMapping注解中的path属性值格式${变量名}
//http://localhost:8080/ParameterBinding/department/1.action
    @RequestMapping("/department/{id}.action")
    public String testRESTful(@PathVariable Integer id) {
        System.out.println(id);
        return null;
    }

2.6 拦截器

springMVC的处理器拦截功能类似于Servlet规范中的过滤器Filter,用于对处理器Handler进行预处理和后处理
区别就是和Filter加载时机不一样. 过滤器Filter在前端控制器前加载,拦截器在前端控制器之后加载
  • 开发步骤
    (1) 创建一个类实现HandlerInterceptor接口. 重写该接口的三个方法
    preHandle
    预处理回调方法,实现处理器的预处理,在客户端请求到达控制器之前进行拦截(登录校验或权限验证)
    该方法的返回值为boolean,如果为true,放行,如果为false,则请求到不了前端控制器.可以使用内部转发重新指定一个界面
    posHandle
    后处理回调方法. 控制器中代码已经加载完毕(在组装ModelAndView对象之前),此时可以在该方法中定义ModelAndView中的数据. 指定Model中传输的数据,指定跳转的视图地址,也可以把它置为null.
    afterCompletion
    在整个方法请求结束后, 组装完ModelAndView, 即将传输给前端控制器之前拦截.
    (2) 把自定义拦截器交给spring容器管理
    <!--配置自定义拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--映射后端请求的资源路径  **代表拦截所有 -->
            <mvc:mapping path="/**"/>
            <bean class="com.interceptor.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值