【技术详解】SpringMVC框架全面解析:从入门到精通(SpringMVC)

文章目录

  • 【技术详解】SpringMVC框架全面解析:从入门到精通(SpringMVC)
    • SpringMVC概述
    • [1. 三层架构与MVC架构区别](#1. 三层架构与MVC架构区别)
    • [2. SpringMVC环境搭建](#2. SpringMVC环境搭建)
      • [2.1 注解启动方式](#2.1 注解启动方式)
      • [2.2 xml启动方式](#2.2 xml启动方式)
      • [2.3 SpringMVC PostMan工具使用](#2.3 SpringMVC PostMan工具使用)
    • [3. SpringMVC 请求与响应](#3. SpringMVC 请求与响应)
      • [3.1 springmvc 5种接受参数类型](#3.1 springmvc 5种接受参数类型)
      • [3.2 springmvc接受json数据](#3.2 springmvc接受json数据)
      • [3.3 springmvc响应json数据](#3.3 springmvc响应json数据)
      • [3.4使用HttpServletRequest 获取参数](#3.4使用HttpServletRequest 获取参数)
      • [3.5 springmvc restful简单介绍](#3.5 springmvc restful简单介绍)
      • [3.6 springmvc 整合jsp技术(过时 了解该技术)](#3.6 springmvc 整合jsp技术(过时 了解该技术))
    • [4. spring+springmvc+mybatis整合](#4. spring+springmvc+mybatis整合)
      • 4.1SSM环境的整合之提供增删改查
      • [4.2 SSM环境的整合之配置整合](#4.2 SSM环境的整合之配置整合)
      • [4.3 接口响应状态码](#4.3 接口响应状态码)
      • [4.4 整合全局捕获异常](#4.4 整合全局捕获异常)

【技术详解】SpringMVC框架全面解析:从入门到精通(SpringMVC)

SpringMVC概述

  1. SpringMVC 是一种基于 Java 实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,它和 Struts2 都属于表现层的框架,属于 Spring FrameWork 的后续产品,Spring MVC 分离了控制器、模型对象、过滤器以及处理程序对象的角色,这种分离让它们更容易进行定制。
  2. SpringMVC 已经成为目前最主流的 MVC 框架之一,并且随着 Spring3.0 的发布,全面超越 Struts2,成 为最优秀的 MVC 框架,它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持 RESTful 编程风格的请求。

简单总结:SpringMVC是一种基于Java实现MVC模型轻量级框架, 底层基于Servlet封装

1. 三层架构与MVC架构区别

1.1 三层架构

表示层:主要对用户的请求接受,以及数据的返回,为客户端提供应用程序的访问。 servlet层

业务逻辑层:对我们数据实现业务逻辑的封装 service层

数据访问层:对数据库访问操作 dao层
com.zhaoli.servlet----表示层
com.zhaoli.service----业务逻辑层
com.zhaoli.dao----数据库访问层

1.2 MVC架构

M 代表 模型(Model)

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。

  1. M 代表 模型(Model)(业务逻辑层+数据库访问组合)
    模型就是数据,就是 dao,bean
    模型是应用程序中用于处理应用程序数据逻辑的部分。
    通常模型对象负责在数据库中存取数据。
  2. V 代表 视图(View)(前端)
    视图就是网页, JSP,用来展示模型中的数据
    视图是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。
  3. C 代表 控制器(controller)
    控制器的作用就是把不同的数据(Model),显示在不同的视图(View)上,Servlet 扮演的就是这样的角色。
    控制器是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
  • 三层是基于业务逻辑来分的,而MVC是基于页面来分的
  • 三层是软件架构,通过接口实现编程;MVC模式是一种复合设计模式,一种解决方案
  • 三层模式是体系结构模式,MVC是设计模式
  • 三层模式又可归于部署模式,MVC可归于表示模式

1.3前后端分离开发模式

体现 让专业的人做专业的事情,前端代码由前端来完成,后端代码由我们后端来完成,后端程序只需要将接口数据提供给前端调用即可。

前端:vue、饿了么UI、网页数据 例如 html、js、css

后端:接口中数据 springmvc+mybatis

将前端和后端代码分开的

View视图层---jsp、ftl、js、css
com.zhaoli.controller----控制层springmvc 底层基于servlet封装 控制页面跳转、控制页面展示数据
com.zhaoli.controller----返回json 给前端
com.zhaoli.service----业务逻辑层
com.zhaoli.dao----数据库访问层

2. SpringMVC环境搭建

2.1 注解启动方式

创建maven工程

Maven依赖

xml 复制代码
<!-- 整合springmvc框架依赖  -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.10.RELEASE</version>
</dependency>

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

创建控制器层

java 复制代码
package com.zhaoli.controller;

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

import java.util.HashMap;
import java.util.Map;

@Controller
public class MayiktController {
    /**
     * 1.@Controller  标记该类是为 SpringMVC控制类
     * 2.@RequestMapping("") 定义url映射  类似与servlet里面的@WebServlet("")
     * 3.@ResponseBody 该接口返回我们的json数据
     */

    /**
     * 访问到请求 返回json数据
     */
    public String getMayikt() {
        //访问该接口的 返回json数据
        return "{code:'200',mgs:'ok'}";
}
}

创建配置类

java 复制代码
package com.zhaoli.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.zhaoli.controller")
public class SpringMVCConfig {
    /**
     * 1.@Configuration 相当于定义了SpringMVCConfig.xml配置文件
     * 2.@ComponentScan("com.zhaoli.controller") 将该包下所有的类注入到IOC容器中
     * 3.在SpringMVC原理中所有请求过来先到达我们的DispatcherServlet分发到具体控制类的方法进行执行
     */
}

注册配置类

java 复制代码
package com.zhaoli.config;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;

public class ServletInitializer extends AbstractDispatcherServletInitializer {
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        //注册我们的 SpringMVC config 配置类
        AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext =
                new AnnotationConfigWebApplicationContext();
        annotationConfigWebApplicationContext.register(SpringMVCConfig.class);
        return annotationConfigWebApplicationContext;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};//拦截所有的servlet请求
    }

    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }
}

maven tomcat插件运行

xml 复制代码
 <build>
    <plugins>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <configuration>
                <port>85</port>
                <path>/</path>
                <ignorePackaging>true</ignorePackaging>
            </configuration>
        </plugin>
    </plugins>
</build>

之后运行要是没有反应 先点击

之后再运行项目

在添加 servlet 依赖

xml 复制代码
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>

看到这样就是运行成功了

搭建环境常见问题

1.扫包范围填写错误 @ComponentScan("com.mayikt.controller") 导致接口访问404

2.在控制类没有加上@Controller 导致接口访问404

2.2 xml启动方式

Maven依赖

xml 复制代码
<!-- 整合springmvc框架依赖  -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.10.RELEASE</version>
</dependency>

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

创建控制器层

java 复制代码
package com.zhaoli.controller;

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

@Controller
public class MayiktController {
    @RequestMapping("getMayikt")
    public String getMayikt(){
        return "ok";
    }
}

spring-mvc.xml 配置

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-mvc.xml 就相当于新建了一个类(SpringMVCConfig) 并且在该类上加上了 @Configuration -->
    <!--配置spring创建容器时要扫描的包  相当于在类(SpringMVCConfig)加上了@ComponentScan("com.zhaoli.controller") -->
    <context:component-scan base-package="com.zhaoli.controller"></context:component-scan>
    <!-- 配置spring开始注解mvc的支持 -->
    <mvc:annotation-driven></mvc:annotation-driven>
</beans>

这是配置 spring-mvc.xml 的模板可以直接粘贴

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

注意粘贴时将这一段代码替换掉

web.xml配置

所有请求过来都是先达到我们的DispatcherServlet

springmvc 基于 Servlet封装

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <!-- 此 web.xml 就相当于新建了一个类(ServletInitializer extends AbstractDispatcherServletInitializer)  -->
    <!-- 配置 springmvc  -->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <!-- java反射机制加载 -->
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- servlet初始化加载我们的 spring-mvc.xml -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <!-- 让我们的 springmvc DispatcherServlet优先加载 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!-- 客户端所有请求都会到达我们的 DispatcherServlet (包括静态资源 控制器类中的请求) -->
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <display-name>Archetype Created Web Application</display-name>
</web-app>

这是配置 web.xml 的模板可以直接粘贴

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">

注意粘贴时将这一段代码替换掉

外部tomcat运行

需要将这些jar包存入 tomcat的lib目录 否则将会报错找不到类该类

2.3 SpringMVC PostMan工具使用

PostMan简介

一 简介 Postman 是一款功能超级强大的用于发送 HTTP 请求的 Chrome插件 。做web页面开发和测试的人员会使用到该工具其主要特点 特点: 创建 + 测试:创建和发送任何的HTTP请求,使用PostMan发送 Get、Post、Delete请求等。

3. SpringMVC 请求与响应

@RequestMapping
@RequestMapping注解是一个用来处理请求地址映射的注解,可用于映射一个请求或一个方法,可以用在类或方法上。

如果加载方法上就是具体访问路径 如果加载类上就是我们访问的前缀

springmvc 定义url路径是不允许重复

java 复制代码
package com.zhaoli.controller;

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

@Controller
@RequestMapping("/user")
public class UserController {
    /**
    * /add UserController.add  OrderController.add?
    * 如果我们将@RequestMapping注解加在我们的类上面 是访问该接口前缀
    * 如果加在方法上就是我们具体的访问路径
    * /user/add
    */
    
    @RequestMapping("/add")
    @ResponseBody
    public String add() {
        return "add ok";
    }
    
    @RequestMapping("/delete")
    @ResponseBody
    public String delete() {
        return "delete ok";
    }
    
    @RequestMapping("/select")
    @ResponseBody
    public String select() {
        return "delete ok";
    }
}
java 复制代码
package com.zhaoli.controller;

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

@Controller
@RequestMapping("/order")
public class OrderController {

    @RequestMapping("/add")
    @ResponseBody
    public String add() {
        return "add ok";
    }

    @RequestMapping("/delete")
    @ResponseBody
    public String delete() {
        return "delete ok";
    }
}
text 复制代码
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'userController' method  com.mayikt.controller.UserController#add() to { /add}: There is already 'orderController' bean method com.mayikt.controller.OrderController#add() mapped.

报错原因是因为 /add 这个url 路径在UserController类和 orderController类中都有

接受Get/Post请求参数

和Controller层方法的形参同名,那么可以直接通过参数名接收值即可

java 复制代码
package com.zhaoli.controller;

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

@Controller
public class MemberController {

    /**
     * addMember
     * RequestMapping 默认的情况下 RequestMapping支持所有请求方式 例如 get、post 、delete
     * method = RequestMethod.POST 设定该接口支持的POST
     */
    @RequestMapping(value = "/addMember", method = RequestMethod.POST)
    @ResponseBody
    public String addMemberPost(Integer id, String name) {
        System.out.println("id:" + id);
        System.out.println("name:" + name);
        return "ok";
    }

    /**
     * addMember
     * RequestMapping 默认的情况下 RequestMapping支持所有请求方式 例如 get、post 、delete
     * method = RequestMethod.GET设定该接口支持的类型 GET
     *
     */
    @RequestMapping(value = "/addMember", method = RequestMethod.GET)
    @ResponseBody
    public String addMemberGet(Integer id, String name) {
        System.out.println("id:" + id);
        System.out.println("name:" + name);
        return "ok---get";
    }
}

3.1 springmvc 5种接受参数类型

普通参数、对象参数、嵌套对象参数、数组参数、集合普通参数

1. 普通参数

  1. url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数;
  2. 如果发生url地址传参,地址参数名与形参变量名不同,使用@RequestParam绑定参数关系;
    参数:
    required:是否为必传参数
    defaultValue:参数默认值
java 复制代码
package com.zhaoli.controller;

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

@Controller
public class MayiktDemoController {
    //springmvc5种接受参数类型

    /**
     * 1.普通参数
     */
    @RequestMapping("/demo01")
    @ResponseBody
    public String demo01(String name, Integer age) {
        return "name:" + name + ",age:" + age;
    }

    /**
     * @RequestParam(name="name",required = false)
     * name="name" 传递的参数名称为 name 方法形参名称 mayiktName
     * required = false 是否必须传递该参数 默认为 true (必须传递改参数)  若为 false 可不传递该参数
     */
    @RequestMapping("/demo02")
    @ResponseBody
    public String demo02(@RequestParam(name = "name", required = false) String mayiktName, @RequestParam(name = "age", required = false) Integer mayiktAge) {
        return "mayiktName:" + mayiktName + ",mayiktAge:" + mayiktAge;
    }
}

报错原因:未传递 name 值

2.对象参数

请求参数名与形参对象属性名相同,定义对象类型形参即可接收参数

java 复制代码
package com.zhaoli.entity;

public class UserEntity {
    String userName;
Integer age;
}
java 复制代码
/**
* 2.对象参数
*/
@RequestMapping("/demo03")
@ResponseBody
public String demo03(UserEntity user) {
   return "userNmae:" + user.getUserName() + ",age:" + user.getAge();
}

3.嵌套对象参数

嵌套对象参数:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套对象属性参数

java 复制代码
package com.zhaoli.entity;

public class UserInfo {
    String addres;//地址
}
package com.zhaoli.entity;

public class UserEntity {
    String userName;
    Integer age;
UserInfo userInfo;
}
java 复制代码
/**
 * 3.嵌套对象参数
 * 地址栏传递 addres 值时必须用: userInfo.addres
 */
@RequestMapping("/demo04")
@ResponseBody
public String demo04(UserEntity user) {
    return "userNmae:" + user.getUserName() + ",age:" + user.getAge()+",addres:"+user.getUserInfo().getAddres();
}

报错原因:没有传递嵌套对象的值

4.数组参数

请求参数名与形参属性名相同且请求参数为多个,定义数组类型形参即可接收参数

java 复制代码
/**
 * 4.数组参数
 * demo05?arrays=zhaoli&arrays=fanjing
 */
@RequestMapping("/demo05")
@ResponseBody
public String demo05(String[] arrays) {
    return Arrays.toString(arrays);
}

5.集合保存普通参数

请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系
@RequestParam :同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据

java 复制代码
/**
 * 5.集合保存普通参数
 * list 集合类型
 */
@RequestMapping("/demo06")
@ResponseBody
public String demo06(@RequestParam List<String> arrays) {
    return Arrays.toString(arrays.toArray());
}

报错原因:没在List<String> arrays 前面加上 @RequestParam

3.2 springmvc接受json数据

开启接受json数据

java 复制代码
package com.zhaoli.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@ComponentScan("com.zhaoli.controller")
@EnableWebMvc
public class SpringMVCConfig {
    /**
     * 1.@Configuration 相当于定义了SpringMVCConfig.xml配置文件
     * 2.@ComponentScan("com.zhaoli.controller") 将该包下所有的类注入到IOC容器中
     * 3.在SpringMVC原理中所有请求过来先到达我们的DispatcherServlet分发到具体控制类的方法进行执行
     */
}

maven依赖

xml 复制代码
<!-- @RequestBody 接收 json 数据 -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>

接受参数加上@RequestBody UserEntity userEntity标记 接受json数据

自动根据json数据反序列化成对象userEntity

1.以实体类方式接收

实体类

java 复制代码
public class UserEntity {
    String userName;
    Integer age;
UserInfo userInfo;
}
public class UserInfo {
String addres;//地址
}
java 复制代码
package com.zhaoli.controller;

import com.zhaoli.entity.UserEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Arrays;
import java.util.List;

@Controller
public class MayiktDemoController {
/**
     * 接受 json 数据
     * 1.以实体类方式
     */
    @RequestMapping("/demo07")
    @ResponseBody
    public String demo07(@RequestBody UserEntity userEntity){
        return userEntity.toString();
	}
}


2.以Map接收
json数据 key是为 Mapkey value Mapvalue

需要注意json数据valueMap集合value类型保持一致否则报错

java 复制代码
/**
 * 接受 json 数据
 * 2.以Map接收
 */
@RequestMapping("/demo08")
@ResponseBody
public String demo08(@RequestBody Map<String,String> paramMap){
    return paramMap.toString();
}
java 复制代码
@RequestMapping("/demo09")
@ResponseBody
public String demo09(@RequestBody Map<String,Object> paramMap){
    return paramMap.toString();
}

3.以List接收

java 复制代码
/**
* 接受 json 数据
* 3.以List接收
*/
@RequestMapping("/demo10")
@ResponseBody
public String demo10(@RequestBody List<String> lists) {
   return lists.toArray().toString();
}


java 复制代码
@RequestMapping("/demo11")
@ResponseBody
public String demo11(@RequestBody List<UserEntity> lists) {
   return lists.toArray().toString();
}


3.3 springmvc响应json数据

  1. 在接口上加上@ResponseBody 根据该方法返回值 返回对应json数据 底层 根据返回值 序列化成json数据。
  2. @RestController 标记该控制类所有接口都是返回json数据
java 复制代码
package com.zhaoli.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @RestController 标记该控制类所有接口都是返回 json 数据
 * 相当于这两个同时作用 @Controller  @ResponseBody
 */
@RestController
public class MayiktRestController {
    @RequestMapping("/getRestMayikt")
    public Map<String, Object> getMayikt() {
        HashMap<String, Object> result = new HashMap<String, Object>();
        result.put("code", "200");
        result.put("msg", "ok");
        //访问该接口的 返回json数据
        return result;
    }
}

3.4使用HttpServletRequest 获取参数

springmvc底层基于Servlet
Servlet HttpServletRequest HttpServletResponse

获取httprequest/response三种方式

  1. public String mayikt(HttpServletRequest request,HttpServletResponse response)
  2. HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
java 复制代码
@Autowired
private HttpServletRequest request; 

3.5 springmvc restful简单介绍

什么是restful

Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格规范。基于这个风格设计的软件可以更简洁,更有层次。

资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。

传统方式操作资源:通过不同的参数来实现不同的效果,post 和 get。
http://127.0.0.1/mayikt/getUser?id=1 查询,GET 用户id是为1信息
http://127.0.0.1/mayikt/saveUser 新增,POST
http://127.0.0.1/mayikt/updateUser 更新,POST
http://127.0.0.1/mayikt/deleteUser?id=1 删除,GET

(查询、删除)get 写操作(新增、修改)Post

使用RESTful操作资源 :可以通过不同的请求方式来实现不同的效果

例如:请求地址一样,但是实现的效果不一样 例如

发送请求get 执行查询、 发送POST 执行新增、发送PUT执行更新、发送DELETE执行删除
http://127.0.0.1/user/1 查询,GET
http://127.0.0.1/user 新增数据,POST
http://127.0.0.1/user 更新,PUT
http://127.0.0.1/user/1 删除,DELETE

根据发送不同的类型 判断 访问不同的接口

restful案例演示

@RequestMappingvalue中使用URI template({变量名}),然后在@RequestMapping注解方法的需要绑定的参数前,使用@PathVariable指定变量名(如果变量名和参数名一致也可以不指定),从而将URL中的值绑定到参数上。
@RequestMapping组合注解
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping

java 复制代码
package com.zhaoli.controller;

import com.zhaoli.entity.UserEntity;
import org.springframework.web.bind.annotation.*;

@RestController
public class MayiktUserRestfulController {
    /**
     * Restful api 请求地址都是一样 根据不同请求方法判断
     * USer 增加/删除/修改/查询 api接口
     */

    /**
     * 提供根据 id 查询接口 ---请求方法的类型 GET 指定请求类型为 GET
     * /user/{id} :比如传递 user/1  就是将 1赋值给 id
     */
//    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    @GetMapping(value = "/user/{id}")
    public UserEntity getUser(@PathVariable("id") Integer id) {
        System.out.println("[getUser] id:" + id);
        return new UserEntity("mayikt" + id, 22);
    }

    /**
     * 提供根据 id 删除接口 ---请求方法的类型 DELETE 指定请求类型为 DELETE
     */
//    @RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE)
    @DeleteMapping(value = "/user/{id}")
    public String deleteUser(@PathVariable("id") Integer id) {
        System.out.println("[deleteUser] id:" + id);
        return "delete ok" + id;
    }

    /**
     * 新增添加数据接口 ---请求方法的类型 POST 指定请求类型为 POST
     * 传递 json 数据
     */
//    @RequestMapping(value = "/user", method = RequestMethod.POST)
    @PostMapping(value = "/user")
    public String addUser(@RequestBody UserEntity userEntity) {
        System.out.println("[addUser] userEntity:" + userEntity);
        return "add ok";
    }

    /**
     * 修改数据接口 ---请求方法的类型 PUT 指定请求类型为 PUT
     * 传递 json 数据
     */
//    @RequestMapping(value = "/user", method = RequestMethod.PUT)
    @PutMapping(value = "/user")
    public String updateUser(@RequestBody UserEntity userEntity) {
        System.out.println("[updateUser] userEntity:" + userEntity);
        return "update ok";
    }
}

3.6 springmvc 整合jsp技术(过时 了解该技术)

核心配置

java 复制代码
package com.mayikt.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@ComponentScan("com.mayikt.controller")
@EnableWebMvc
public class SpringMVCConfig   implements WebMvcConfigurer {
    /**
     * 1.@Configuration  定义SpringMVCConfig.xml配置文件
     * 2.需要将我们的控制类注入到ioc容器 @ComponentScan("com.mayikt.controller")
     * @ComponentScan("com.mayikt.controller")将该包下所有的类 注入到IOC容器种
     * 3.在springmvc原理 所有请求过来先达到我们的 DispatcherServlet 分发具体控制类 方法执行
     *
     *
     *    @Configuration
     *     SpringMVCConfig.java   @Configuration
     *     springmvc.xml=== SpringMVCConfig.java
     *     -->
     */

    //WebMvcConfigurer
    @Bean
    public InternalResourceViewResolver resourceViewResolver() {
        InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
        //请求视图文件的前缀地址
        internalResourceViewResolver.setPrefix("/WEB-INF/jsp/");
        //请求视图文件的后缀
        internalResourceViewResolver.setSuffix(".jsp");

        internalResourceViewResolver.setExposeContextBeansAsAttributes(true);
        return internalResourceViewResolver;
    }

    /**
     * 视图配置
     *
     * @param registry
     */
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.viewResolver(resourceViewResolver());
    }
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

webapp 目录下创建 WEB-INF/jsp 存放jsp

定义控制器

java 复制代码
package com.mayikt.controller;

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

import javax.servlet.http.HttpServletRequest;

@Controller
public class MayiktJspController {
    @RequestMapping("/mayiktJsp")
    public String mayiktJsp() {
        return "mayikt";
    }
}

定义jsp页面

html 复制代码
<%--
  Created by IntelliJ IDEA.
  User: mayikt
  Date: 2022/7/29
  Time: 16:12
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>mayikt</title>
</head>
<body>
springmvc整合jsp
</body>
</html>

4. spring+springmvc+mybatis整合

项目技术需求分析

使用ssm+layui技术开发 对用户表数据实现增删改查

采用前后端分离架构模式

4.1SSM环境的整合之提供增删改查

整合数据库表结构

sql 复制代码
CREATE TABLE `mayikt_users` (
	`id` INT NOT NULL AUTO_INCREMENT,
	`name` VARCHAR ( 255 ) CHARACTER 
	SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
	`age` INT DEFAULT NULL,
	`addres` VARCHAR ( 255 ) DEFAULT NULL,
	PRIMARY KEY ( `id` ) 
) ENGINE = INNODB AUTO_INCREMENT = 48 DEFAULT CHARSET = utf8mb3;

整合maven依赖

xml 复制代码
  <dependencies>
    <!--整合springmvc 底层会自动整合spring -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
    <!--整合mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.6</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.3.0</version>
    </dependency>
    <!-- mysql 驱动架包 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.13</version>
    </dependency>
    <!--使用alibaba数据源 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.16</version>
    </dependency>
    <!-- servlet 依赖 -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <!--使用@ResponseBody 能够响应数据 -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.0</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.1</version>
            <configuration>
                <port>80</port>
                <path>/</path>
            </configuration>
        </plugin>
    </plugins>
</build>

实体类层

java 复制代码
package com.zhaoli.entity;

public class UserEntity {
   private Integer id;
   private String name;
   private Integer age;
   private String addres;//地址
}

数据库访问层

java 复制代码
package com.zhaoli.mapper;

import com.zhaoli.entity.UserEntity;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

public interface UserMapper {
    /**
     * mybatis 注解方式
     */
    @Insert("INSERT INTO mayikt_users VALUES(null,#{name},#{age},#{addres});")
    int insertUser(UserEntity userEntity);

    @Delete("DELETE mayikt_users WHERE id=#{id};")
    int deleteById(Integer id);

    @Update("UPDATE mayikt_users SET name=#{name},aeg=#{age},addres=#{addres} WHERE id=#{id};")
    int update(UserEntity userEntity);

    @Select("SELECT * FROM mayikt_users WHERE id=#{id};")
    UserEntity getById(Integer id);
}

业务逻辑层

java 复制代码
package com.zhaoli.service;

import com.zhaoli.entity.UserEntity;
import com.zhaoli.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service //将该类注入到 ioc 容器中
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public int insertUser(UserEntity userEntity) {
        return userMapper.insertUser(userEntity);
    }

    public int deleteById(Integer id) {
        return userMapper.deleteById(id);
    }

    public int update(UserEntity userEntity) {
        return userMapper.update(userEntity);
    }

    public UserEntity getById(Integer id) {
        return userMapper.getById(id);
    }
}

控制层

java 复制代码
package com.zhaoli.controller;

import com.zhaoli.entity.UserEntity;
import com.zhaoli.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * 标记该类是为 SpringMVC控制类
 * 在该类中定义的接口都是返回 json 数据
 */
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    /**
     * 根据id查询数据
     */
    @GetMapping("/getById/{id}")
    public UserEntity getById(@PathVariable("id") Integer id) {
        return userService.getById(id);
    }

    /**
     * 修改数据
     */
    @PutMapping("/update")
    public int update(@RequestBody UserEntity userEntity) {
        return userService.update(userEntity);
    }

    /**
     * 根据 id 删除数据
     */
    @DeleteMapping("/deleteById/{id}")
    public int deleteById(@PathVariable("id") Integer id) {
        return userService.deleteById(id);
    }

    /**
     * 新增数据
     */
    @PostMapping("/insertUser")
    public int insertUser(@RequestBody UserEntity userEntity) {
        return userService.insertUser(userEntity);
    }
}

4.2 SSM环境的整合之配置整合

JdbcConfig

java 复制代码
package com.zhaoli.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

public class JdbcConfig {
    /**
     * 配置数据源信息
     * 注入到 ioc 容器中
     *
     * @Bean 相当于在xml中的 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource.DruidDataSource"></bean>
     */
    @Bean
    public DataSource dataSource() {
        //配置阿里巴巴数据源连接池
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource.setUrl("jdbc:mysql://localhost:3306/mayikt_springmvc?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT");
        druidDataSource.setUsername("root");
        druidDataSource.setPassword("20020806");
        return druidDataSource;
    }

    /**
     * 数据源事务相关的配置
     *
     * @Autowired DataSource dataSource 自动在 ioc 容器中去找
     */
//    @Bean
    public PlatformTransactionManager platformTransactionManager(@Autowired DataSource dataSource) {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        //设置数据源
        dataSourceTransactionManager.setDataSource(dataSource);
        return dataSourceTransactionManager;
    }
}

MybatisConfig

java 复制代码
package com.zhaoli.config;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;

import javax.sql.DataSource;

public class MybatisConfig {
   @Bean
   public SqlSessionFactoryBean sqlSessionFactory(@Autowired DataSource dataSource) {
       SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
       sqlSessionFactoryBean.setDataSource(dataSource);
       //实体类层包
       sqlSessionFactoryBean.setTypeAliasesPackage("com.com.zhaoli.entity");
       return sqlSessionFactoryBean;
   }
}

SpringConfig

java 复制代码
package com.zhaoli.config;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.transaction.annotation.EnableTransactionManagement;

//相当于创建了一个 SpringConfig.xml 即标记此类为配置类
@Configuration
//mybatis 扫包范围
@MapperScan("com.zhaoli.mapper")
//业务逻辑层的扫包范围
@ComponentScan("com.zhaoli.service")
//开启事务
@EnableTransactionManagement
//导入相关配置 相当于将这些类的配置拷贝进 SpringConfig.xml
@Import({JdbcConfig.class, MybatisConfig.class})
public class SpringConfig {
}

SpringMVCConfig

java 复制代码
package com.zhaoli.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

//开启 springmvc
@EnableWebMvc
//相当于创建了一个 SpringMVCConfig.xml 即标记此类为配置类
@Configuration
//控制层的扫包范围
@ComponentScan("com.zhaoli.controller")
public class SpringMVCConfig {
}

ServletConfig

java 复制代码
package com.zhaoli.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    /**
     * 加载 spring 相关配置
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{ServletConfig.class};
    }

    /**
     * 加载 springMVC 相关配置
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMVCConfig.class};
    }

    /**
     * 拦截所有的请求
     */
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

4.3 接口响应状态码

统一规范返回数据的格式,此处以json格式为例。返回数据应包含:返回状态码、返回状态信息、具体数据。

格式规范如下:

json 复制代码
{
    "code":"200",
    "msg":"ok",
    "data": {
        //json格式的具体数据
    }
}

查询到数据

json 复制代码
{
    "code":"200",
    "msg":"ok",
    "data": {
        "userName":"mayikt",
        "age":22
    }
}

前端 ajax技术

json 复制代码
if(code==200){
	"data": {
	"userName":"mayikt",
	"age":22
	}
}

Api Code状态码
1** 服务器收到请求,需要请求者继续执行操作
2** 操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误

如何封装接口响应状态码

java 复制代码
package com.zhaoli.controller;

import java.util.HashMap;

public class BaseController {
    /**
     * @param code code为200处理成功 为500 处理失败
     * @param msg  响应错误内容
     * @param data 响应的数据
     * @return
     */
    public HashMap<String, Object> setResult(Integer code, String msg, Object data) {
        HashMap<String, Object> result = new HashMap<String, Object>();
        result.put("code", code);
        result.put("msg", msg);
        result.put("data", data);
        return result;
    }

    /**
     * 提供处理请求响应成功的情况下(查询)
     */
    public HashMap<String, Object> setResultOk(Object data) {
        return setResult(200, "ok", data);
    }
    /**
     * 提供处理请求响应成功的情况下(删除、修改、插入)
     */
    public HashMap<String, Object> setResultSuccess(String msg) {
        return setResult(200, msg, null);
    }
    /**
     * 提供处理请求响应失败的情况下
     */
    public HashMap<String, Object> setResultError(String msg) {
        return setResult(500, msg, null);
    }
}
java 复制代码
package com.zhaoli.controller;

import com.zhaoli.entity.UserEntity;
import com.zhaoli.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;

/**
 * 标记该类是为 SpringMVC控制类
 * 在该类中定义的接口都是返回 json 数据
 */
@RestController
@RequestMapping("/user02")
public class UserController02 extends BaseController{
    @Autowired
    private UserService userService;

    /**
     * 根据id查询数据
     */
    @GetMapping("/getById/{id}")
    public HashMap<String, Object> getById(@PathVariable("id") Integer id) {
        if(id==null){
            return setResultError("id is null");
        }
        UserEntity user = userService.getById(id);
        if (user==null){
            return setResultError("根据此id:"+id+"没有查询到数据");
        }
        return setResultOk(user);
    }

    /**
     * 修改数据
     */
    @PutMapping("/update")
    public HashMap<String, Object> update(@RequestBody UserEntity userEntity) {
        return userService.update(userEntity)>0?setResultSuccess("修改成功"):setResultError("修改失败");
    }

    /**
     * 根据 id 删除数据
     */
    @DeleteMapping("/deleteById/{id}")
    public HashMap<String, Object> deleteById(@PathVariable("id") Integer id) {
        if(id==null){
            return setResultError("id is null");
        }
        return userService.deleteById(id)>0?setResultSuccess("删除成功"):setResultError("删除失败");
    }

    /**
     * 新增数据
     */
    @PostMapping("/insertUser")
    public HashMap<String, Object> insertUser(@RequestBody UserEntity userEntity) {
        return userService.insertUser(userEntity)>0?setResultSuccess("新增成功"):setResultError("新增失败");
    }
}

4.4 整合全局捕获异常

当系统发生错误时,统一将系统错误日志 返回输出

java 复制代码
package com.mayikt.controller;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

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

@ControllerAdvice
public class GlobalExceptionHandler extends BaseController {
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public Map<String, Object> handleException(HttpServletRequest h, Exception e) {
        System.out.println("自定义异常:" + e);
        return setResultError("系统发生了错误!");
    }
}
相关推荐
懒洋洋大魔王1 分钟前
RocketMQ的使⽤
java·rocketmq·java-rocketmq
武子康6 分钟前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
qq_174482857529 分钟前
springboot基于微信小程序的旧衣回收系统的设计与实现
spring boot·后端·微信小程序
转世成为计算机大神38 分钟前
易考八股文之Java中的设计模式?
java·开发语言·设计模式
qq_327342731 小时前
Java实现离线身份证号码OCR识别
java·开发语言
锅包肉的九珍1 小时前
Scala的Array数组
开发语言·后端·scala
心仪悦悦1 小时前
Scala的Array(2)
开发语言·后端·scala
2401_882727572 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
心仪悦悦2 小时前
Scala中的集合复习(1)
开发语言·后端·scala
阿龟在奔跑2 小时前
引用类型的局部变量线程安全问题分析——以多线程对方法局部变量List类型对象实例的add、remove操作为例
java·jvm·安全·list