SpingMVC

SpringMVC


在这里插入图片描述

1.作用

  1. 接受前台或者其他服务的数据并校验
  2. 返回数据到前台或者其他服务
  3. 指定跳转的页面或其他服务数据接口

2.搭建

2.1导入jar包
<packaging>war</packaging>
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.1.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>5.1.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.1.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.1</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.0</version>
            <configuration>
                <source>1.8</source> <!-- 源代码使用jdk1.8支持的特性 -->
                <target>1.8</target> <!-- 使用jvm1.8编译目标代码 -->
                <compilerArgs> <!-- 传递参数 -->
                    <arg>-parameters</arg>
                    <arg>-Xlint:unchecked</arg>
                    <arg>-Xlint:deprecation </arg>
                </compilerArgs>
            </configuration>
        </plugin>

    </plugins>
</build>
2.2详解配置springmvc.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">

    <!-- 配置spring创建容器时要扫描的包 -->
    <context:component-scan base-package="cn.cdqf.web"></context:component-scan>

    <!-- 配置视图解析器 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <property name="suffix" value=".html"></property>
    </bean>
    <!-- 配置spring开启注解mvc的支持-->
    <mvc:annotation-driven></mvc:annotation-driven>
</beans>
2.3配置web.xml
<?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">
    <!-- SpringMVC的核心控制器 -->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 配置Servlet的初始化参数,读取springmvc的配置文件,创建spring容器 -->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
        <!-- 配置servlet启动时加载对象 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!--避免springmvc拦截以html结尾的请求-->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>

</web-app>
2.4代码执行
@Controller
public class UserController {

    @RequestMapping("index")
    public ModelAndView index(ModelAndView modelAndView){
        System.out.println("hello");
        modelAndView.setViewName("a");
        return modelAndView;
    }
}

3.核心流程分析

DispacthServlet:中央控制

handlerMapping:描述是url与method的对应关系

容器加载的时候会加载到springmvc.xml,在根据springmvc.xml中配置扫描路径,就可以找到对应包,找到包以后会遍历该包下面所有类,判断类上面是否有@controller注解,如果有就放在IOC容器中,springmvc会从IOC容器中拿出所有被@controller注解修饰的类,遍历这些类的方法,拿到method对象,通过反射获得method对象上面@requestMapping注解,获得@requestMapping注解的value,就是一个url,就会把这个url与当前方法, new HandlerMapping(url,method) 放在一个List:存储了当前项目所有url以及url与method的对应关系

url---- DispacthServlet-----把这个给,就会拿到这个,去判断是否有这个,如果没有,如果有就拿到这个方法

4.ModelAndView

返回前台:

  1. 包含数据,request/session.setAttribute(“user”,user对象)
  2. 指定跳转页面 request forward方法(请求转发) response.sendRedicet(重定向)

模型视图对象:modelAndView 就是把上面两步封装到一起

addObject()方法:添加数据 添加的数据 放在request作用域 viewName:视图名称

@RequestMapping("index")
//封装了 ModelAndView  当返回String的时候 springmvc会去创建modelandview.setviewName("index")
public String index(){
    System.out.println("来了,老弟");
   return "index";
}

@RequestMapping("index2")
//直接放在这儿
public ModelAndView index2(ModelAndView modelAndView){
    System.out.println("来了,老弟");
    //request.setAttribute("username","张三") 数据
    modelAndView.addObject("username","张三");
    //指定跳转的页面
    modelAndView.setViewName("index");
    return modelAndView;
}

5.json参数返回

4.1详解配置

jsp的前后端耦合性太强,不适用于高度解耦的前后端分离的开发。

json是作为前后端的数据交互的重要数据载体

  1. 导入fastjson.jar

  2. 配置springmvc.xml中的json转换器

    1. 编码问题
    2. 配置前后端下载文件冲突
    3. 属性值为null转换输出配置
    4. 日期格式
    5. 循环调用问题
    <!-- 配置spring开启注解mvc的支持-->
    <mvc:annotation-driven></mvc:annotation-driven>
    
    <mvc:annotation-driven>
        <!--不使用默认消息转换器 -->
        <mvc:message-converters register-defaults="false">
            <!--spring消息转换器 -->
            <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
            <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
    
            <!--解决@Responcebody中文乱码问题 -->
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
            </bean>
            <!--配合fastjson支持 -->
            <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="defaultCharset" value="UTF-8"/>
                <property name="supportedMediaTypes">
                    <list>
                        <!--顺序保持这样,避免IE下载出错  配置1.注意编码 2.注意与下载文件冲突-->
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json</value>
                    </list>
                </property>
                <property name="fastJsonConfig" ref="fastJsonConfig"/>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
    
    <!--fastJsonConfig  这里面的配置需要开发中 跟前端进行协商-->
    <bean id="fastJsonConfig" class="com.alibaba.fastjson.support.config.FastJsonConfig">
        <!--默认编码格式 -->
        <property name="charset" value="UTF-8"/>
    
        <property name="serializerFeatures">
            <list>
                <!--3.需要指定null按照协商好的配置返回-->
                <!-- List字段如果为null,输出为[]-->
                <value>WriteNullListAsEmpty</value>
                <!--4.日期格式
                使得返回的日期类型默认为yyyy-MM-dd hh:mm:ss
                -->
                <value>WriteDateUseDateFormat</value>
                <!--美化格式-->
                <value>PrettyFormat</value>
                <value>WriteMapNullValue</value>
                <value>WriteNullStringAsEmpty</value>
                <!--禁止循环引用检测
                    Teacher : List<Student>
                    Student : Teacher
                    stackOverFlow:
                -->
                <value>DisableCircularReferenceDetect</value>
            </list>
        </property>
    </bean>
    
  3. 导入前端js,css等静态资源,配置放过拦截js

    <!-- 对指定目录下的静态资源放行(**代表当前文件夹及子文件夹所有文件) -->
    <mvc:resources location="/fonts/" mapping="/fonts/**"/>
    <mvc:resources location="/css/" mapping="/css/**"/>
    <mvc:resources location="/js/" mapping="/js/**"/>
    
4.2 基本数据类型
4.3 String类型

后端代码:

@Controller
//namespace作用  handlerMapping: url=类上面+方法上
@RequestMapping("ajax")
//@RestController=@Controller+@ResponseBody
public class AjaxController {
    //8888/ajax/ajax1
    @RequestMapping("ajax1")
    //如果不告诉springmvc返回json  默认返回字符串是代表路径
    @ResponseBody//就是告诉springmvc 这个方法得返回值是一个json  springmvc就会调用配置json库
    // 来进行转换为json字符串然后通过  response.getwriter写回去
    public String ajax1(){
        System.out.println("ajax1方法被请求");
        return "hello ajax1";
    }
}
public String index(){
    System.out.println("来了,老弟");
    //转发
   return "forward:index";//forward默认省略 等于return “index"
    //重定向
    return "redirect:/WEB-INF/pages/index.html";
}
  1. 请求转发的字符串若在springmvc.xml文件中配置了viewResolver将为其加上前缀和后缀进行请求
  2. 重定向的字符串路径则需要手动拼接

前端代码:

<link href="/css/bootstrap.min.css">
    <script src="/js/jquery-3.3.1.min.js"></script>
    <script src="/js/bootstrap.min.js"></script>
</head>
<body>
    <button id="ajax">点击</button>
</body>
<script>
    $(function () {
        $("#ajax").click(function () {
            $.ajax({
               url:"/ajax/ajax1",
                type:"GET",
                dataType:"json",//返回数据类型
                success:function (data) {
                    console.log(data);
                }
            })
        })
    })
</script>
4.4集合类型
4.5Map类型
4.6数组类型
4.7日期类型
4.8实体对象
@RestController
@RequestMapping("student")
public class Ajax2Controller {

    @RequestMapping("ajax1")
    public List<Student> ajax1(){
        return Arrays.asList(new Student("张三", "力宝", new Date(), 100), new Student("李四", "力宝", new Date(), 100));
    }
}

5.其他配置

5.1配置过滤器
<!-- 配置过滤器,解决中文乱码的问题 -->
<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>
5.2日期转换配置
  1. 创建日期转换类实现Converter接口

    public class DateConverter implements Converter<String, Date> {
        @Override
        public Date convert(String s) {
            if(s !=null){
                try {
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    return dateFormat.parse(s);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    }
    
  2. xml配置

    <!--配置自己写好的转换器-->
        <bean id="dateConverter" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
            <property name="converters">
                <list>
                    <bean class="com.ctbu.converter.DateConverter"/>
                </list>
            </property>
        </bean>
        <!--配置注解驱动,让转换器生效-->
        <mvc:annotation-driven conversion-service="dateConverter"/>
    
5.3拦截器配置

在这里插入图片描述

  1. 创建自定义拦截器,实现HandlerInterceptor接口

    public class MyInterceptor implements HandlerInterceptor {
        /**
         * @param request
         * @param response
         * @param handler
         * @return
         * @throws Exception
         * 在controller方法之前执行
         *
         * 1.return true就执行controller
         *2. return false就不会执行controller
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            //用户没有登录 让用户跳转到登录页面
            //response.sendRedirect("http://localhost:8888/login.html");
            //response也可以写json
    
            //拿到url 拿到参数 获得session  获得cookie
            //某些请求需要等 某些不登录   queryAllProduct 不需要登录 updateProduct需要登录
            //通过request获得url  看一看是不是需要登录的请求 从session中获得登录信息 就可以判断
    
            //不同的角色 在项目 权限不同  deleteUser
    
            //url:login----LoginController中 login方法
            //HttpMethod handler1 = (HttpMethod) handler;
    
            System.out.println("拦截器执行了.....");
            return true;
        }
        //modelAndView :1.会有数据携带 2.跳转的页面
        //html中 ${abc} 取出request.setAttribute("abc","张三")
        //视图渲染:把页面中占位符替换为 值  页面html元素 与数据的整合
    
        //1.会在视图渲染前执行,可以去修改视图渲染的值
        //正常情况下 postHandle先执行 afterCompletion后执行
        // postHandle出现异常不会执行 afterCompletion出现异常也会执行
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
            System.out.println("postHandle执行了");
        }
        //2.会在视图渲染后执行
        //可以获得当前请求出现异常
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("afterCompletion执行了");
        }
    }
    
  2. xml拦截器配置(多个拦截器)

    <mvc:interceptors>
        <mvc:interceptor>
            <!--当前拦截器 要拦截的路径-->
            <mvc:mapping path="/**"/>
            <!--在上面的路径中排除某些路径-->
            <mvc:exclude-mapping path="/interceptor/index3"/>
            <bean class="cn.cdqf.web.interceptor.MyInterceptor"/>
        </mvc:interceptor>
    
        <mvc:interceptor>
            <!--当前拦截器 要拦截的路径-->
            <mvc:mapping path="/**"/>
            <!--在上面的路径中排除某些路径-->
            <mvc:exclude-mapping path="/interceptor/index3"/>
            <bean class="cn.cdqf.web.interceptor.MyInterceptor2"/>
        </mvc:interceptor>
    </mvc:interceptors>
    

6.请求参数

6.1@RequestParam注解
  1. 基本类型

    1. 基本数据类型作为请求方法的参数时,参数名必须一致
    2. 前台传入的数据为空将抛出类型转换异常,返回400错误(参数有误)。若为包装类型则会将null作为值传入
    3. 使用@RequestParam替换参数名
  2. 数组/集合类型

    配置@RequestParam注解

    //@RequestParam中的value必须在对应的名称后面加[]表示接受数组或者集合类型
    //用@RequestParam标注表示必须传一个名字相同的参数
    public void insert(@RequestParam(value = "ids[]",required = false) String[] ids, @RequestParam("name") String username)
        {
      }
    
6.2@Requestbody注解
  1. 标注在方法上表示方法将返回json数据

    @RestController=@Controller+@ResponseBody

  2. 标注在参数上表示参数为接受json数据
    1. 前端请求参数类型为json字符串
    2. 请求方法为Post
    3. 请求头中的ContentType=“application/json”,表示Http响应回来的是json数据

7.HTTP常见Code编号

编号 概述
404 请求路径错误
400 请求参数错误
405 请求方法错误,前后端GET/POST方法不一致
302 重定向
304 浏览器缓存
500 后台服务器错误
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章