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

文章目录

  • 【技术详解】SpringMVC框架全面解析:从入门到精通(SpringMVC)
    • SpringMVC概述
    • 1. 三层架构与MVC架构区别
      • 1.1 三层架构
      • 1.2 MVC架构
      • 1.3前后端分离开发模式
    • 2. SpringMVC环境搭建
      • 2.1 注解启动方式
      • 2.2 xml启动方式
      • 2.3 SpringMVC PostMan工具使用
    • 3. SpringMVC 请求与响应
      • 3.1 springmvc 5种接受参数类型
      • 3.2 springmvc接受json数据
      • 3.3 springmvc响应json数据
      • 3.4使用HttpServletRequest 获取参数
      • 3.5 springmvc restful简单介绍
      • 3.6 springmvc 整合jsp技术(过时 了解该技术)
    • 4. spring+springmvc+mybatis整合
      • 4.1SSM环境的整合之提供增删改查
      • 4.2 SSM环境的整合之配置整合
      • 4.3 接口响应状态码
      • 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依赖

<!-- 整合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>

创建控制器层

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'}";
}
}

创建配置类

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分发到具体控制类的方法进行执行
     */
}

注册配置类

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插件运行

 <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 依赖

<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依赖

<!-- 整合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>

创建控制器层

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 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 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 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 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路径是不允许重复

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";
    }
}
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";
    }
}
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层方法的形参同名,那么可以直接通过参数名接收值即可

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:参数默认值
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.对象参数
请求参数名与形参对象属性名相同,定义对象类型形参即可接收参数

package com.zhaoli.entity;

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

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

package com.zhaoli.entity;

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

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

在这里插入图片描述

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

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

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

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

/**
 * 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数据

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依赖

<!-- @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.以实体类方式接收
实体类

public class UserEntity {
    String userName;
    Integer age;
UserInfo userInfo;
}
public class UserInfo {
String addres;//地址
}
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类型保持一致否则报错

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

在这里插入图片描述

@RequestMapping("/demo09")
@ResponseBody
public String demo09(@RequestBody Map<String,Object> paramMap){
    return paramMap.toString();
}

在这里插入图片描述

3.以List接收

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

在这里插入图片描述
在这里插入图片描述

@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数据
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();
@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

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技术(过时 了解该技术)

核心配置

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

定义控制器

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页面

<%--
  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环境的整合之提供增删改查

整合数据库表结构

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依赖

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

实体类层

package com.zhaoli.entity;

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

数据库访问层

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);
}

业务逻辑层

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);
    }
}

控制层

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

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

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

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

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

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格式为例。返回数据应包含:返回状态码、返回状态信息、具体数据。
格式规范如下:

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

查询到数据

{
    "code":"200",
    "msg":"ok",
    "data": {
        "userName":"mayikt",
        "age":22
    }
}

前端 ajax技术

if(code==200){
	"data": {
	"userName":"mayikt",
	"age":22
	}
}

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

如何封装接口响应状态码

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);
    }
}
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 整合全局捕获异常

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

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("系统发生了错误!");
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/889617.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL 实验1:Windows 环境下 MySQL5.5 安装与配置

MySQL 实验1&#xff1a;Windows 环境下 MySQL5.5 安装与配置 目录 MySQL 实验1&#xff1a;Windows 环境下 MySQL5.5 安装与配置一、MySQL 软件的下载二、安装 MySQL三、配置 MySQL1、配置环境变量2、安装并启动 MySQL 服务3、设置 MySQL 字符集4、为 root 用户设置登录密码 一…

【华为欧拉】国产OpenEuler服务器系统安装以及图形界面

openEuler下载 | openEuler ISO镜像 | openEuler社区官网 下载安装iso 本次选择4G的社区版本 安装&#xff0c;复制到光盘&#xff0c;光盘引导安装。虚拟机安装&#xff0c;准备好iso文件引用&#xff0c;指定好安装源&#xff0c;安装界面和centOS基本一样。选择最小安装就…

代码随想录算法训练营第三十天|491. 非递减子序列,46. 全排列,47. 全排列 II,332. 重新安排行程,51. N 皇后,37. 解数独

491. 非递减子序列&#xff0c;46. 全排列&#xff0c;47. 全排列 II&#xff0c;332. 重新安排行程&#xff0c;51. N 皇后&#xff0c;37. 解数独 491. 非递减子序列46. 全排列47. 全排列 II332. 重新安排行程51. N 皇后37. 解数独 491. 非递减子序列 给你一个整数数组 nums…

友思特方案 | FantoVision边缘计算:嵌入式视觉系统如何实现“更快 更高 更强”?

导读 便于集成的嵌入式视觉系统一直以来面临着带宽、内存、算力三个方面的挑战。友思特 FantoVision 边缘计算设备拥有更快的处理速度和更高的带宽选择&#xff0c;其开放式架构有效突破了上述三重阻碍。 嵌入式视觉 嵌入式视觉是传统机器视觉衍生出来的子集&#xff0c;嵌入…

k8s 中存储之 PV 持久卷 与 PVC 持久卷申请

目录 1 PV 与 PVC 介绍 1.1 PersistentVolume&#xff08;持久卷&#xff0c;简称PV&#xff09; 1.2 PersistentVolumeClaim&#xff08;持久卷声明&#xff0c;简称PVC&#xff09; 1.3 使用了PV和PVC之后&#xff0c;工作可以得到进一步的细分&#xff1a; 2 持久卷实验配置…

UE5运行时动态加载场景角色动画任意搭配-相机及运镜(二)

通过《MMD模型及动作一键完美导入UE5》系列文章,我们可以把外部场景、角色、动画资产导入UE5,接下来我们将实现运行时动态加载这些资产,并任意组合搭配。 1、运行时播放相机动画 1、创建1个BlueprintActor,通过这个蓝图动态创建1个LevelSequence,并Play 2、将这个Bluep…

Verdin AM62使用CODESYS

By Toradex 胡珊逢 简介 CODESYS 是基于 IEC 61131-3 的 PLC 开发工具&#xff0c;在工业控制、交通等领域中有着广泛的应用。文章将介绍如何在 Toradex 采用 TI AM62 SoC 的 Arm 计算机模块 Verdin AM62 使用评估版本的 CODESYS。 硬件介绍 Verdin AM62使用 TI AM623/AM625…

打卡第四天 P1081 [NOIP2012 提高组] 开车旅行

今天是我打卡第四天&#xff0c;做个省选/NOI−题吧(#^.^#) 原题链接&#xff1a;[NOIP2012 提高组] 开车旅行 - 洛谷 题目描述 输入格式 输出格式 输入输出样例 输入 #1 4 2 3 1 4 3 4 1 3 2 3 3 3 4 3 输出 #1 1 1 1 2 0 0 0 0 0 输入 #2 10 4 5 6 1 …

✨机器学习笔记(七)—— 交叉验证、偏差和方差、学习曲线、数据增强、迁移学习、精确率和召回率

机器学习笔记&#xff08;七&#xff09; 1️⃣评估模型&#x1f397;️使用测试集评估模型&#x1f397;️交叉验证集&#xff08;cross validation&#xff09; 2️⃣偏差和方差&#xff08;Bias / Variance&#xff09;3️⃣学习曲线&#xff08;Learning curves&#xff09…

获取时隔半个钟的三天

摘要&#xff1a; 今天遇到需求是配送时间&#xff0c;时隔半个钟的排线&#xff01;所以需要拼接时间&#xff01;例如2024-10-08 14&#xff1a;30&#xff0c;2024-10-08 15&#xff1a;00&#xff0c;2024-10-08 15&#xff1a;30 <el-form-item label"配送时间&a…

【HarmonyOS】HMRouter使用详解(四)路由拦截

路由拦截器 可以对指定或全局路由跳转时添加拦截器&#xff0c;作用是可以实现在页面切换前做判断是否有进入当前页面的权限。这篇文章将实现登录的全局路由拦截样式。 新建拦截器类 通过继承IHMInterceptor接口实现生命周期接口的方法重写。 通过添加HMInterceptor装饰器&…

2022年黄河流域旅游资源空间分布数据(shp)

数据介绍 黄河是中华民族的母亲河。黄河流域旅游资源丰富且极具特色。黄河流域旅游资源空间分布数据是黄河流域旅游资源开发与决策的基础。本数据集以县&#xff08;区&#xff09;域行政边界为单元、以国家旅游资源分类标准为依据&#xff0c;收集整理了黄河流域各县&#xf…

ART 光学跟踪系统:通过 VR HMD 解锁完全沉浸式 VR 体验

在虚拟现实体验中&#xff0c;完全沉浸式虚拟现实体验应该既准确又舒适。当与现实世界的物体融合时&#xff0c;虚拟现实的表现必须与现实精确匹配。这意味着所使用的运动跟踪系统必须为整套项目提供可靠且可重复的高精度运动数据&#xff0c;以及体感无法察觉到的超低延迟。AR…

HECTOR:一种新型多模态深度学习模型用于预测子宫内膜癌复发风险|顶刊精析·24-10-12

小罗碎碎念 这篇文章是关于一项名为HECTOR&#xff08;histopathology-based endometrial cancer tailored outcome risk&#xff09;的研究&#xff0c;它是一个基于多模态深度学习的预测模型&#xff0c;用于预测子宫内膜癌&#xff08;EC&#xff09;的复发风险。 作者角色作…

高级软件测试工程师:我的2024面试经验!干货满满!

最近行业里有个苦涩的笑话&#xff1a;公司扛过了之前的三年&#xff0c;没扛过摘下最近的一年&#xff0c;真是让人想笑又笑不出来。年前听说政策的变化&#xff0c;大家都满怀希望觉得年后行情一片大好&#xff0c;工作岗位激增&#xff0c;至少能有更多的机会拥抱未来。然而…

mac电脑如何删除应用程序?怎么删除苹果电脑里的软件

在使用Mac电脑的过程中&#xff0c;随着时间的推移&#xff0c;我们可能会安装大量的应用程序。然而&#xff0c;这些应用程序中有很多可能只是临时使用&#xff0c;或者已经不再需要了。这些无用的应用程序不仅占据了宝贵的硬盘空间&#xff0c;还可能拖慢Mac系统的运行速度。…

Qt 自绘开关按钮以及设计器中的提升为用法

文章目录 自绘按钮实现概要效果图代码 提升为用法介绍步骤 总结 自绘按钮实现 概要 当我们需要一个开关样式的QPushbutton&#xff0c;没有图片的话&#xff0c;我们可以采用自绘的形式实现。且使用QtDesinger中提升为Promote to的功能加入界面中&#xff0c;而不是使用代码的…

godot帧同步-关于“显示与逻辑分离”

很多教程说帧同步的关键是“显示与逻辑分离”&#xff0c;但是又没有具体讲解&#xff0c;我起初也没有搞懂这句话的意思&#xff0c;就直接上手开发帧同步了。在开发的过程中&#xff0c;一下子就悟了&#xff0c;所以分享一下。 显示与逻辑未分离&#xff08;单机&#xff0…

《系统架构设计师教程(第2版)》第18章-安全架构设计理论与实践-02-安全模型

文章目录 1. 安全模型概述1.1 信息安全的目标1.2 安全模型 2. 状态机模型2.1 概念2.2 状态机模型工作步骤 3. Bell-LaPadula模型3.1 概念3.2 模型安全规则3.3 示例 3. Biba模型3.1 概念3.2 模型安全规则3.3 示例 4. Clark-Wilson模型&#xff08;CWM&#xff09;4.1 概述4.2 模…

低代码赋能汽车制造产业链场景系列

当前汽车行业数字化智能化转型浪潮下&#xff0c;整车及其上下游产业链的协同创新正变得至关重要。头部车企与上下游供应链企业正逐步解决在生产管理、业务互通、系统集成等方面的痛点与挑战。电动化、智能化、网联化作为汽车产业的三大趋势&#xff0c;正共同推动未来汽车产业…