Spring+SpringMVC+MyBatis-教程、笔记-3

base黑马,视频链接:https://www.bilibili.com/video/BV1WZ4y1P7Bp?t=94.4
此系列文章可以当做视频的配套笔记,也可以当做自学SSM框架的教程。

Spring集成web环境-基本三层架构环境搭建

在原来代码的基础上,添加web层相关的坐标

<!--    添加web层相关的坐标-->
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.0.1</version>
  <scope>provided</scope>
</dependency>

<dependency>
  <groupId>javax.servlet.jsp</groupId>
  <artifactId>javax.servlet.jsp-api</artifactId>
  <version>2.2.1</version>
  <scope>provided</scope>
</dependency>

编写web层的代码UserServlet 继承 HttpServlet

package com.lyh.web;

import com.lyh.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ApplicationContext app= new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) app.getBean("userService");
        userService.save();
    }
}

在 web.xml文件中 配置Servlet

<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">

  <servlet>
    <servlet-name>UserServlet</servlet-name>
    <servlet-class>com.lyh.web.UserServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>UserServlet</servlet-name>
    <url-pattern>/userServlet</url-pattern>
  </servlet-mapping>

</web-app>

将项目发布到TomCat上
效果:image.png
image.png

Spring继承web环境-ContextLoaderListener监听器的分析

应用上下文的获取方式
在web层通过Spring容器获得Service,Service内部的Dao是在容器内部注入的
ApplicationContext app= new ClassPathXmlApplicationContext(“applicationContext.xml”);
上面的代码获得应用上下文的
web层有很多业务,有很多的servlet组件,而每个当中如果想去调用方法,都需要应用上下文去获取service,每一个doGet、doPost都得写上面的一句话,配置文件和容器得创建很多个。(没有意义)
所有的配置都是在xml中配置的,加载一次创建一个Spring容器供大家去使用就可以了。image.png
可以使用监听器。
ApplicationContext app= new ClassPathXmlApplicationContext(“applicationContext.xml”),这句话放到服务器一启动就让它创建,创建好的应用上下文对象,放到最大的域当中,也就是ServletContext(ApplicationContext域)域中。
在web层任何Servlet当中都能拿到最大的ServletContext域当中的应用上下文,因为达到了数据共享。
为什么用监听器?
服务器一启动,项目一被加载就会创建ServletContext对象(代表Servlet上下文)。ServletContext对象一被创建,就会有一个监听器被执行,ServletContextListener这个监听器就会被执行(专门监听ServletContext对象创建的)。如果编写一个ServletContextListener就会监听服务器启动,可以把ApplicationContext app= new ClassPathXmlApplicationContext(“applicationContext.xml”),这个代码放到监听器初始化方法当中,创建好的对象可以放到最大的域当中。
image.png

Spring集成web环境-自定义ContextLoaderLIstener1

编写监听器类 ContextLoaderListener 内容如下所示:

package com.lyh.listener;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class ContextLoaderListener implements ServletContextListener {
    //上下文初始化的方法
    @Override	
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        ApplicationContext app= new ClassPathXmlApplicationContext("applicationContext.xml");
        //得放到一个位置,让别人能在web层拿到 所以
        //将Spring的应用上下文对象存储到最大的域当中ServletContext域中
        ServletContext servletContext = servletContextEvent.getServletContext();
        servletContext.setAttribute("app",app);
        System.out.println("Spring容器创建完毕。。。 ");
    }

    //上下文销毁的方法
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
    
}

在web.xml中配置监听器

<!--  配置监听器-->
<listener>  
  	<listener-class>com.lyh.listener.ContextLoaderListener</listener-class>
</listener>

web层UserServlet类中的代码

package com.lyh.web;

import com.lyh.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //这是一种获取方式
        //ServletContext servletContext = req.getServletContext();
        //另一种获取方式
        ServletContext servletContext = this.getServletContext();
        ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app");
        UserService userService = (UserService) app.getBean("userService");
        userService.save();
    }
}

重启服务器的效果:
image.png
image.png
image.png

Spring集成web环境-自定义ContextLoaderListener2

优化:
优化点1:
ContextLoaderListener类中的
ApplicationContext app= new ClassPathXmlApplicationContext(“applicationContext.xml”);
这行代码是写死的。具体点说就是applicationContext.xml这个代码是写死的。
可以把这个东西提升配置文件解耦,web.xml本身就是配置文件。
web.xml文件中的配置

<!--Web工程中的全局初始化参数-->
<!--  其中的名字和值可以自己定义-->
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>applicationContext.xml</param-value>
</context-param>
<!-- 这里会有一个爆红,但是不要紧 -->

ContextLoaderListener类中的内容

package com.lyh.listener;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class ContextLoaderListener implements ServletContextListener {
    //上下文初始化的方法
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        ServletContext servletContext = servletContextEvent.getServletContext();
        //读取web.xml中的全局参数
        String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");
        ApplicationContext app = new ClassPathXmlApplicationContext(contextConfigLocation);

        //得放到一个位置,让别人能在web层拿到 所以
        //将Spring的应用上下文对象存储到最大的域当中ServletContext域中
        servletContext.setAttribute("app",app);
        System.out.println("Spring容器创建完毕。。。 ");
    }

    //上下文销毁的方法
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}

如果后期的配置文件的名字不叫applicationContext.xml这个名字,直接在web.xml配置文件中进行更改就可以了。
重启服务器…
效果:
image.png
是可以进行下去的

优化点2:
在web层的UserServlet类中

package com.lyh.web;

import com.lyh.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
         //这个app这个名字也是耦合死的,每次都得需要客户端去记住这个app这个名字(不太好)
        ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app");
        UserService userService = (UserService) app.getBean("userService");
        userService.save();
    }
}

在listener包下面创建WebApplicationContextUtils类,内容如下:

package com.lyh.listener;

import org.springframework.context.ApplicationContext;
import javax.servlet.ServletContext;

public class WebApplicationContextUtils {
    //建立工具方法
    public static ApplicationContext getWebApplicationContext(ServletContext servletContext){
        return (ApplicationContext) servletContext.getAttribute("app");
    }
}

web层中的UserServlet中的代码

package com.lyh.web;

import com.lyh.listener.WebApplicationContextUtils;
import com.lyh.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//这里需要仔细思考
public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        //ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app");
        //也就是这里的servletContext.getAttribute("app");过程交给了一个方法去执行
        //这里就不具体的字符串了
        ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        UserService userService = (UserService) app.getBean("userService");
        userService.save();
    }
}

效果:
image.png
image.png
image.png

Spring集成web环境-Spring集成web环境代码实现

Spring提供获取应用上下文的工具
image.png
Spring提供的工具和自己手动写的是一样的。
image.png
导入坐标:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>5.0.5.RELEASE</version>
</dependency>

在web.xml文件中进行配置

<!--全局初始化参数-->
<context-param>
  <param-name>contextConfigLocation</param-name>
  <!--需要指定文件的位置,这个文件在类加载路径当中-->
  <param-value>classpath:applicationContext.xml</param-value>
</context-param>

<!--  配置监听器-->
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

测试代码,UserServlet类中的代码

package com.lyh.web;

import com.lyh.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        //ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app");
        //这里就不具体的字符串了
        //ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        //WebApplicationContext 是 ApplicationContext 的 子
        //WebApplicationContext、ApplicationContext 这两个接收都是可以的
        ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        UserService userService = (UserService) app.getBean("userService");
        userService.save();
    }
}

重启服务器
效果:
image.png

SpringMVC简介-SpringMVC概述

image.png
M:Model,主要用于数据封装和业务逻辑处理
V:View,视图,主要用于数据的展示
C:Controller,控制器,主要用于分发,指派的工作。
Servlet内部有很多行为都是重复的。
一般Servlet内部执行的动作就是,接收请求参数、封装实体、访问业务层、接收返回结果、指派页面
可以将重复的行为给抽取出来。
抽取的部分一般是web层的框架,帮助完成的操作。image.png
在web应用的内部是web层的组件负责接收请求,比如就是Servlet。
客户端发送请求,首先接收请求的是TomCat服务器中的引擎。
TomCat引擎第一步要做的事情,是接收客户端的请求
然后将请求中的数据进行封装
HTTP请求、请求行、请求头、请求体等这些数据都会被TomCat进行封装。
第二步TomCat会封装一个代表请求的request对象 和 一个代表响应的response对象
现在请求是有数据的,而响应是没有数据的
第三步TomCat这个引擎会帮助去调用对应的资源(根据请求的地址)
共有行为:接收数据、封实体、指派视图等这些都是公有行为。
特有行为:每一个Servlet负责的功能不一致。
请求再过去会找共有行为的Servlet,内部再去调用特有行为的资源,特有行为的资源不一定是Servlet了,是一个普通的POJO就行。
共有行为一般是框架帮忙封装的,一般称之为前端控制器。(前端控制器这种思想是web层的框架基本都有的)
不同的框架充当前端控制器的技术是不一样的。
SpringMVC充当前端控制器的技术就是一个Servlet
Struts2充当前端控制器的技术是Filter
前端控制器内部的代码十分复杂。

SpringMVC简介-SpringMVC的开发步骤

前端控制器是SpringMVC的核心。
1、导入SpringMVC的包
2、配置Servlet(TomCat的请求过去之后,每个请求都让找这个共有行为的Servlet,再去分发特有行为的,配置一个 / ,表示每个请求都要过这个共有行为的前端控制器)
3、编写POJO、在SpringMVC中习惯把这个POJO简单的称之为Controller。
POJO可以通过Bean标签配置到Spring容器当中,也可以使用注解
SpringMVC主张使用注解的方式
4、将Controller使用注解配置到Spring容器当中,使用@Controller注解
5、配置组件扫描,可以配置到Spring的配置文件当中,但是SpringMVC有一个自己的配置文件
配置Spring-mvc.xml文件(配置组件扫描)
6、执行访问的测试。image.png
image.png

SpringMVC简介-SpringMVC快速入门代码实现

1、导入相关坐标,导完之后,内部就有了前端控制器了。

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>5.0.5.RELEASE</version>
</dependency>

2、在web.xml文件中配置SpringMVC的前端控制器

<!--  配置SpringMVC的前端控制器-->
<servlet>
  <servlet-name>DispatcherServlet</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <!--    代表服务器启动时就加载这个Servlet创建对象-->
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>DispatcherServlet</servlet-name>
  <!-- / 代表缺省的servlet,每次在访问时,任何请求都要走这个servlet-->
  <!--在开发中有的是 *.xxx类型的,意味着这个请求的资源的扩展名是xxx的时才会走这个servlet-->
  <url-pattern>/</url-pattern>
</servlet-mapping>

3、编写视图,在webapp下面创建一个jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
  <html>
    <head>
      <title>Title</title>
    </head>
    <body>
      <h1>Success!</h1>
    </body>
  </html>

4、编写controller层的UserController

package com.lyh.controller;

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

//放到Spring容器当中
@Controller
    public class UserController {
        //在请求的时候,我请求的地址和方法之间有一个映射关系,这个映射关系用注解去替代
        //请求映射
        @RequestMapping("/quick")
        public String save(){
            System.out.println("Controller save running...");
            return "success.jsp";
        }

    }

5、创建SpringMVC的配置文件spring-mvc.xml。可以在applicationContext.xml中进行包扫描,但是要分开的,SpringMVC的配置是要配置到SpringMVC的配置文件中。

<?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"
  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">
  <!--这个配置文件中只扫描web层的,也就是controller层的-->
  <!--service层和dao层注解的扫描放到Spring的配置文件applicationContext.xml这个文件中进行组件的扫描-->
  <!--    Controller的组件扫描-->
  <context:component-scan base-package="com.lyh.controller"/>
</beans>

但是现在还有一个问题,spring-mvc.xml的文件没有被加载。SpringMVC的配置文件得告诉是在哪里的。
SpringMVC的配置文件是前端控制器来用,所以得告诉这个控制器,SpringMVC的配置文件是在那里。

所以在web.xml文件中的前端控制器中添加

 <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring-mvc.xml</param-value>
  </init-param>

在web.xml文件中新加的内容

<!--  配置SpringMVC的前端控制器-->
<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:spring-mvc.xml</param-value>
  </init-param>
  <!--    代表服务器启动时就加载这个Servlet创建对象-->
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>DispatcherServlet</servlet-name>
  <!-- / 代表缺省的servlet,每次在访问时,任何请求都要走这个servlet-->
  <!--在开发中有的是 *.xxx类型的,意味着这个请求的资源的扩展名是xxx的时才会走这个servlet-->
  <url-pattern>/</url-pattern>
</servlet-mapping>

6、进行测试
结果:
image.png
image.png

SpringMVC简介-快速入门的流程和小结

代码角度的一个过程
image.png
image.png
Service就是配置的那个前端控制器,前端控制器就是一个Servlet,Servlet内部直接接收请求就是Serviceimage.png

SpringMVC组件解析-SpringMVC执行流程

image.png
很多工作都是前端控制器进行封装,其实不是的,这个前端控制器只是负责调度,进行相应的组件调用。
在SpringMVC内部,很多功能,都有对应的组件帮助我们去完成,就是分工很明确。
DispatcherServlet,得知道根据请求去找那个资源
找资源解析资源的过程不是DispatcherServlet完成的
DispatcherServlet 会去请求 HandlerMapper(处理器映射器) 这个组件
HandlerMapper(处理器映射器)负责对请求进行解析,知道最终要找谁
HandlerMapper返回的并不是某一个资源的地址 而是 一串资源的地址
SpringMVC后期要学习 interceptor拦截器,有可能在执行到 目标Controller之前,要执行很多的Interceptor
所以,在执行的过程中,要执行很多的资源,最终才能到达目标Controller
HandlerMapper 会返回一个 HandlerExecutionChain(返回处理器执行链)
这个 链对象 内部封装着 要执行的 很多资源的顺序
HandlerAdapter(处理器适配器)负责去执行 调度 要被执行的资源
这里的Handler(处理器),可以认为这个是自己写的Controller
ViewResolver(视图解析器),负责从ModelAndView中 把视图对象给解析出来
目前接触最多的就是JSP,是一种视图对象类型
对这个视图要进行,解析渲染,最终把内容返回给客户端。image.png

SpringMVC组件解析-SpringMVC注解解析

image.png

package com.lyh.controller;

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

    //放到Spring容器当中
    @Controller
    @RequestMapping("/user")
    public class UserController {
        //在请求的时候,我请求的地址和方法之间有一个映射关系,这个映射关系用注解去替代
        //请求映射
        //请求地址 http://localhost:8080/spring_demo_01/user/quick
        @RequestMapping("/quick")
        public String save(){
            System.out.println("Controller save running...");
            //当前访问的是quick这个资源,所在的地址是前面的user
            //所以会去找http://localhost:8080/spring_demo_01/user 下面的jsp
            //这里是一个相对地址,相对当前资源所在地址,加上一个 / 就没有问题了
            return "/success.jsp";
        }

    }

错误的效果:
image.png
正常的效果:
image.png
@RequestMapping中的属性
value属性:如果这个属性只写一个并且这个属性的名称是value的话,可以省略掉,多个属性就不能省略掉
@RequestMapping(value = “/quick”)
method属性:可以指定请求方式,method的值是枚举方式的
@RequestMapping(value = “/quick”,method = RequestMethod.POST)
当前访问quick的请求方式必须是post的方式才可以访问到
再次访问会出现错误
image.png
当请求方式是 Get 的方式时
@RequestMapping(value = “/quick”,method = RequestMethod.GET)
效果:
image.png
params属性:限定请求参数条件的。
比如在请求的时候,必须得携带个什么参数,或者不要是什么参数,或者是不要是什么值。
@RequestMapping(value = “/quick”,method = RequestMethod.GET,params = {“username”})
params的值可以是数组,可以组织多个参数的限制条件。
此时表示在请求quick时,必须携带username参数,如果不携带,这个资源是不能让访问到的。
出问题的效果:
image.png
正确的效果:
image.png

SpringMVC组件解析-SpringMVC组件扫描

<!--    Controller的组件扫描-->
<context:component-scan base-package="com.lyh">
  <!-- include-filter-->
  <!-- 将 @Controller 注解的全茂名写到下面 表示只扫描com.lyh包下面的@Controller注解-->
  <!-- exclude-filter -->
  <!-- 扫描com.lyh 这个包下面的不包括 @Controller注解 -->
  <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--    Controller的组件扫描-->
<context:component-scan base-package="com.lyh.controller"/>

SpringMVC组件解析-SpringMVC的XML配置解析(资源解析器)

SpringMVC底层在操作时,有很多的组件:处理器映射器、处理器适配器、视图解析器,这些都可以进行配置。
这些是有默认的,不去配置也是可以完成的。
image.png
这个组件内部配置的都是一些默认的组件。

# Default implementation classes for DispatcherServlet's strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers.

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver

org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter

org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

但是此时可以对内部的功能做指定的增强
image.png
进入上面的资源里面
image.png
image.png
image.png

	@RequestMapping(value = "/quick",method = RequestMethod.GET,params = {"username"})
    public String save(){
        System.out.println("Controller save running...");
        //这里将forward:省略掉了,forward:可以省略
        //地址没有变化,又可以看到对应的视图,是转发的行为。
        return "forward:/success.jsp";
    }

forward(转发):地址没有变化,又可以看到对应的视图,是转发的行为。
redirect(重定向):如果地址有变化,又可以看到对应的视图,是重定向的行为。

转发效果:地址没有发生改变
image.png
重定向效果:地址发生了改变
image.png
image.png
有对应的set方法
set前缀、set后缀
对于这些,我们可以在配置文件中复写一下视图解析器,重新配置一下视图解析器,指定前缀和后缀。
image.png设置这样的目录结构

	@RequestMapping(value = "/quick",method = RequestMethod.GET,params = {"username"})
    public String save(){
        System.out.println("Controller save running...");
        return "/jsp/success.jsp";
    }

效果:
image.png
也是可以的。


image.png
image.png

<!--    配置内部资源视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- /jsp/ success .jsp    -->
  <property name="prefix" value="/jsp/"/>
  <property name="suffix" value=".jsp"/>
</bean>
package com.lyh.controller;

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

	//放到Spring容器当中
	@Controller
    @RequestMapping("/user")
    public class UserController {
        @RequestMapping(value = "/quick",method = RequestMethod.GET,params = {"username"})
        public String save(){
            System.out.println("Controller save running...");
            return "success"; //这里就可以这样写了
        }

    }

效果:也是可以的
image.png

SpringMVC组件解析

image.png

SpringMVC的数据响应-数据响应方式

image.png

SpringMVC的数据响应-页面跳转-返回字符串形式

image.png
image.png
重定向代表客户端再次访问,而 WEB-INF 属于受保护的文件夹,外界不能直接访问到WEB-INF,要想重定向,资源必须处在一个可以有权限被访问的位置。

SpringMVC的数据响应-页面跳转-返回ModelAndView形式1

	@RequestMapping(value = "/quick2")
    public ModelAndView save2(){
        /*
        Model:模型 作用是封装数据的
        View:视图 作用是展示数据的
		*/
        ModelAndView modelAndView = new ModelAndView();
        //可以单独只给一个视图
        modelAndView.setViewName("success");
        return  modelAndView;
    }

效果:
image.png

	@RequestMapping(value = "/quick2")
    public ModelAndView save2(){
        /*
            Model:模型 作用是封装数据的
            View:视图 作用是展示数据的
         */
        ModelAndView modelAndView = new ModelAndView();
        //设置模型数据,这个数据就相当于放到了域当中了
        modelAndView.addObject("username","李永恒");//这里不止能写字符串 还 可以写其他类型的数据
        //设置视图名称,可以单独只给一个视图
        modelAndView.setViewName("success");
        return  modelAndView;
    }

success.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
  <html>
    <head>
      <title>Title</title>
    </head>
    <body>
      <%--用EL表达式 取 键值对 的 键的名称--%>
        <h1>Success!${username}</h1>
    </body>
  </html>

效果:
image.png

SpringMVC的数据响应-页面跳转-返回ModelAndView形式2

	@RequestMapping(value = "/quick3")
    public ModelAndView save3(ModelAndView modelAndView){
        modelAndView.addObject("username","LiYongHeng");
        modelAndView.setViewName("success");
        return  modelAndView;
	}

效果:
image.png
SpringMVC对方法的参数,可以帮你进行相应的注入。
SpringMVC在解析这个方法的时候发现参数
有一个ModelAndView需要SpringMVC框架提供,那这个SpringMVC就为你提供一个ModelAndView对象。
所以在内部可以直接使用。

	@RequestMapping(value = "/quick4")
    public String save4(Model model){
        model.addAttribute("username","LYH");
		return "success";
	}

效果:
image.png

SpringMVC的数据响应-页面跳转-返回ModelAndView形式3

用原始的方式,往域当中存数据。

	//这个方法是SpringMVC框架帮忙调用的
    //在调用时,常用的一些对象,能想到的,基本上框架的编写者都想到了
    //如果想用Request对象 加入形参 SpringMVC框架帮忙注入
	//这种方式不常用
    @RequestMapping(value = "/quick5")
    public String save5(HttpServletRequest request){
        //request 是 TomCat服务器帮忙创建的request对象
        //request对象内部是有东西的,Http请求的数据,都在这里封装着,请求行、请求头、请求体等
        request.setAttribute("username","RedmiBook14 锐龙版");
    	return "success";
	}

效果:
image.png

SpringMVC的数据响应-回写数据-直接回写字符串

image.png

	@RequestMapping(value = "/quick6")
    public void save6(HttpServletResponse response) throws IOException {
        response.getWriter().println("Hello RedmiBook");
    }

效果:
image.png
image.png

	@RequestMapping(value = "/quick7")
    //告知SpringMVC框架 该方法 不进行视图跳转 直接进行 数据响应 
    //响应的数据以HTTP响应体的方式回写
    @ResponseBody 
    public String save7(){
        return "Hello~~RedmiBook";
    }

效果:
image.png

SpringMVC的数据响应-回写数据-直接回写json格式字符串

	@RequestMapping(value = "/quick8")
    @ResponseBody
    public String save8(){
        return "{\"username\":\"zhangsan\",\"age\":18}";
    }

效果:
image.png
使用Jackson工具的方式转换JSON
创建User类

package com.lyh.domain;

public class User {
    private String username;
    private int age;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
            "username='" + username + '\'' +
            ", age=" + age +
            '}';
    }
}
pom.xml文件中导入相关依赖
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.9.0</version>
</dependency>

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

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

controller层的代码

	@RequestMapping(value = "/quick9")
    @ResponseBody
    public String save9() throws JsonProcessingException {
        //模拟一下对象
        User user = new User();
        user.setAge(18);
        user.setUsername("lisi");
        //需要把 user 对象转换成 JSON 返回
        //使用JSON的转换工具 将 对象转换成JSON格式的字符串 再返回
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(user);
        return json;
	}

效果:
image.png

SpringMVC的数据响应-回写数据-返回对象或集合

返回对象或集合
image.png
现在用的处理器适配器就是这个处理器适配器
但是现在这个处理器适配器默认情况下,不能帮忙转换
我需要在用到这个处理器适配器的时候,告诉它,我内部需要用到这个JSON转换工具去转换

里面有这样的一个方法
image.png
在配置适配器时,可以让你指定多个消息转换器
可以自己在配置转换器的时候,指定一个JSON转换的转换器。

在 spring-mvc.xml 中进行相关的配置

<!--    在这里配置一下 处理器适配器 并且在内部进行参数设置 告诉其 使用Jackson进行转换-->
<!--    配置处理器映射器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
  <property name="messageConverters">
    <list>
      <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
    </list>
  </property>
</bean>

UserController类中的

	@RequestMapping(value = "/quick10")
    @ResponseBody
    //期望SpringMVC自动把User转换成JSON字符串
    public User save10() throws JsonProcessingException {
        User user = new User();
        user.setAge(22);
        user.setUsername("WangWu");
        return user;
    }

效果:
image.png

SpringMVC的数据响应-回写数据-返回对象或集合2

<!--    在这里配置一下 处理器适配器 并且在内部进行参数设置 告诉其 使用Jackson进行转换-->
<!--    配置处理器映射器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
  <property name="messageConverters">
    <list>
      <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
    </list>
  </property>
</bean>

以上的配置相对来说是比较麻烦的。image.png
image.png

spring-mvc.xml文件中的修改

<!--    在这里配置一下 处理器适配器 并且在内部进行参数设置 告诉其 使用Jackson进行转换-->
<!--    配置处理器映射器-->
<!--    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">-->
<!--        <property name="messageConverters">-->
<!--            <list>-->
<!--                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>-->
<!--            </list>-->
<!--        </property>-->
<!--    </bean>-->

<!--    mvc的注解驱动-->
<mvc:annotation-driven/>

UserController类中的代码

	@RequestMapping(value = "/quick10")
    @ResponseBody
    //期望SpringMVC自动把User转换成JSON字符串
    public User save10() throws JsonProcessingException {
        User user = new User();
        user.setAge(22);
        user.setUsername("WangWu");
        return user;
	}

效果:
image.png
也是可以的

SpringMVC的数据响应-知识要点小结

image.png

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值