springMVC笔记1

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

源码怎么处理put/delete的请求方法:
在这里插入图片描述

注意:高版本的tomcat:restful支持有点问题,解决方案如下:
在这里插入图片描述
springmvc直接在方法的参数上使用原生 的API(如 session,request):

在这里插入图片描述

用法:
在这里插入图片描述

在这里插入图片描述

获取inputStream :

ServletInputStream inputStream = request.getInputStream();

获取outputStream :

ServletOutputStream outputStream = response.getOutputStream();

解决编码问题:

在这里插入图片描述

在这里插入图片描述

当配置多个filter的时候,要按照配置的顺序执行,所有肌肤编码的filter要放在restful处理乱码的filter前。才能生效。

springmvc如何将数据带到前台页面:

总结:springmvc将数据带到前台页面总共有5中方式:分别是

1.原生api : HttpSession 和 HttpServletRequest
2.Map
3.Model
4.ModelMap
5.ModelAndView

特别注意:2.Map3.Model4.ModelMap5.ModelAndView最终存入的数据都最后放到了request域中

首先我们在index.jsp中发送请求,如下:

<%--
  Created by IntelliJ IDEA.
  User: fan
  Date: 2021/3/23
  Time: 9:43
  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>
  <a href="${pageContext.request.contextPath}/hello">hello</a><br>
  <a href="${pageContext.request.contextPath}/handle01">handle01测试原生api传值</a><br>
  <a href="${pageContext.request.contextPath}/handle02">handle02测试map传值到页面</a><br>
  <a href="${pageContext.request.contextPath}/handle03">handle03测试Model传值到页面</a><br>
  <a href="${pageContext.request.contextPath}/handle04">handle04测试ModelMap传值到页面</a><br>
  <a href="${pageContext.request.contextPath}/handle05">handle05测试ModelAndView传值到页面</a><br>
  </body>
</html>

然后在WEB-INF/pages下创建页面success页面,作为视图跳转的页面,如下:

<%--
  Created by IntelliJ IDEA.
  User: fan
  Date: 2021/3/23
  Time: 10: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>
成功<br>
<%--在页面使用spring的EL表达式来获取后台数据的值--%>
获取request中存入的值:${requestScope.request},
获取session中存入的值:${sessionScope.session},

request域中的值:${requestScope.msg},
</body>
</html>

方式一:将数据传输到前台页面 第一种方式 原生api

原生api HttpSession HttpServletRequest
HttpSession:保存的数据存放在session作用域当中
HttpServletRequest :保存的数据存放在请求域当中

存值:
session.setAttribute(key,value)

request.setAttribute(key,value)

取值:
requestScope.key,sessionScope.key

//   将数据传输到前台页面 第一种方式 原生api
    @RequestMapping(value = "/handle01")
    public String handle01(HttpServletRequest request, HttpSession session){
        //1.演示后台将数据存入原生的API(request,session)中,---->并传递到前端页面,并在前端页面获取。
        request.setAttribute("request","我是request中存入的值");
        session.setAttribute("session","我是session中存入的值");
        return "success";
    }

方式二、三、四都是通过请求方法的参数Map,Model,ModelMap将数据携带到前端页面,这些方式参数中保存的数据都会放到请求域requestScope中

Map
存值:
map.put(key,value)

取值:
格式:作用域.key , 用法requestScope.key

Model
存值:
model.addAttribute(key,value)

取值:
格式:作用域.key ,用法requestScope.key

ModelMap
存值:
modelmap.addAttribute(key,value)

取值:
格式:作用域.key, 用法requestScope.key

可以通过如下代码验证Map,Model,ModelMap中的数据是放在请求域中的。

在这里插入图片描述

方式五、可以通过请求方法的返回值将数据携带到前端页面

当返回值是ModelAndView时,此类型既包含视图信息(页面地址)也包含模型数据(给页面带的数据),而且数据是放在请求域中。我们可以通过四种域来获取值验证。

在这里插入图片描述

代码演示5种方式:

package com.fan;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttribute;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Map;

@Controller
public class OutputController {

    //   将数据传输到前台页面 第一种方式 原生API
    @RequestMapping(value = "/handle01")
    public String handle01(HttpServletRequest request, HttpSession session){
        //1.演示后台将数据存入原生的API(request,session)中,---->并传递到前端页面,并在前端页面获取。
        request.setAttribute("request","我是request中存入的值");
        session.setAttribute("session","我是session中存入的值");
        return "success";
    }

    //   将数据传输到前台页面 第二种方式 Map
    @RequestMapping(value = "/handle02")
    public String handle02(Map<String,Object> map){
        map.put("msg","我是map中的value");
        System.out.println("map的类型:"+map.getClass());
        return "success";
    }

    //   将数据传输到前台页面 第三种方式 Model
    @RequestMapping(value = "/handle03")
    public String handle03(Model model){
        model.addAttribute("msg","我是model的值");
        System.out.println("model的类型:"+model.getClass());
        return "success";
    }

    //   将数据传输到前台页面 第四种方式 ModelMap
    @RequestMapping(value = "/handle04")
    public String handle04(ModelMap modelMap){
        //用法和model一样,都是使用addAttribut方法添加数据
        modelMap.addAttribute("msg","我是modelMap中的值");
        System.out.println("modelMap的类型:"+modelMap.getClass());
        return "success";
    }

    //   将数据传输到前台页面 第五种方式 Modelandview,
    //   当方法的返回值为Modelandview时,是将数据放到了request请求域中。
    @RequestMapping(value = "/handle05")
    public ModelAndView handle05(){
        ModelAndView mv = new ModelAndView();
        System.out.println("ModelAndView的类型:"+mv.getClass());
        mv.addObject("msg","我是ModelAndView中的值");//向mv存入一个key-value的值
        mv.setViewName("success");//设置逻辑视图名
        return mv;
    }

   /* model的类型:class org.springframework.validation.support.BindingAwareModelMap
    modelMap的类型:class org.springframework.validation.support.BindingAwareModelMap
    modelMap的类型:class org.springframework.validation.support.BindingAwareModelMap
    ModelAndView的类型:class org.springframework.web.servlet.ModelAndView*/
}

Map、Model、ModelMap之间的区别:

相同点:
用法和作用类似:

map.put(“msg”,“我是map中的value”);
model.addAttribute(“msg”,“我是model的值”);
modelMap.addAttribute(“msg”,“我是modelMap中的值”);

(1)都可以将数据存到request中,传送到前端页面,并在请求域中获取
(2)底层都是一个隐含模型BindingAwareModelMap在实际的工作

在这里插入图片描述

不同点:
测试Model和ModelMap的类型:

Map(jdk接口),Model(spring框架的接口) ModelMap(类)

以及三者之间的关系:

public class BindingAwareModelMap extends ExtendedModelMap

public class ExtendedModelMap extends ModelMap implements Model

public class ModelMap extends LinkedHashMap<String, Object>

public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>

在这里插入图片描述

完整的结构图:

在这里插入图片描述

总结 :

除了ModelAndView之外的方式,其他方式的返回值都是String
除了原生api以外能,其他四种方式的存在默认存放的作用域在request(请求)作用域当中

补充点 :
以上记录的除了原生api能存放在session域当中,其他四种方式默认存放的作用域为request域当中,那么怎么修改他们的作用域 ,并存放在session中

解决办法 添加 @SessionAttributes注解

@SessionAttributes给数据保存在session域中:

该注解只能存放在类上

@SessionAttributes参数

value:指定需要存放在session域的key值
names:指定需要存放在session域的key值
types:指定需要存放在session域中的类型 比如String类型 填入String.class

而这里使用了@SessionAttributes(value={“user”})将BindingAwareModelMap中属性名为user的数据或者ModelAndView中的数据,同时copy一份给了session域中.

代码演示(存入模型的值,也会给session复制一份的效果):
index页面:

<%--
  Created by IntelliJ IDEA.
  User: fan
  Date: 2021/3/23
  Time: 9:43
  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>
  <a href="${pageContext.request.contextPath}/hello">hello</a><br>
  <a href="${pageContext.request.contextPath}/handle01">handle01测试原生api传值</a><br>
  <a href="${pageContext.request.contextPath}/handle02">handle02测试map传值到页面</a><br>
  <a href="${pageContext.request.contextPath}/handle03">handle03测试Model传值到页面</a><br>
  <a href="${pageContext.request.contextPath}/handle04">handle04测试ModelMap传值到页面</a><br>
  <a href="${pageContext.request.contextPath}/handle05">handle05测试ModelAndView传值到页面</a><br>

  <hr>
  <h2>测试@SessionAttributes</h2>
  <a href="${pageContext.request.contextPath}/s1">s1</a>
  <a href="${pageContext.request.contextPath}/s2">s2</a>
  </body>
</html>

测试success页面:

<%--
  Created by IntelliJ IDEA.
  User: fan
  Date: 2021/3/23
  Time: 10: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>
成功<br>
<%--在页面使用spring的EL表达式来获取后台数据的值--%>
获取request中存入的值:${requestScope.msg},<br/>
获取session中存入的值:${sessionScope.msg},<br/>
获取session中存入的值:${sessionScope.hehe},<br/>

获取pageContext中存入的值:${pageScope.msg},<br/>
获取Application中存入的值:${applicationScope.msg}<br/>


</body>
</html>

controller;

package com.fan.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;

import java.util.Map;

@Controller
@SessionAttributes(value = {"msg","haha"})//相当于设置session的key为msg,另一个key为haha
public class SessionAttrTest {
    //我们使用四种常见的模型数据存值,map,model,modelmap,modelandview,
    // 都是将数据存入BindingAwareModelMap中,存入request中
    @RequestMapping(value = "/s1")
    public String handle01(Map<String,Object> map){
        //先将数据存放到map中,本质是BindingAwareModelMap类型
        map.put("msg","测SessionAttributes注解");
        map.put("haha","哈哈哈");
        return "success";
    }

    @RequestMapping(value = "/s2")
    public String handle02(Map<String,Object> map){
        //先将数据存放到map中,本质是BindingAwareModelMap类型
        map.put("msg","测SessionAttributes注解");
        map.put("haha","哈哈哈");
        map.put("hehe","呵呵呵");
        return "success";
    }
}


或者其他模型类型:

import org.springframework.web.bind.annotation.SessionAttributes;

import java.util.Map;

@Controller
@SessionAttributes(value = "msg")//相当于设置session的key为msg
public class SessionAttrTest {
    //我们使用四种常见的模型数据存值,map,model,modelmap,modelandview,
    // 都是将数据存入BindingAwareModelMap中,存入request中
    @RequestMapping(value = "/s1")
    public String handle01(Model model){
        //先将数据存放到map中,本质是BindingAwareModelMap类型
       model.addAttribute("msg","测SessionAttributes注解");
        return "success";
    }
}

在这里插入图片描述

后来推荐@SessionAttributes就不要用了,可能会引发异常,最好我们使用原生的HttpSession,这样存值和移除session值都很方便。

或者通过value数组存放多个值:


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;

import java.util.Map;

@Controller
@SessionAttributes(value = {"msg","haha"})//相当于设置session的key为msg,另一个key为haha
public class SessionAttrTest {
    //我们使用四种常见的模型数据存值,map,model,modelmap,modelandview,
    // 都是将数据存入BindingAwareModelMap中,存入request中
    @RequestMapping(value = "/s1")
    public String handle01(Map<String,Object> map){
        //先将数据存放到map中,本质是BindingAwareModelMap类型
        map.put("msg","测SessionAttributes注解");
        map.put("haha","哈哈哈");
        return "success";
    }
}

types:指定需要存放在session域中的类型 比如String类型 填入String.class
在这里插入图片描述

type演示:

package com.fan.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;

import java.util.Map;

@Controller
@SessionAttributes(types = {String.class})//相当于设置session的key为msg,另一个key为haha
public class SessionAttrTest {
    //我们使用四种常见的模型数据存值,map,model,modelmap,modelandview,
    // 都是将数据存入BindingAwareModelMap中,存入request中
    @RequestMapping(value = "/s1")
    public String handle01(Map<String,Object> map){
        //先将数据存放到map中,本质是BindingAwareModelMap类型
        map.put("msg","测SessionAttributes注解");
        map.put("haha","哈哈哈");
        return "success";
    }

    @RequestMapping(value = "/s2")
    public String handle02(Map<String,Object> map){
        //先将数据存放到map中,本质是BindingAwareModelMap类型
        map.put("msg","测SessionAttributes注解");
        map.put("haha","哈哈哈");
        map.put("hehe","呵呵呵");
        return "success";
    }
}

代码说明types属性:只要你存的value是String类型,则不论你的key是什么名字,都可以存进去,而非String的value值则不会存进去。

@ModelAttribute的使用:

有了mybatis后此注解基本不使用了。当时和hebernate一起使用。

在这里插入图片描述
@ModelAttribute的使用场景(以图书管理为例):

在这里插入图片描述
POJO对象理想的封装过程:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

研究DispatchServlet类:

在这里插入图片描述
两个重要的方法:
(1)执行目标方法:
在这里插入图片描述

(2)转发到目标页面:

在这里插入图片描述

doDispatch方法的源码理解:
在这里插入图片描述

在这里插入图片描述

5.处理器/控制器Controller的方法被调用执行,返回一个ModelAndView:
在这里插入图片描述

没有视图名称的话,设置一个默认的视图名。
在这里插入图片描述

6.转发到目标页面(doDispatch方法中调用了此方法):
在这里插入图片描述
然后渲染视图,将数据填充到页面中。
在这里插入图片描述

具体整理以下步骤:
在这里插入图片描述

getHandler()处理细节:
在这里插入图片描述

在这里插入图片描述

每一个请求所对应的处理器/控制器。即请求地址对应的controller控制器。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

然后视图解析器进行
springmvc的九大组件:

在这里插入图片描述

@Nullable//文件上传解析器
    private MultipartResolver multipartResolver;
    @Nullable//区域信息解析器:和国际化有关
    private LocaleResolver localeResolver;
    @Nullable//主题解析器:强大的主题效果更换
    private ThemeResolver themeResolver;
    @Nullable//Handler映射信息:处理器映射器
    private List<HandlerMapping> handlerMappings;
    @Nullable//处理器适配器
    private List<HandlerAdapter> handlerAdapters;
    @Nullable//springmvc强大的异常解析共给你:异常解析器
    private List<HandlerExceptionResolver> handlerExceptionResolvers;
    @Nullable
    private RequestToViewNameTranslator viewNameTranslator;
    @Nullable//springmvc中运行重定向携带数据的功能
    private FlashMapManager flashMapManager;
    @Nullable//视图解析器
    private List<ViewResolver> viewResolvers;

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
确定参数:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

视图解析器的知识:

其他普通的页面跳转到WEB-INF下的pages下的jsp,可以通过默认的return 返回的试图名来完成,此方式默认的是转发。

特殊的其他跳转:

第一种跳转到当前项目下的页面:与WEB-INF同级目录:

在这里插入图片描述

第2种跳转到当前项目下的页面:与WEB-INF同级目录:

在这里插入图片描述

第三种:

在这里插入图片描述

在这里插入图片描述

重定向:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

总结:有前缀的转发和重定向操作,配置的视图解析器就不会进行拼串。

视图解析器如何解析视图:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

jstl视图解析器(JstlView)使用:

第一步,导入jstl的包:

在这里插入图片描述

第二步:配置springmvc.xml文件:

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

再配置一个资源文件管理器:
在这里插入图片描述

在这里插入图片描述

jsp页面先导入标签库:在这里插入图片描述

取国际化配置文件中的值:
国际化

国际化步骤总结:

在这里插入图片描述

注意:一定要过springmvc的视图解析流程,springmvc才会去创建一个jstlView帮我们快速国际化,也不能写forward:因为带forwa人的:信息的会创建一个不带国际化的视图解析器,如下代码
在这里插入图片描述

springmvc.xml中配置请求跳转页面:

在这里插入图片描述

在这里插入图片描述

自定义视图解析器:

有的时候 SpringMVC 框架提供的视图解析器不能满足我们的需求,这时候我们可以来自定义视图以及视图解析器来完成定制的功能。

主要分为以下三步:
(1)编写自定义视图实现类
(2)编写视图解析器的实现类
(3)在配置文件中将自定义的视图解析器注入ioc容器中
准备工作:
index写一个超链接,测试MyViewRessoverController

<%--
  Created by IntelliJ IDEA.
  User: fan
  Date: 2021/3/24
  Time: 16:38
  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>
 
  <a href="mv">测试自定义的视图解析器--下载美女资源</a>

  </body>
</html>

controller:(数据进行模拟)

package com.fan.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.ArrayList;

@Controller
public class MyViewRessoverController {
    @RequestMapping("/mv")
    public String handle01(Model model){
        ArrayList<String> vname = new ArrayList<>();
        //添加一些数据
        vname.add("张三");
        vname.add("李四");

        ArrayList<String> imgname = new ArrayList<>();
        imgname.add("萌萌");
		
		//将数据放到模型中
        model.addAttribute("video",vname);
        model.addAttribute("imgs",imgname);
        //让返回的视图名被我们自定义的视图解析器解析,前缀为mv:
        return "mv:/gaoqing";
    }

}

(1)编写自定义视图实现类

package com.fan.view;

import org.springframework.web.servlet.View;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

public class MyView implements View {
   
    @Override//渲染的方法
    public void render(Map<String, ?> map, HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 编写渲染视图页面的业务逻辑
        // 可以在这里取得 model 中保存的数据
        // 可以使用 request 和 response 进行请求和响应
        System.out.println("之前保存的数据:" + map);
        //输出:之前保存的数据:{video=[张三, 李四], imgs=[萌萌]}证明我们自定义的视图解析器起作用了
        //设置响应的内容格式,不至于乱码
        response.setContentType("text/html");
        response.getWriter().write("哈哈<h1>即将展现精彩内容</h1>");
    }
}

(2)编写视图解析器的实现类
让我们的视图解析器先工作,调整自定义视图解析器的执行顺序,要使得自定义的视图解析器实现Ordered接口。

package com.fan.view;
import org.springframework.core.Ordered;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import java.util.Locale;

public class MyViewResover implements ViewResolver, Ordered {
    // 视图解析器的遍历顺序
    private Integer order;
    @Override//解析视图名
    public View resolveViewName(String viewName, Locale locale) throws Exception {
        // 进行视图解析器的业务逻辑,返回视图对象则进行渲染,若返回 null 则继续遍历下一个视图解析器
        if (viewName.startsWith("mv:")) {
            return new MyView();
        }

        return null;
    }

    @Override
    public int getOrder() {
        return order;
    }

    //设置视图解析器的遍历顺序
    public void setOrder(Integer order){
        this.order = order;
    }
}

(3)springmvc.xml配置文件中配置我们自定义的视图解析器的bean,让ioc去管理:

<?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:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--注解扫描-->
    <context:component-scan base-package="com.fan"></context:component-scan>
    <!--mvc注解驱动-->
    <mvc:annotation-driven></mvc:annotation-driven>

    <!--视图解析器,这里我们配置自定义的视图解析器-->

    <!--自定义的视图解析器,value=1,数字越小,优先级越高-->
    <bean class="com.fan.view.MyViewResover">
        <property name="order" value="1"></property>
    </bean>

</beans>

运行测试,控制台输出:
之前保存的数据:{video=[张三, 李四], imgs=[萌萌]}
证明走了MyView中的代码;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值