Day51

JSR-303

简介

JSR全称为 Java Specification Requests,表示 Java 规范提案。JSR-303是 Java 为 Java Bean 数据合法性校验提供的标准框架,它定义了一套可标注在成员变量,属性方法上的校验注解。Hibernate Validatior提供了这套标准的实现。

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.1.Final</version>
<!-- 最新7.0.1.Final -->
</dependency>

校验注解

注解解释注解解释
@Null必须为null@NotNull不能为null
@AssertTrue必须为true@AssertFalse必须为false
@Min必须为数字,其值大于或等于指定的最小值@Max必须为数字,其值小于或等于指定的最大值
@DecimalMin必须为数字,其值大于或等于指定的最小值@DecimalMax必须为数字,其值小于或等于指定的最大值
@Size集合的长度@Digits必须为数字,其值必须再可接受的范围内
@Past必须是过去的日期@Future必须是将来的日期
@Pattern必须符合正则表达式@Email必须是邮箱格式
@Length(min=,max=)字符串的大小必须在指定的范围内@NotEmpty不能为null,长度大于0
@Range(min=,max=,message=)元素必须在合适的范围内@NotBlank不能为null,字符串长度大于0(限字符串)

mvc配置

pom.xml:

依赖:

spring-context-support, spring-mvc, fastjson

 <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>5.3.10</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.10</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>2.0.42</version>
    </dependency>
     <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>6.0.1.Final</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

web.xml:

配置servlet:DispatcherServlet,其中配置参数:contextConfigLocation,value为自己的xml文件,除了参数外还要配置项目启动即创建:load-on-startup,为1。

配置filter:CharacterEncodingFilter,配置参数:encoding,:value为UTF-8,forceEncoding:value为true。

<servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

spring-mvc.xml:

配置视图解析器:InternalResourceViewResolver。

配置处理字符串的消息转换器:StringHttpMessageConverter。

配置fastjson转换器:FastJsonHttpMessageConverter。

配置启动注解支持。

配置扫描包。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/" p:suffix=".jsp"/>

    <!--处理字符串的消息转换器-->
    <bean id="httpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter"/>

    <bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>text/html;charset=UTF-8</value>
                <value>application/json;charset=UTF-8</value>
            </list>
        </property>
    </bean>
    <mvc:annotation-driven>
        <mvc:message-converters>
            <ref bean="httpMessageConverter"/>
            <ref bean="fastJsonHttpMessageConverter"/>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <context:component-scan base-package="com.qf.controller"/>

</beans>

使用:

package com.qf.controller;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.NotNull;

public class UserController {
    @NotNull(message = "账号不能为空")
    @Length(min = 8, max = 15, message = "账号长度必须为8~15位")
    private String username;

    @NotNull(message = "密码不能为空")
    @Length(min = 8, max = 20, message = "密码长度必须为8~20位")
    private String password;

    @Range(min = 0, max = 120, message = "年龄只能在0~120岁之间")
    private int age;

    public String getUsername() {
        return username;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getAge() {
        return age;
    }

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

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

import javax.validation.Valid;

@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/add")
    @ResponseBody
    public Object saveUser(@Valid User user, BindingResult result){
        if(result.hasErrors()) return result.getAllErrors();
        return 1;
    }
}


Spring MVC中DispatcherServlet与核心组件底层

DispatcherServlet找到配置类,通过配置类信息拿到包信息,扫描包(扫描包的目的是找到配置类和controller类,并创建对象保存起来)。

扫描包的思路为:利用当前线程获取上下文的类加载器,将包名变成文件的URL地址,再从URL地址中获取文件的路径。对于路径中的每一个文件进行查找,找到.class文件后创建对象并将对象保存起来。

创建对象和保存的思路为:查看类是否是配置类,即检查类上是否有configuration注解,如果有则创建配置类的实例,获取配置类中定义的公开方法,对于每个方法获取方法上的bean注解,获取bean的名字,然后通过method.invoke(配置类实例)无参方法执行得到bean对象,并将bean对象存储在IOC容器中。

查看类是否是处理器类,即检查类上是否有controller注解,如果有则获取注解的值,即bean名字,如果为空那么就使用类名作为bean的名字,创建bean对象存储到IOC容器中。

IOC容器:拥有一个静态的hashmap属性,映射的键值分别为bean对象的名字和bean对象。

扫描完包后,从IOC容器中拿到所有的bean对象,对bean对象进行判断,如果bean对象属于处理器映射器类,则用自己的处理器映射器容器属性添加此bean对象;如果是处理器适配器类则用自己的处理器适配器容器属性添加此bean对象;如果是视图解析器类,则将自己的视图解析器属性赋值为此bean对象。

处理器映射器类都实现HandlerMapping接口,此接口只有一个getHandler方法用于获得一个处理器链,而处理器链有一个处理器属性。相当于就是返回一个处理器。

HandlerMapping接口下有若干处理器映射器实现类,如(这里举例说明两个处理器映射器类)

BeanNameUrlHandlerMapping,用bean的名字与url进行匹配,其重写的getHandler方法的思路就是从请求地址中拼接出url,然后将此url作为bean对象名去Ioc容器中获取bean对象并返回。

DefautAnnotationHandlerMapping,根据注解来获取对应的bean对象,思路为先获取所有的Ioc容器中的bean对象,利用stream流筛选含有Controller注解的控制器类,先通过RequestMapping注解获得父级url,即类上的url,然后获取控制器类中的所有公开方法,判断方法属于什么请求方式,即判断方法的注解为GetMapping、PostMapping、PutMapping、DeleteMapping中的哪一个,并获取对应注解内容中的子级url,拼接成url。然后将请求中的url和注解拼接的url进行匹配,注解中的url可能有{},因此匹配逻辑如果有花括号则不管,其余部分都必须一样。如果匹配成功并且请求方式和方法的请求方式一致则返回方法级别的处理器对象,即返回控制器对象、方法、url。

方法级别的处理器对象构建:一个表示方法级别的处理器类,只针对使用Controller或者RestController注解标识的控制器,有三个属性,分别为控制器对象、方法对象、返回值对象。

处理器适配器类都实现了HandlerAdapter接口,这个接口拥有两个方法,一个是表示当前处理器适配的处理器类型,返回布尔值,另外一个方法是返回ModelAndView类型的handle方法。ModelAndView类拥有视图名和map两个属性。只有当第一个方法满足之后才会执行handle方法。

HandlerAdapter接口下有若干处理器适配器类,如(列举两个处理器适配器类):

ControllerHandlerAdapter,这个适配器只支持实现Controller接口定义的控制器,Controller接口中只有一个handle方法,用户的controller类可以实现这个接口方法,而ControllerHandlerAdapter适配器就是首先判断当前处理器是否是Controller接口的实例,如果是则调用接口的方法,即调用用户写的方法。

HandlerMethodAdapter,这个适配器支持方法级别的处理器,首先判断处理器是否是HandlerMethod类的实例,即是否是方法级别的处理器,如果是则获取方法对象,获取参数列表并转换为参数数组,然后用method.invoke()调用方法,判断返回值类型,如果方法有ResponseBody注解则将返回值作为对象添加到modelandview对象中,如果没有则表明返回的是视图名,则作为视图名添加到modelandview对象中。

其中将参数列表转换为参数数组需要对于参数列表进行遍历,先获取参数的类型,然后根据不同情况分别进行对应的参数获取,具体为先判断参数的注解类型:

如果是RequestParam注解类,则从请求中获取给定参数名(注解内容表示参数名)的参数值并进行相应的类型解析转换。

如果是RequestBody注解,则表明参数为JSON格式,需要先获取请求体内容的字符流进行写入,然后转换成参数类型的对象。

如果是PathVariable注解,则表明是从路径中获得参数,需要拼接出url,然后寻找花括号{}里面的值,拿到后进行相应的解析转换。

如果是RequestHeader注解,则直接从请求头中获取参数值,并解析转换。

如果是CookieValue注解,则从cookie中获取参数值并解析转换。

然后判断参数类型是否是特殊类型,如请求类型、响应类型、session类型,如果是这三种类型则直接获取。

如果是其他类型则利用请求的getParameterMap()方法获取所有的参数,然后遍历判断类型是字符串还是字符串数组,利用JSON格式(JSON本身是一个map)获取并封装为对象返回。

视图解析器类实现ViewResolver接口,该接口有两个方法,getPrefix和getSuffix,这里以InternalResourceViewResolver实现类为例:

InternalResourceViewResolver类有两个属性,就是prefix和suffix,重写的方法就是两个属性的get方法,此外还有set方法。

DispatcherServlet的init方法到此结束,总结就是通过扫描包创建了处理器映射器的list,处理器适配器的list以及设置了视图解析器。之后要重写service方法,首先根据用户的请求地址和请求方式拿到处理器链,如果为空就会向前端发送一个404,如果不为空就说明有处理器可以处理,但是不能确定处理器的类型,所以需要处理器适配器进行适配,在处理器适配器中实现方法的调用,最后对返回值进行处理,如果返回的是数据则利用字符流进行输出,如果是视图则根据视图名和前后缀找到视图文件,用流读取文件的内容进行渲染。

其中,根据用户而定请求地址和请求方式拿到处理器链的方式为遍历处理器映射器,拿到其中的处理器链(处理器),如果不为空就返回,因此会找到第一个处理器链。

而处理器适配器进行适配的逻辑则为遍历处理器适配器,调用该处理器适配器的匹配类型的方法,如果匹配成功就返回,因此也是返回第一个处理器适配器。

整个DispatcherServlet的代码:

package com.qf.mvc;

import com.alibaba.fastjson.JSON;
import com.qf.anno.ComponentScan;
import com.qf.container.IocContainer;
import com.qf.data.ModelAndView;
import com.qf.handler.HandlerAdapter;
import com.qf.handler.HandlerExecutionChain;
import com.qf.mapping.HandlerMapping;
import com.qf.utils.PackageScanner;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class DispatcherServlet extends HttpServlet {

    //当前用户配置的处理器映射器
    private List<HandlerMapping> mappings = new ArrayList<>();
    private List<HandlerAdapter> adapters = new ArrayList<>();
    private ViewResolver viewResolver;

    @Override
    public void init(ServletConfig config) throws ServletException {
        //找到配置类
        String configClass = config.getInitParameter("appConfig");
        try {
            Class<?> clazz = Class.forName(configClass);//获取配置类的字节码信息
            ComponentScan scan = clazz.getAnnotation(ComponentScan.class);//获取含有扫描包信息的注解
            if(scan!=null){
                String[] packages = scan.value();//获取要扫描的包
                if(packages.length ==0){
                    //如果没有配置扫描的包,那么就扫描这个配置类所在的包
                    packages = new String[]{clazz.getPackage().getName()};
                }
                for (String pk : packages) {
                    PackageScanner.scan(pk);//循环扫描每一个配置的包
                }
            }
            Collection<Object> beans = IocContainer.getAllBeans();
            for (Object bean : beans) {
                if(bean instanceof HandlerMapping){
                    mappings.add((HandlerMapping) bean);
                } else if (bean instanceof HandlerAdapter) {
                    adapters.add((HandlerAdapter) bean);
                }else if(bean instanceof ViewResolver){
                    viewResolver = (ViewResolver) bean;
                }
            }


        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //当拿到请求的时候,我们需要根据请求的地址和请求的方式去找到匹配的处理器
        //如何来查找处理器呢?就需要根据用户的配置来决定
        try {
            HandlerExecutionChain handlerExecutionChain = getHandlerExecutionChain(req);
            if(handlerExecutionChain == null || handlerExecutionChain.getHandler() == null){
                //没有找到匹配的处理器执行链,那么此时就会向前端发送一个404
                resp.setContentType("text/html;charset=UTF-8");
                PrintWriter writer = resp.getWriter();
                writer.write("404  Not Found");
                writer.flush();
                writer.close();
                return;
            }
            //只要代码执行到这里,说明处理器也不为空,但是此时不能确定处理器的类型,因此需要处理器适配器
            HandlerAdapter adapter = getHandlerAdapter(handlerExecutionChain.getHandler());
            if(adapter == null){//如果说处理器适配器为空,说明存在配置问题
                return;
            }
            ModelAndView view = adapter.handle(req, resp, handlerExecutionChain.getHandler());
            if(view.hasData()){
                Object data = view.getData("data");
                resp.setContentType("application/json;charset=UTF-8");
                PrintWriter writer = resp.getWriter();
                writer.write(JSON.toJSONString(data));
                writer.flush();
                writer.close();
            } else {
                String viewName = view.getViewName();
                String location = viewResolver.getPrefix() + viewName + viewResolver.getSuffix();
                //根据位置用流读取文件的内容
                InputStream in = DispatcherServlet.class.getResourceAsStream(location);
                InputStreamReader isr = new InputStreamReader(in);
                BufferedReader reader = new BufferedReader(isr);
                PrintWriter writer = resp.getWriter();
                String line;
                while ((line = reader.readLine()) != null){
                    writer.write(line);
                }
                writer.flush();
                writer.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private HandlerExecutionChain getHandlerExecutionChain(HttpServletRequest req) throws Exception {
        for (HandlerMapping mapping : mappings) {
            HandlerExecutionChain handlerExecutionChain = mapping.getHandler(req);
            if(handlerExecutionChain != null){
                return handlerExecutionChain;
            }
        }
        return null;
    }

    private HandlerAdapter getHandlerAdapter(Object handler){
        for (HandlerAdapter adapter : adapters) {
            if(adapter.supports(handler)) return adapter;
        }
        return null;
    }
}

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

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

相关文章

DEPTHAI 2.27.0 发布!

小伙伴们大家好&#xff0c;我们发布了DepthAI 2.27.0版本&#xff0c;本次对DepthAI库有了一些小更新&#xff0c;以下是更新内容。 功能 设置DEPTHAI_ENABLE_FEEDBACK_CRASHDUMP时自动故障转储收集&#xff1b; 漏洞修补 修复深度超出ImageAlign节点时生成PointCloud的问…

安卓手机软件自动运行插件的开发流程及代码科普!

随着智能手机的普及和移动互联网的快速发展&#xff0c;安卓手机软件的需求日益旺盛&#xff0c;为了提高软件的功能性和扩展性&#xff0c;许多开发者选择通过插件的方式为软件添加新功能。 一、安卓手机软件自动运行插件的开发流程 1、明确需求与目标 在开发安卓手机自动运…

STM32——GPIO(点亮LED)

一、GPIO是什么&#xff1f; 1、GPI/O(general porpose intput output):通用输入输出端口的简称&#xff0c;通俗地说&#xff0c;就是我们所学的51单片机的IO口&#xff0c;即P0_0等。但要注意&#xff1a;并非所有的引脚都是GPIO 输出模式下可控制端口输出高低电平&#xf…

echarts-wordcloud:打造个性化词云库

前言 在当今信息爆炸的时代&#xff0c;如何从海量的文本数据中提取有用的信息成为了一项重要的任务。词云作为一种直观、易于理解的数据可视化方式&#xff0c;被广泛应用于文本分析和可视化领域。本文将介绍一种基于 echarts-wordcloud 实现的词云库&#xff0c;通过其丰富的…

uniapp + vue3 + Script Setup 写法变动 (持续更新)

一、uniapp 应用生命周期&#xff1a; https://uniapp.dcloud.net.cn/tutorial/vue3-composition-api.html 注意&#xff1a; 应用生命周期仅可在App.vue中监听&#xff0c;在其它页面监听无效。 二 、uniapp页面生命周期&#xff1a; https://uniapp.dcloud.net.cn/tutori…

【Rust入门教程】安装Rust

文章目录 前言Rust简介Rust的安装更新与卸载rust更新卸载 总结 前言 在当今的编程世界中&#xff0c;Rust语言以其独特的安全性和高效性吸引了大量开发者的关注。Rust是一种系统编程语言&#xff0c;专注于速度、内存安全和并行性。它具有现代化的特性&#xff0c;同时提供了低…

准化 | 水系统碳中和标准体系初见成效

2024年5月31日&#xff0c;中华环保联合会发布《团体标准公告 2024年第10号&#xff08;总第78号&#xff09;》&#xff0c;批准发布了由中华环保联合会提出并归口的《废水处理温室气体监测技术规程》(T/ACEF 142-2024)、《工业水系统碳排放核算方法与报告指南》(T/ACEF143-20…

解决ps暂存盘已满的问题

点击编辑->首选项->暂存盘 ps默认暂存盘使用的是c盘&#xff0c;我们改成d盘即可 然后重启ps

羊大师:自然力量,守护头皮健康

在繁忙的生活节奏中&#xff0c;我们往往忽略了与大自然最亲密的接触&#xff0c;也忘记了用自然的力量来呵护我们的每一寸肌肤&#xff0c;尤其是那细腻而脆弱的头皮。头皮&#xff0c;作为头发的根基&#xff0c;其健康直接决定了秀发的光泽与密度。 想象一下&#xff0c;清晨…

编译Open Cascade(OCC)并使用C#进行开发

说明&#xff1a; VS版本&#xff1a;Visual Studio Community 2022系统&#xff1a;Windows 11 专业版23H2Open CASCADE&#xff1a;v7.7.0&#xff08;链接&#xff1a;https://pan.baidu.com/s/1-o1s4z3cjpYf5XkwhSDspQ?pwdp9i5提取码&#xff1a;p9i5&#xff09; 下载和…

Android选择题界面的设计——线性布局实操

目录 任务目标任务分析任务实施 任务目标 使用TextView、Button、CheckBox等实现一个选择题界面&#xff0c;界面如图1所示。 图1 选择题界面效果图 任务分析 上述界面可以分解为上下两部分&#xff0c;上面部分可以使用横向的线性布局来完成&#xff0c;下面部分可以使用…

Python爬取国家医保平台公开数据

国家医保服务平台数据爬取python爬虫数据爬取医疗公开数据 定点医疗机构查询定点零售药店查询医保机构查询药品分类与代码查询 等等&#xff0c;数据都能爬 接口地址&#xff1a;/ebus/fuwu/api/nthl/api/CommQuery/queryFixedHospital 签名参数&#xff1a;signData {dat…

在手机上也能开发软件?而且只需要用几句话就可以自动生成一个应用!

随着人工智能技术的飞速发展&#xff0c;软件开发的门槛正在迅速降低。 曾几何时&#xff0c;开发一款软件需要精通编程语言和掌握复杂的开发工具&#xff0c;而如今&#xff0c;只需几句话的描述&#xff0c;便能在手机上轻松开发出功能齐全的软件。 这一切的背后&#xff0…

Debian linux忘记root密码如何重置

重启电脑, 到下图再按 e 键 在页面中可以看到有个ro的行&#xff0c;在ro行的尾部&#xff0c;添加 rw init/bin/bas 3. ctrl X 启动系统&#xff0c;最后会进入命令行模式 4. 重设root密码&#xff0c;输入命令 passwd root&#xff0c;按照提示输入新密码并确认 5. 重启系…

进程间通信————信号通信,共享内存,IPC对象之信号量集

进程间通信 》信号通信 应用&#xff1a;异步通信。 中断&#xff0c; 1~64&#xff1b;32应用编程。&#xff08;查表即可&#xff09; 如何响应&#xff1a;Term Default action is to terminate the process Ign Default action is to ignore the signal. wait …

mysql 忘记 root 密码的解决办法(针对不同 mysql 版本)

文章目录 1.前提说明1.1 cmd 窗口打开方式1.2 mysql 服务相关命令知识补充1.3 三个 mysql 版本说明1.4 运行时可能发生的报错问题&#x1f340; 跳过密码授权命令报错&#x1f340; 修改密码时报错&#x1f340; ERROR 2003 (HY000): Cant connect to MySQL server on localhos…

订单服务-提交订单业务立即购买业务

文章目录 1、提交订单 业务2、在 OrderController 创建 submitOrder 方法3、 在 OrderServiceImpl 中实现 submitOrder 方法4、根据id查询sku详情&#xff08;service-product"&#xff09;5、查询用户地址保存到订单项中&#xff08;service-user&#xff09;6、删除购物…

vue3开发过程中遇到的一些问题记录

问题&#xff1a; vue3在使用 defineProps、defineEmits、defineExpose 时不需要import&#xff0c;但是 eslint会报错error defineProps is not defined no-undef 解决方法&#xff1a; 安装 vue-eslint-parser 插件&#xff0c;在 .eslintrc.js 文件中添加配置 parser: vue-e…

论文学习_UVSCAN: Detecting Third-Party Component Usage Violations in IoT Firmware

论文名称发表时间发表期刊期刊等级研究单位 Understanding the Security Risks Introduced by Third-Party Components in IoT Firmware 2024年IEEE TDSCCCF A佐治亚理工学院 1. 引言 研究背景&#xff1a;物联网&#xff08;IoT&#xff09;已经无处不在&#xff0c;为我们…

DGMamba: Domain Generalization via Generalized State Space Model论文笔记

文章目录 DGMamba: Domain Generalization via Generalized State Space Model摘要动机DGMamba设计隐藏状态抑制(HSS)语义感知补丁细化(SPR)免先验扫描域上下文交换上下文patch识别 实验结果 DGMamba: Domain Generalization via Generalized State Space Model paper: https:/…