SpringMVC基础知识学习笔记

news2024/9/24 17:41:11

Universe Infinity Inc.

目录

        • 一、学习SpringMVC主要是学什么
          • 1、SpringMVC的基本原理
          • 2、SpringMVC学习串联
        • 二、快速体验SpringMVC的开发
          • 1、新建项目,转成web项目
          • 2、引入依赖
          • 3、编写Spring的配置类
          • 4、配置web启动类,替代web.xml
          • 5、编写Handler(Controller)处理请求
          • 6、配置Tomcat,访问[localhost:8080/index](http://localhost:8080/index)
        • 三、SpringMVC接收数据
          • 1、param接收数据
          • 2、json接收数据
          • 3、路径传参
          • 4、请求头、请求体、cookies等内容
        • 四、SpringMVC响应数据
          • 1、返回json数据
          • 2、返回页面视图
          • 3、转发和重定向
          • 4、静态资源访问
        • 五、异常处理和拦截器
          • 1、异常处理配置
          • 2、SpringMVC拦截器

一、学习SpringMVC主要是学什么

在SpringMVC的学习中,我们首先要明确其核心内容是稳定的,而其他内容则需要在探索中逐渐掌握。对于那些不熟悉Spring的底层知识,你无需过于担心,可以先学会如何使用它,然后在你单独学习Spring的基础知识时再去深入理解其背后的原理。同样,如果你对Servlet的知识感到困惑,可能会让你对请求和响应的处理感到迷茫。此时,你不应停滞不前,去深入研究Servlet的知识,可以先学会如何使用SpringMVC,然后再去深入了解Servlet的相关知识。重要的是要明确,SpringMVC的知识点并不包含那些内容。我们在学习的过程中切忌偏离主题,不要因为关注一些细枝末节而忽略了真正重要的核心内容。

1、SpringMVC的基本原理

看懂下面这个图
在这里插入图片描述

2、SpringMVC学习串联

1、知道SpringMVC的基本原理。
DIspatcherServlet、HandlerMapping、HandlerAdapter、Handler、ViewResovler几个内容的含义及理解
DefaultServletHandler、HandlerInterceptor、ExceptionHandler等内容的理解
2、SpringMVC接入参数
param入参、json入参、路径传参、原生API获取、请求头和请求体获取
3、SpringMVC响应数据
返回json数据、返回页面视图、转发和重定向、静态资源的访问处理DefaultServletHandler
4、SpringMVC的HandlerInterceptor、ExceptionHandler配置

二、快速体验SpringMVC的开发

SpringMVC6、JDK17、Tomcat10+

1、新建项目,转成web项目

项目整体的架构
在这里插入图片描述

2、引入依赖
<dependencies>
    <!-- springIoc相关依赖  -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>6.1.2</version>
    </dependency>
    <!-- springMVC相关依赖  -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>6.1.2</version>
    </dependency>
    <!-- web相关依赖  -->
    <!--SpringMVC6中使用jakarta EEServlet,需要配置对应的依赖-->
    <dependency>
        <groupId>jakarta.platform</groupId>
        <artifactId>jakarta.jakartaee-web-api</artifactId>
        <version>10.0.0</version>
        <scope>provided</scope> <!--这里打个疑问,为什么要配置成provide呢?-->
    </dependency>
</dependencies>
3、编写Spring的配置类
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
 * 全注解开发模式,配置Spring容器的信息
 */
@Configuration
@ComponentScan("com.universe")
public class SpringConfig {
}
4、配置web启动类,替代web.xml
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
/**
 * 全注解开发模式,替代web.xml
 * 通过继承AbstractAnnotationConfigDispatcherServletInitializer实现容器的初始化
 */
public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    /**
     * 指定service / mapper层的配置类
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
        System.out.println("getRootConfigClasses");
        return new Class[0];
    }
    /**
     * 指定Spring的配置类
     * @return
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
        System.out.println("getServletConfigClasses");
        return new Class[]{SpringConfig.class}; //这里指定了Spring的配置类,将会在web启动时加载
    }
    /**
     * 设置dispatcherServlet的处理路径!
     * 一般情况下为 / 代表处理所有请求!
     */
    @Override
    protected String[] getServletMappings() {
        System.out.println("getServletMappings");
        return new String[]{"/"};
    }
}
5、编写Handler(Controller)处理请求
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class IndexController {
    @RequestMapping("/index")
    @ResponseBody
    public String index(){
        return "Welcome to UII!";
    }
}
6、配置Tomcat,访问localhost:8080/index

在这里插入图片描述

三、SpringMVC接收数据
1、param接收数据

param传参形式,使用==@RequestParam==注解

  • param传参是什么形式,在url后加?形式
  • 单值传参、多值传参、同名值传参、实体类接收param、Map接收param
  • 创建实体类
@Data
public class Product {
    String id;
    String name;
    String price;
}
  • param传参的示例
@Controller
@ResponseBody
@RequestMapping("product")
public class ProductController {
    /**
     * 1、使用param传参形式测试
     * 1)使用注解@RequestParam表示param传参
     * 2)当URL传递的参数名和方法形参名相同时,会自动接收
     * 3)可以使用required表示是否必须,并使用defaultValue设置默认值
     * 4)特殊情况
     * a、一名多值情况
     * b、实体类接收
  	 * c、Map接收
     */
    //http://localhost:8080/product/update1?name=mobile
    @RequestMapping("update1")
    public String updateProduct1(@RequestParam("name") String name) {
        System.out.println(name);
        return name;
    }

    //http://localhost:8080/product/update2?name=mobile&price=200
    @RequestMapping("update2")
    public String updateProduct2(String name, String price) { //这种情况因配置问题会报错,暂且忽略
        System.out.println("name=" + name + ",price=" + price);
        return name + " " + price;
    }

    //http://localhost:8080/product/update3?name=mobile&price=200
    //通过required指定参数是否为必须,默认true必须。使用defaultValue指定默认值
    @RequestMapping("update3")
    public String updateProduct3(@RequestParam(value = "name") String productName,
                                 @RequestParam(value = "price", required = false, defaultValue = "0") String productPrice) {
        System.out.println("name=" + productName + ",price=" + productPrice);
        return productName + " " + productPrice;
    }

    //http://localhost:8080/product/update4a?name=mobile&name=computer
    //多个相同传参情况下,直接使用list接收
    @RequestMapping("update4a")
    public String updateProduct4a(@RequestParam("name") List<String> list) {
        System.out.println(list.toString());
        return list.toString(); //[mobile, computer]
    }

    //http://localhost:8080/product/update4b?name=mobile&price=999
    //通过实体类接收param,实体类的成员变量和param传参名相同,mvc会自动封装
    @RequestMapping("update4b")
    public String updateProduct4b(Product product) {
        System.out.println(product.toString());
        return product.toString(); //Product(id=null, name=mobile, price=999)
    }
    //http://localhost:8080/product/update4c?name=mobile&price=999
    //通过Map接收param,自动封装为map
    @RequestMapping("/update4c")
    public String updateProduct4c(@RequestParam Map<String, Object> map){
        for (Map.Entry<String, Object> stringObjectEntry : map.entrySet()) {
            System.out.println(stringObjectEntry.getKey()+":"+stringObjectEntry.getValue());
        }
        return map.toString(); //{name=mobile, price=999}
    }
}
2、json接收数据

json传参形式,使用==@ResponseBody来接收数据,SpringMVC会自动封装json到实体类
json转实体类需要配置json转换器。使用
@EnablewebMvc添加json处理器,该注解同时也会添加HandlerMappingHandlerAdapter==处理器不用手工创建。

  • 知道如何配置json处理器,知道如何使用json传参
  • json传参封装到String
  • 简单json传参封装到实体类
  • 复杂json传参封装到实体类
  • json传参封装到Map中
  • 创建实体类
//用户
@Data
public class User {
    String name;
    int age;
}
//订单详情
@Data
public class OrderDetails {
    int id; //订单编号
    List<Product> productList; //订单的产品列表
    int date; //下单日期
}
  • JSON传参的示例
@Controller
@ResponseBody
@RequestMapping("user")
public class UserController {
    /**
     * 2、使用json传参
     * json传参需要先配置web的json转换器,先引入依赖
     *<dependency>
     *     <groupId>com.fasterxml.jackson.core</groupId>
     *     <artifactId>jackson-databind</artifactId>
     *     <version>2.15.0</version>
     * </dependency>
     * 在Spring配置类中加上注解@EnableWebMvc  //json数据处理,必须使用此注解,因为他会加入json处理器
     * 这里留一个问题:@EnableWebMvc的原理是什么呢?
     */

    /**
     * http://localhost:8080/user/data1
     * {"name": "tang","age":"22"}
     * 1) 输入的json直接转为String
     */
    @RequestMapping("data1")
    public String updateUser1(@RequestBody String json) {
        System.out.println(json);
        return json;
    }

    /**
     * http://localhost:8080/user/data2
     * {"name": "tang","age":"22"}
     * 2) 将简单参数直接封装到实体类
     */
    @RequestMapping("data2")
    public String updateUser2(@RequestBody User user) {
        System.out.println(user.toString());
        return user.toString(); //User(name=tang, age=22)
    }

    /**
     * http://localhost:8080/user/data3
     {"id":"001",
     "productList":[
     {"id":"1","name":"apple","price":"999"},
     {"id":"2","name":"hw","price":"1999"},
     {"id":"3","name":"mobile","price":"9999"}],
     "date":"20240116"}
     * 3) 将复杂的参数封装到实体类
     */
    @RequestMapping("data3")
    public String updateUser3(@RequestBody OrderDetails orderDetails) {
        System.out.println(orderDetails.toString());
        for (Product product : orderDetails.getProductList()) {
            System.out.println(product.toString());
        }
        return orderDetails.toString();
        //OrderDetails(id=1, productList=[Product(id=1, name=apple, price=999), Product(id=2, name=hw, price=1999), Product(id=3, name=mobile, price=9999)], date=20240116)
    }

    /**
     * http://localhost:8080/user/data4
     (1) {"name": "tang","age":"22"}
     (2) {"id":"001",
     "productList":[
     {"id":"1","name":"apple","price":"999"},
     {"id":"2","name":"hw","price":"1999"},
     {"id":"3","name":"mobile","price":"9999"}],
     "date":"20240116"}
     * 4)使用map接收json数据
     */
    @RequestMapping("data4")
    public String updateUser4(@RequestBody Map<String,Object> map){
        for (Map.Entry<String, Object> stringObjectEntry : map.entrySet()) {
            System.out.println(stringObjectEntry.getKey()+":"+stringObjectEntry.getValue());
        }
        return map.toString(); 
        //{name=tang, age=22}
        //{id=001, productList=[{id=1, name=apple, price=999}, {id=2, name=hw, price=1999}, {id=3, name=mobile, price=9999}], date=20240116}
    }
}
3、路径传参

路径传参的使用在后续的RestFul风格的开发中会经常用到
其主要的注解是==@PathVariable==

  • 知道路径传参的输入格式,后续怎么处理扥个
@Controller
@ResponseBody
@RequestMapping("order")
public class OrderDetailsController {
    /**
     * http://localhost:8080/order/1/20230116
     * 3、使用路径传参的形式
     * 路径传参主要在RestFul风格开发中用到
     * 使用@PathVariable注解表示
     * 简单的展示下
     */
    @RequestMapping("/{id}/{date}")
    public String selectOrder(@PathVariable("id") String id,@PathVariable("date") String date){
        System.out.println(id+" "+date);
        return id+"_"+date;
    }
}
4、请求头、请求体、cookies等内容

SpringMVC也支持原生的API的使用,直接在Handler中参数中传
请求头使用==@RequestHeader==
请求体使用==@RequestBody==,这一点可以看到,json接收数据仅仅是接收请求体数据的一部分
接收Cookies可以使用==@CookieValue==

  • 请求头数据也可以获取到
  • 请求体数据可以是任何内容,json只是其中的一部分
  • 想要使用原生Servlet的话,直接在handler参数中声明即可
  • cookies可以使用特定注解获取,当然也有其它方式
@Controller
@ResponseBody
@RequestMapping("native")
public class NativeController {
    /**
     * 4、请求头,请求体,cookies等内容
     * 使用原生的Servlet API获取数据
     */
    //获取请求头:http://localhost:8080/native/header1
    //(1)获取请求头中的单个内容,@RequestHeader("accept")获取的是accept
    @RequestMapping("header1")
    public String getHerder1(@RequestHeader("accept") String header){
        System.out.println(header);
        return header; //text/html,application/xhtml+x...
    }

    //http://localhost:8080/native/header2
    //(2)获取全部请求头内容
    @RequestMapping("header2")
    public String getHerder2(@RequestHeader Map<String, Object> headers){
        System.out.println(headers.toString());
        return headers.toString();
    }

    //http://localhost:8080/native/body
    //使用postman,请求体可以是任何内容
    //(3)获取请求体,对应的json传参情况只是获取请求体过程中的一个例外
    @RequestMapping("body")
    public String getBody(@RequestBody String body){
        System.out.println(body);
        return body;
    }
    //http://localhost:8080/native/setcookies
    //(4)获取cookies,当然在获取cookies的时候需要先存放cookies
    @RequestMapping("setcookies")
    public String setCookies(HttpServletRequest req, HttpServletResponse resp){
        Cookie cookies1 = new Cookie("cookies1", "Universe_Infinity_inc.");
        resp.addCookie(cookies1);
        return "Ok!";
    }
    //http://localhost:8080/native/cookies1
    @RequestMapping("cookies1")
    public String getCookies1(@CookieValue(value = "cookies1",required = false,defaultValue = "") String cookies){
        System.out.println(cookies);
        return cookies; //Universe_Infinity_inc.
    }
    //http://localhost:8080/native/cookies2
    @RequestMapping("cookies2")
    public String getCookies2(@CookieValue Map<String,Object> map){ //这个请求会失败!
        System.out.println(map.toString());
        return map.toString();
    }
}

在这里插入图片描述

四、SpringMVC响应数据

在前后端分离的开发模式下,响应数据仅仅需要返回字符串,这时使用==@ResponseBody==直接返回字符串
在非前后端分离的开发模式下,响应数据需要返回具体的视图,这时需要对视图进行一系列的配置

  • 返回JSON数据情况,配置好
  • 创建实体类
@Data
public class User {
    String name;
    String age;
}

@Controller
@RequestMapping("user")
public class UserController {
}
1、返回json数据

关键注解==@ResponseBody==

/**
 * http://localhost:8080/user/get
 * request:{"name":"tang","age":"22"}
 * 1、前后端分离的情况下,响应数据为json形式情况,使用@ResponseBody注解
 * 使用@EnableWebMvc注解,配置json处理器
 */
@PostMapping("/get")
@ResponseBody
public User getUser(@RequestBody User user){
    System.out.println(user.toString());
    return user;
}
2、返回页面视图
  • 编写页面视图

    文件路径:/webapp/WEB-INF/view/page.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <p>这是JSP生成的页面</p>
        ${msg}
    </body>
    </html>
    
    
  • 配置页面处理

    @EnableWebMvc
    @Configuration
    @ComponentScan("com.response")
    public class SpringConfig implements WebMvcConfigurer {
        //配置jsp对应的视图解析器
        @Override
        public void configureViewResolvers(ViewResolverRegistry registry) {
            //快速配置jsp模板语言对应的
            registry.jsp("/WEB-INF/view/", ".jsp");
        }
    }
    
  • 编写handler

    注意不要加==@ResponseBody注解,同样不能使用@RestController==注解

    /**
     *http://localhost:8080/user/page?name=tang&age=22
     * 2、非全后端分离的情况下,返回页面视图。注意不要加@ResponseBody注解!!
     * 在容器中添加好视图解析器
     *     public void configureViewResolvers(ViewResolverRegistry registry) {
     *         //快速配置jsp模板语言对应的
     *         registry.jsp("/WEB-INF/view/", ".jsp");
     *     }
     * 直接返回的page会自动拼装为"/WEB-INF/view/page.jsp",同时也会对model中的数据解析
     */
    @RequestMapping("page")
    public String getUserPage(User user,Model model){
        System.out.println(user.toString());
        model.addAttribute("msg",user.toString());
        return "page";
    }
    
  • 前台展示
    在这里插入图片描述

3、转发和重定向

什么是转发,什么是重定向呢?
转发和重定向在返回视图页面时使用。
转发直接在返回的字符串前加forward:
重定向直接在返回的字符串加redirect:

 /**
 * http://localhost:8080/user/forward?name=tang&age=22
 * 此请求返回的是:User(name=tang, age=22)
 * 3、使用forward进行转发,注意不要加@ResponseBody注解
 * 转发时服务器的操作,用户请求一次。全程只有一个HttpServletRequest对象,请求参数可以传递
 * 转发可以访问到WEB-INF下受保护的资源
 */
@RequestMapping("forward") //转发
public String forward() {
    return "forward:/user/page";
}
/**
 * http://localhost:8080/user/redirect?name=tang&age=22
 * 此请求返回的是:User(name=null, age=null)
 * 4、使用redirect进行重定向,注意不要加@ResponseBody注解
 * 重定向是服务端告诉客户端去请求其它路径的操作,客户端至少请求两次。会产生多个请求对象,参数不可以传递
 * 重定向可以访问项目外的资源
 *
 */
@RequestMapping("redirect") //重定向
public String redirect() {
    return "redirect:/user/page";
}
4、静态资源访问
  • 添加静态资源处理器

    @EnableWebMvc
    @Configuration
    @ComponentScan("com.response")
    public class SpringConfig implements WebMvcConfigurer {
        //http://localhost:8080/image/lyf.jpg
        //请求在最初的时候会通过SpringMVC的机制转给RequestMapping查找对应的Handler,然而查不到静态资源,会直接报错
        //开启静态资源处理 <mvc:default-servlet-handler/>,添加DefaultServletHandler再解析
        @Override
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
            configurer.enable();
        }
    }
    
  • 放个静态资源

    /webapp/image/lyf.jpg

    http://localhost:8080/image/lyf.jpg 直接访问就可以访问到了

五、异常处理和拦截器
1、异常处理配置
  • 异常处理内容
/**
 * SpringMVC异常处理机制的步骤:
 * 1、编写专门处理异常的类,标注注解@ControllerAdvice或@RestControllerAdvice。
 * 2、编写异常处理的方法,方法上标注@ExceptionHandler(异常.class)
 * 3、异常处理的方法中编写异常处理的逻辑等
 * 异常处理一般单独放在一个包内
 */
@RestControllerAdvice //这个是@ControllerAdvice和@ResponseBody的整合形式
public class ExceptionHandlerConfig {
    //在其中编写异常处理的类
    //使用@ExceptionHandler来注解处理异常的类
    @ExceptionHandler(Exception.class)
    public String allExcetpion(Exception e){
        System.out.println(e.getMessage());
        return "serious mistake!";
    }
    @ExceptionHandler(NullPointerException.class)
    public String nullPointerExcetpionHandler(NullPointerException e){
        System.out.println(e.getMessage());
        return "null error!";
    }
}
  • 测试异常处理是否正常
@RestController
@RequestMapping("exception")
public class ExceptionController {
    //http://localhost:8080/exception/exce1
    @RequestMapping("exce1")
    public String exception1() {
        int i = 1 / 0;
        return "exception1";
    }
    //http://localhost:8080/exception/exce2
    @RequestMapping("exce2")
    public String exception2() {
        User user = null;
        user.toString();
        return "exception2";
    }
}
  • 无异常处理的时候
    在这里插入图片描述

  • 有异常处理机制
    在这里插入图片描述

2、SpringMVC拦截器

SpringMVC拦截器是MVC容器内部的处理器。其主要是与过滤器对比。
1、如何编写SpringMVC拦截器,实现HandlerInterceptor接口
2、HandlerInterceptor接口的三个方法的生效位置
3、拦截器的作用范围。addPathPatterns(),excludePathPatterns()的使用

  • 编写拦截器
/**
 * SpringMVC的拦截器编写步骤:
 * 1、编写自定义的拦截类,实现HandlerInterceptor接口
 * 2、HandlerInterceptor接口中有三个方法,用于请求拦截
 * 3、直接实现三个方法即可
 * 4、将拦截器加到配置类中
 *     //配置拦截器
 *     @Override
 *     public void addInterceptors(InterceptorRegistry registry) {
 *         registry.addInterceptor(new MyInterceptor());
 *     }
 * 5、拦截器可以配置拦截的路径,针对性拦截
 */
public class MyInterceptor implements HandlerInterceptor {

    /**
     * preHandle在HandlerAdapter寻找Handler前执行
     * @param request 请求
     * @param response 响应
     * @param handler 方法
     * @return true放行 false拦截
     * @throws Exception 异常处理
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor.preHandle");
        System.out.println(handler.toString());
        return true;
    }

    /**
     * postHandler在Handler执行后执行,handler报错不执行
     * @param request 请求
     * @param response 响应
     * @param handler 方法
     * @param modelAndView 视图
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor.postHandle");
    }

    /**
     * afterCompletion在视图渲染(如果有)后执行
     * @param request 请求
     * @param response 响应
     * @param handler 方法
     * @param ex 异常
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor.afterCompletion");
    }
}
  • 注册拦截器
@EnableWebMvc
@Configuration
@ComponentScan("com.universe")
public class SpringConfig implements WebMvcConfigurer {
    //配置拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new RootInterceptor()).addPathPatterns("/rest/*"); //拦截特定的url
        registry.addInterceptor(new MyInterceptor());
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

助力焊接场景下自动化缺陷检测识别,基于YOLOv3模型开发构建工业焊接场景下缺陷检测识别分析系统

焊接是一个不陌生但是对于开发来说相对小众的场景&#xff0c;在我们前面的博文开发实践中也有一些相关的实践&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a; 《轻量级模型YOLOv5-Lite基于自己的数据集【焊接质量检测】从零构建模型超详细教程》 《基于DeepLabV3Pl…

令牌桶算法与Guava的实现RateLimiter源码分析

令牌桶算法与Guava的实现RateLimiter源码分析 令牌桶RateLimiter简介RateLimiter使用示例导入maven依赖编写测试代码 RateLimiter的实现源码解析SmoothRateLimiterSmoothBursty恒速获取令牌acquire(int)tryAcquire(int,long,TimeUnit) 存量桶系数小结 优缺点与漏桶的区别总结 令…

01-开始Rust之旅

1. 下载Rust 官方推荐使用 rustup 下载 Rust&#xff0c;这是一个管理 Rust 版本和相关工具的命令行工具。下载时需要连接互联网。 这边提供了离线安装版本。本人学习的机器环境为&#xff1a; ubuntu x86_64&#xff0c;因此选用第②个工具链&#xff1b; 1. rust-1.75.0-x86_…

CloudPanel RCE漏洞复现(CVE-2023-35885)

0x01 产品简介 CloudPanel 是一个基于 Web 的控制面板或管理界面,旨在简化云托管环境的管理。它提供了一个集中式平台,用于管理云基础架构的各个方面,包括虚拟机 (VM)、存储、网络和应用程序。 0x02 漏洞概述 由于2.3.1 之前的 CloudPanel 具有不安全的文件管理器 cook…

【JSON2WEB】01 WEB管理信息系统架构设计

WEB管理信息系统分三层设计&#xff0c;分别为DataBase数据库、REST2SQL后端、JSON2WEB前端&#xff0c;三层都可以单独部署。 1 DataBase数据库 数据库根据需要选型即可&#xff0c;不需要自己设计开发&#xff0c;一般管理信息系统都选关系数据库&#xff0c;比如Oracle、…

beego的模块篇 - I18n国际化

1. i18n 安装导入 安装该模块&#xff1a; go get github.com/beego/i18n 导入引用包&#xff1a; import ("github.com/beego/i18n" ) conf 目录下就有 locale_en-US.ini 和 locale_zh-CN.ini 两个本地化文件。 本地化文件的文件名和后缀是随意的&#xff0c;不…

C++_Lambda表达式的完整介绍

目录 1. 什么是Lambda表达式 1.1 四种表达式的含义 1.2 lambda表达式各个成员的解释 2. 捕获列表 3. 编译器如何看待Lambda表达式 参考文章 参考: C Lambda表达式的完整介绍 - 知乎 c在c11标准中引入了lambda表达式&#xff0c;一般用于定义匿名函数&#xff0c;使得代码…

超过GPT3.5?Mixtral 8*7B 模型结构分析

Datawhale干货 作者&#xff1a;宋志学&#xff0c;Datawhale成员 前言 2023年12月11日&#xff0c;Mistral AI团队发布了一款高质量的稀疏专家混合模型Mixtral 8x7B。 Mistral AI继续致力于向开发者社区提供最优秀的开放模型。在人工智能领域向前发展&#xff0c;需要采取超越…

关于SpringBoot项目整合Log4j2实现自定义日志打印失效原因

主要的原因是因为&#xff0c;SpringBoot的logback包的存在&#xff0c;会导致Spring Boot项目优先实现logback的日志设置&#xff0c;所以导致我们用Log4j2实现自定义日志失效。 先找l哪个包引用了logback包 进入之后查询logback 然后双击包 发现是spring-boot-starter-loggin…

UVa1318/LA2797 Monster Trap

题目链接 本题是2003年ICPC亚洲区域赛会津(日本)赛区的H题 题意 给出一些线段障碍&#xff0c;你的任务是判断怪物能否逃到无穷远处。如下图所示&#xff0c;左图无法逃出&#xff0c;右图的可以逃出。 输入包含多组数据。每组数据第一行为整数n&#xff08;1≤n≤100&#xf…

C++编写、生成、调用so库详解(一)

开发中经常会用到so库,大多是调用第三方的so库,偶尔也需要自己封装一个so库给别人调用,这边就记录一下开发so库的一个过程. 首先我们这边是在Android Studio中开发的,所以仅描述在Android环境下开发过程,当然也可以用其他工具开发. 目录 1.第一步新建项目,配置需要的工具 2…

插件分享 Chrome浏览器实现外语翻译自由

【有道灵动翻译】使用有道翻译大模型&#xff0c;沉浸式网页翻译的首选工具&#xff01; 实时对照翻译:让任何网页变成对照。输入框即时翻译:输入中文轻松变英文。 &#x1f525;功能亮点&#x1f525;&#xff1a; 实时对照翻译&#xff1a;使用有道翻译大模型&#xff0c;无…

了解Vue中日历插件Fullcalendar

实现效果如下图&#xff1a; 月视图 周视图 日视图 官方文档地址&#xff1a;Vue Component - Docs | FullCalendar 1、安装与FullCalendar相关的依赖项 npm install --save fullcalendar/vue fullcalendar/core fullcalendar/daygrid fullcalendar/timegrid fullcalend…

MySQL复合查询 内外连接

目录 前言&#xff1a; 多表查询&#xff1a; 显示部门号为10的部门名&#xff0c;员工名和工资 : 显示各个员工的姓名&#xff0c;工资&#xff0c;及工资级别: 自连接 显示员工FORD的上级领导的编号和姓名(mgr是员工领导的编号&#xff09; 子查询 单行子查询&#…

IPv6自动隧道---6to4中继

6to4中继 普通IPv6网络需要与6to4网络通过IPv4网络互通,这可以通过6to4中继路由器方式实现。所谓6to4中继,就是通过6to4隧道转发的IPv6报文的目的地址不是6to4地址,但转发的下一跳是6to4地址,该下一跳为路由器我们称之为6to4中继。隧道的IPv4目的地址依然从下一跳的6to4地…

电池容量常见测试方法分享 -纳米软件

电池容量是衡量电池性能的重要指标之一&#xff0c;它是指电池在一定条件下放出的电量&#xff0c;可以用于帮助评估电池的性能和寿命。那么如何快速测试电池容量呢? 一、用万用表测试 用万用表测试电池容量&#xff0c;需要将万用表调整到电容模式&#xff0c;然后连接电池到…

鸿蒙HarmonyOS实战-ArkTS语言(基本语法)

&#x1f680;一、ArkTS语言基本语法 &#x1f50e;1.简介 HarmonyOS的ArkTS语言是一种基于TypeScript开发的语言&#xff0c;它专为HarmonyOS系统开发而设计。ArkTS语言结合了JavaScript的灵活性和TypeScript的严谨性&#xff0c;使得开发者能够快速、高效地开发出高质量的Har…

mac PyCharm 上传文件到远程服务器+远程服务器下载到本地

1 部署配置 选择SFTP name&#xff1a;test6 输入ssh账号和密码。保存密码和30s心跳。 2 目录映射 Local path&#xff08;本地mac机器&#xff09;&#xff1a;/Users/clevercode/PycharmProjects/test6 Root path&#xff08;远程服务机器&#xff09;&#xff1a;/home/…

Redis持久化方案RDB和AOF

Redis两种持久化方案 RDB持久化AOF持久化 RDB持久化 RDB全称Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;&#xff0c;也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后&#xff0c;从磁盘读取快照文…

【stm32】hal库学习笔记-GPIO按键控制LED和蜂鸣器(超详细!)

【stm32】hal库学习笔记-GPIO按键控制LED和蜂鸣器 注&#xff1a;本学习笔记基于stm32f4系列 使用的开发板为正点原子stmf407ZGT6探索者开发板 GPIO引脚使用时&#xff0c;可输入或输出数字信号 例如: 检测按键输入信号&#xff08;Read_Pin&#xff09;输出信号&#xff08;W…