<二>SpringMVC

一、图解SpringMVC执行流程:

 SpringMVC执行流程:

  1. 用户发送请求前端控制器DispatcherServlet;
  2. DispatcherServlet收到请求调用处理器映射器HandlerMapping;
  3. 处理器映射器根据请求url找到具体的处理器,生成处理器执行链HandlerExecutionChain(包括处理器对象和处理器拦截器)----并返回给DispatcherServlet;
  4. DispatcherServlet根据处理器Handler获取处理器适配器HandlerAdapter执行HandlerAdapter处理一系列的操作,如:参数封装、数据格式转换、数据验证等操作;
  5. 执行处理器Handler(Controller,也交页面控制器)。
  6. Handler执行完成返回ModelAndView
  7. HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
  8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器
  9. ViewReslover解析后返回具体View
  10. DispatcherServlet对View进行渲染视图(即将模型数据model填充至视图中);
  11. DispatcherServlet响应用户请求。

二、springMVC实战

1、SpringMVC简介

SpringMVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring框架提供了构建Web应用程序的全功能MVC模块。使用Spring可插入的MVC架构,从而在使用Spring进行Web开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架。如Struts1、Struts2等,在这里暂时就不分析SpringMVC与Struts2的比较了。

2、搭建环境入门程序

需要的jar包(需要什么包后面自己添加什么包)

(1)添加Spring的核心包

(2)添加web.xml文件,使用3.0或以上的版本,3.0以下的对el表达式不是很智能,需要配置isELIgnored="false" 

配置前端控制器

 <!--前端控制器/请求分发器-->
<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:application-mvc.xml</param-value>
    </init-param>
    <!--设置优先级-->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springMVC</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

(3)创建自定义的Controller类,实现Controller接口。复写handlerRequest方法

package com.controller;
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 HelloWorldController implements Controller {

    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse             response) throws Exception {
          //创建自定义Controller类,实现contrller接口复写handleRequest方法
           request.setAttribute("msg","hello!");
           request.getRequestDispatcher("/hello.jsp").forward(request,response);
           return null;
    }
}

(4)在application-mvc.xml中配置Controller的映射路径,并且交给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"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

<!--name请求的映射路径 class:该路径处理类-->
<bean name="/index" class="com.controller.HelloWorldController"></bean>

<!-- 返回类型定义  -->
<bean  id="stringHttpMessageConverter"
       class="org.springframework.http.converter.StringHttpMessageConverter">
    <constructor-arg value="UTF-8" index="0"></constructor-arg>
    <property name="supportedMediaTypes">
        <list>
            <value>text/plain;charset=UTF-8</value>
        </list>
    </property>
</bean>
<bean id="fastJsonHttpMessageConverter"
      class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
    <property name="supportedMediaTypes">
        <list>
            <value>text/html;charset=UTF-8</value>
            <value>application/json;charset=UTF-8</value>
        </list>
    </property>
    <property name="features">
        <util:list>
            <value>WriteMapNullValue</value>
            <value>WriteNullStringAsEmpty</value>
            <value>QuoteFieldNames</value>
            <value>WriteNullListAsEmpty</value>
            <value>WriteDateUseDateFormat</value>
        </util:list>
    </property>
</bean>
<bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller" />
<bean id="marshallingHttpMessageConverter"
      class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
    <property name="marshaller" ref="castorMarshaller" />
    <property name="unmarshaller" ref="castorMarshaller" />
    <property name="supportedMediaTypes">
        <list>
            <value>text/xml;charset=UTF-8</value>
            <value>application/xml;charset=UTF-8</value>
        </list>
    </property>
</bean>
<util:list id="messageConverters">
    <ref bean="stringHttpMessageConverter" />
    <ref bean="fastJsonHttpMessageConverter" />
    <ref bean="marshallingHttpMessageConverter" />
</util:list>

<!-- 支持springMVC的注解驱动 json解析文件上传等很多功能都依赖这个配置 -->
<mvc:annotation-driven>
    <mvc:message-converters>
        <ref bean="stringHttpMessageConverter" />
        <ref bean="fastJsonHttpMessageConverter" />
        <ref bean="marshallingHttpMessageConverter" />
    </mvc:message-converters>
</mvc:annotation-driven>

<!-- 开启注解扫描 -->
<context:component-scan base-package="com.controller" use-default-filters="false">
    <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>

<!-- springMVC的静态资源处理配置 -->
<mvc:default-servlet-handler></mvc:default-servlet-handler>

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

<!-- 不进行拦截的 -->
<mvc:resources location="/" mapping="/**/*.html" order="0" />
<mvc:resources location="/images/" mapping="/images/**" cache-period="2592000" />
<mvc:resources location="/common/" mapping="/common/**" cache-period="31536000"/>
<mvc:resources location="/js/" mapping="/js/**" cache-period="31536000"/>
<mvc:resources location="/css/" mapping="/css/**" cache-period="31536000"/>


<!-- 支持上传文件 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding">
        <value>UTF-8</value>
    </property>
    <property name="maxUploadSize">
        <value>104857600</value>
    </property>
    <property name="maxInMemorySize">
        <value>2048000</value>
    </property>
</bean>

(5)在web.xml中,让框架去找我们的自定义的文件名与路径

注意:第一次访问的时候才去加载框架;如果类很多,那么第一次访问就会很慢。

3、使用注解的方式

  1. 在类上打@Controller注解
  2. 在方法上添加@RequestMapping注解
  3. 在springmvc的配置文件上开启注解扫描
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 使用注解的方式来配置URL  必须开启注解扫描才能帮我们创建bean
 */
@Controller
@RequestMapping("/employee")
public class EmployeeController{

    @RequestMapping("/index1")
    public void employee(HttpServletRequest request,HttpServletResponse response) throws Exception{
        //方法中需要什么参数就写到形参上
        request.setAttribute("msg","emplay=====");
        request.setAttribute("success","success====");
        request.getRequestDispatcher("/hello.jsp").forward(request,response);
    }
    @RequestMapping("/update")
    public void employee1(){
        System.out.println("ecvefwg===");
    }
}

 使用注解,必须在application-mvc.xml中开启注解扫描

@RequestMapping可以打在上也可以打在方法上。如果打在类上,必须先加载类上的映射,在加载方法的映射。

访问的时候:http://localhost:8080/employee/index1

4、静态资源处理

(1)/和./的区别

./:会匹配到url路径(/index),静态资源(.html,.js等),但是不会匹配到.jsp

/:会匹配到url路径(/index),静态资源(.html,.js等),也会匹配到.jsp

(2)为什么springmvc不能使用/*

struts2里面是有自定义标签s:form,jsp文件必须要交由struts2来解析,所以才会用到/*

springmvc是没有自定义标签的,也不能处理jsp文件,所以jsp文件必须交回tomcat来处理,所以才会用/,不过滤jsp文件。

(3)springmvc匹配到静态资源的时候出现的重定向错误问题

当我们在浏览器访问http://localhost:8080/dept.html,此时的dept.html路径就会被当作url的映射路径来匹配。

就会去找@RequestMapping有没有匹配到的路径,如果有的话就把dept.html当作url路径来访问(/dept.???)?是不会加载进去匹配的。

也就是说访问dept.html时,只要有dept的路径就可以匹配到。

解决方案:

方案1: 交由tomcat来处理,tomcat中的dafault本来就是处理静态资源的。

web.xml
<!-- 静态资源交由tomcat的defaultServlet来处理 -->
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.html</url-pattern>
    <url-pattern>*.js</url-pattern>
    <url-pattern>*.css</url-pattern>
</servlet-mapping>

方案2:配置springmvc处理静态资源(先匹配url是否有相同的路径,如果有就交由方法处理,如果没有才当作静态资源处理)(推荐使用)在application-mvc.xml中

5、前台往后台传参的方式

(1)request传参

(2)使用同名匹配的方式

(3)使用对象的方式

(4)地址栏传参

6、解决中文乱码问题(post)在web.xml中做如下配置

7、后台往前台传值

//后台往前台传值
public class ValueController {
//1.使用原始方式传值
@RequestMapping("/value")
public void value(HttpServletRequest requst, HttpServletResponse response) throws Exception {
    //方法中需要什么对象就写到形参上
    requst.setAttribute("msg", "value!!!!!!!!");
    requst.getRequestDispatcher("/hello.jsp").forward(requst, response);
}

//2.使用ModelAndView对象
@RequestMapping("value1")
public ModelAndView value() throws Exception {
    ModelAndView mv = new ModelAndView();
    //设置属性
    mv.addObject("name", "CoderZS");
    mv.addObject("password", "123");
    User user = new User("zhangsan", "1234");
    mv.addObject("user", user);
    //mv.addObject(user);
    mv.addObject("maYun");//设置默认key为当前对象类型(小写开头)
    mv.addObject("hahaha");//后面设置相同类型的值会覆盖之前的值

    Map map = new HashMap<>();
    map.put("name1", "laowang");
    map.put("password", "12344");
    mv.addAllObjects(map);

    //设置视图
    mv.setViewName("/hello.jsp");
    return mv;
}

//3.直接返回对象
//此时会寻找视图解析器中[前缀+value2+后缀]的页面/WEB-INF/views/value2.jsp
@RequestMapping("/value2")
public User getUser() {
    return new User("CoderZS", "1234");
}

//注意返回String的时候会当做视图解析(推荐使用)
//如果返回的类型是String就会把返回值当做视图的一部分
//最终去寻找的路径[前缀+返回的值+后缀]
//WEB-INF/views/vvv.jsp
@RequestMapping("/value3")
public String getString(Model model) {
    model.addAttribute("name", "coderZS");
    return "vvv";
}

//4.访问其他路径的文件,不需要用到前后缀
@RequestMapping("/value4")
public String getString() {
    //希望访问其他路径的文件,就不需要用到前缀后缀
    //forward:login.html //请求转发
    return "redirect:login.html";//重定向
}
}

8、文件上传

public class FileController{

    //文件上传
    @RequestMapping("/upload")
    //在方法形参上添加MultipartFile对象来接收(不能使用File来接收了)
    public void upload(MultipartFile file) throws Exception {
        System.out.println(file.getName());//提交表单的文件的参数名
        System.out.println(file.getContentType());//文件类型
        System.out.println(file.getOriginalFilename());//提交的文件名
        System.out.println(file.getSize());//文件大小
        //拷贝文件
        FileOutputStream outputStream = new
        FileOutputStream("/Users/Desktop/file" + file.getOriginalFilename());
        IOUtils.copy(file.getInputStream(), outputStream);
        //关闭输出流
        outputStream.close();
    }
}

在application-mvc.xml中添加文件上传解析器

9、文件下载

public class FileController{
    //文件下载
    @RequestMapping("/download")
    public  void download(HttpServletResponse response) throws Exception {
        System.out.println("---下载-----");
        //设置下载响应头
        response.setHeader("Content-Disposition","attachment;filename=a.jpg");
        //读取文件
        FileInputStream inputStream=new                          
        FileInputStream("/Users/zhangshuai/Desktop/file/1.jpg");
        IOUtils.copy(inputStream, response.getOutputStream());
        //关闭输入流
        inputStream.close();
    }

}

10、注册拦截器

(1)创建自定义的拦截器类,实现HandlerInterceptor接口

(2)注册拦截器

在application-mvc.xml中加入如下代码:

<!-- 注册拦截器 -->
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**" />
        <!-- 排除拦截的路径 -->
        <mvc:exclude-mapping path="/login" />
        <!-- 拦截处理类 -->
        <bean class="com.interceptor.LoginInterceptor" />
    </mvc:interceptor>
</mvc:interceptors>

11、返回json格式

在方法的返回值上直接声明要返回的类型,并且加上@RespoonseBody注解

需要添加json解析依赖包

//返回json格式
// 1.在方法的返回值上直接声明要返回的类型,并且加上@ResponseBody注解
 @Controller
public class JsonController {
@RequestMapping("/json")
@ResponseBody
public User json() {
    User user = new User("CoderZS", "1234");
    return user;
}

@RequestMapping("/json1")
@ResponseBody
public List<User> json1() {
    User user = new User("CoderZS", "1234",new Date());
    List list = new ArrayList<>();
    list.add(user);
    return list;
}

//2.使用ObjectMapper
public static void main(String[] args) throws Exception {
    User user = new User("CoderZS", "1234");
    //转成json字符串的工具
    ObjectMapper objectMapper = new ObjectMapper();
    String json = objectMapper.writeValueAsString(user);
    System.out.println(json);
}
}

12、日期处理

后台往前台传json值时(包含日期)

解决方案

方案1:在属性上添加@JsonFormat注解,注意要添加时区

方案2:在总配置文件application-mvc.xml添加相关配置

前台往后台传参时(包含日期)

(1)在日期参数上添加@DateTimeFormat注解

(2)在Controller上添加initBinder方法

如果两种都有,会使用initBinder方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值