若依的使用(token补充、HTTPS(网络安全)、分页前后端配置)

news2024/11/16 9:33:35

本文章转载于公众号:王清江唷,仅用于学习和讨论,如有侵权请联系

QQ交流群:298405437

本人QQ:4206359  具体视频地址:8 跑后端_哔哩哔哩_bilibili

1、HTTP?

曾经我们在讲JWT的时候,当时JWT需要配合https使用呢?

因为http自身是明码传输,我们通过网卡抓包可以轻而易举得到token。

我们的token相当于在网络上明码传输,很容易被人拦截查看!

下面演示一下拦截token!

效果图:

图片

2、不安全怎么办呐?

既然不安全,那咋办呢?上https!

视频演示腾讯云上https。

3、HTTPs实现

现在我们利用腾讯云实现HTTPs。

首先得有一个域名吧?怎么买我就不多说了,直接在腾讯云搜索域名,选择自己喜欢的购买。

然后呢,还需要购买SSL证书,一般来说,买域名会送一个SSL证书,反正我的是送的。如果没送可以点击申请免费证书,证书界面如下:

https://console.cloud.tencent.com/ssl

图片

有了证书之后,我们需要先下载证书,下载nginx证书。请直接看视频。

腾讯云官方学习视频:

https://cloud.tencent.com/document/product/400/35244

把打包下载的证书直接全部丢到nginx/conf文件夹,然后改写nginx配置文件:

user  www;
worker_processes auto;
error_log  /www/wwwlogs/nginx_error.log  crit;
pid        /www/server/nginx/logs/nginx.pid;
worker_rlimit_nofile 51200;
events
   {
       use epoll;
       worker_connections 51200;
       multi_accept on;
   }
http {
   include       mime.types;
   default_type  application/octet-stream;
   sendfile        on;
   keepalive_timeout  65;
   client_max_body_size 100m;
   #用于tomcat反向代理,解决nginx 504错误
   proxy_connect_timeout 7200; #单位秒
   proxy_send_timeout 7200; #单位秒
   proxy_read_timeout 7200; #单位秒
   proxy_buffer_size 16k;
   proxy_buffers 4 64k;
   proxy_busy_buffers_size 128k;
   proxy_temp_file_write_size 128k;
   # ps:以timeout结尾配置项时间要配置大点
   server {
       listen       80;
       server_name  localhost;
   charset utf-8;
     location / {
           root   /home/wqj/dist;
     try_files $uri $uri/ /index.html;
           index  index.html index.htm;
         }
     location /prod-api/ {
     proxy_set_header Host $http_host;
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header REMOTE-HOST $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_pass http://localhost:8765/;
     }
       error_page   500 502 503 504  /50x.html;
       location = /50x.html {
           root   html;
       }
   }
server {
       #SSL 默认访问端口号为 443
       listen 443 ssl;
       #请填写绑定证书的域名
       server_name wangqingjiang.top;
       #请填写证书文件的相对路径或绝对路径
       ssl_certificate wangqingjiang.top_bundle.crt;
       #请填写私钥文件的相对路径或绝对路径
       ssl_certificate_key wangqingjiang.top.key;
       ssl_session_timeout 5m;
       #请按照以下协议配置
       ssl_protocols TLSv1.2 TLSv1.3;
       #请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
       ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
       ssl_prefer_server_ciphers on;
   charset utf-8;
   
   location / {
     root   /home/wqj/dist;
     try_files $uri $uri/ /index.html;
     index  index.html index.htm;
   }
   
   location /prod-api/ {
   proxy_set_header Host $http_host;
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header REMOTE-HOST $remote_addr;
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   proxy_pass http://localhost:8765/;
   }
   
   error_page   500 502 503 504  /50x.html;
       location = /50x.html {
           root   html;
       }
   }

}

回头再看,其实就是一些固定的配置。然后重启nginx之后就发现https已经生效:

图片

后来抓的包我就没读懂过:

图片

 

4、分页的前端配置

接下来以操作日志页面为例子,进行讲述。

前端每次给后端发请求的时候,都是带了分页参数的,默认都是请求第一页,每页10条数据。源码:

//请求参数:
     queryParams: {
       pageNum: 1,
       pageSize: 10,
       title: undefined,
       operName: undefined,
       businessType: undefined,
       status: undefined
     }
     
//每次 发送请求带上了分页参数的:
   /** 查询登录日志 */
   getList() {
     this.loading = true;
     list(this.addDateRange(this.queryParams, this.dateRange)).then( response => {
         this.list = response.rows;
         this.total = response.total;
         this.loading = false;
       }
     );

},

ry对elementUI的分页组件进行了小小的封装:

​​​​​

<template>
 <div :class="{'hidden':hidden}" class="pagination-container">
   <el-pagination
     :background="background"
     :current-page.sync="currentPage"
     :page-size.sync="pageSize"
     :layout="layout"
     :page-sizes="pageSizes"
     :pager-count="pagerCount"
     :total="total"
     v-bind="$attrs"
     @size-change="handleSizeChange"
     @current-change="handleCurrentChange"
   />
 </div>
</template>
<script>
import { scrollTo } from '@/utils/scroll-to'
export default {
 name: 'Pagination',
 props: {
   total: {
     required: true,
     type: Number
   },
   page: {
     type: Number,
     default: 1
   },
   limit: {
     type: Number,
     default: 20
   },
   pageSizes: {
     type: Array,
     default() {
       return [10, 20, 30, 50]
     }
   },
   // 移动端页码按钮的数量端默认值5
   pagerCount: {
     type: Number,
     default: document.body.clientWidth < 992 ? 5 : 7
   },
   layout: {
     type: String,
     default: 'total, sizes, prev, pager, next, jumper'
   },
   background: {
     type: Boolean,
     default: true
   },
   autoScroll: {
     type: Boolean,
     default: true
   },
   hidden: {
     type: Boolean,
     default: false
   }
 },
 data() {
   return {
   };
 },
 computed: {
   currentPage: {
     get() {
       return this.page
     },
     set(val) {
       this.$emit('update:page', val)
     }
   },
   pageSize: {
     get() {
       return this.limit
     },
     set(val) {
       this.$emit('update:limit', val)
     }
   }
 },
 methods: {
   handleSizeChange(val) {
     if (this.currentPage * val > this.total) {
       this.currentPage = 1
     }
     this.$emit('pagination', { page: this.currentPage, limit: val })
     if (this.autoScroll) {
       scrollTo(0, 800)
     }
   },
   handleCurrentChange(val) {
     this.$emit('pagination', { page: val, limit: this.pageSize })
     if (this.autoScroll) {
       scrollTo(0, 800)
     }
   }
 }
}
</script>
<style scoped>
.pagination-container {
 background: #fff;
 padding: 32px 16px;
}
.pagination-container.hidden {
 display: none;
}

</style>

我们跟着elementUI学习一下分页插件即可:

https://element.eleme.cn/#/zh-CN/component/pagination

参考学习资料:

https://blog.csdn.net/chenxi_li/article/details/118682708

我们看到了,前端只需要维护好数据,我需要当前是第几页,一共有几条数据,每页多少条。

前端只需要维护好这三个数据,其他的交给后端就行了。

4.1后端分页实现pagehelper

后端是通过pagehelper插件实现的。

ry通过pagehelper间接引入了mybatis:

图片

现在我们需要学习一波pagehelper的使用。

这就不得不介绍一波pagehelper的官网了:

https://pagehelper.github.io/docs/howtouse/

通过官网,我们需要知道为啥ry引入了分页插件就可以使用了,难道没有配置吗?

确实,如果使用了SpringBoot可以零配置。我们先通过创建一个新的项目零配置来使用一下pagehelper:

通过官网讲述常见的下面的分页方式:

// //第二种,Mapper接口方式的调用,推荐这种使用方式。
//获取第1页,10条内容,默认查询总数count
// ry用的就是下面这种。
PageHelper.startPage(1, 10);
//第五种,参数对象
//如果 pageNum 和 pageSize 存在于 User 对象中,只要参数有值,也会被分页
//有如下 User 对象
public class User {
   //其他fields
   //下面两个参数名和 params 配置的名字一致
   private Integer pageNum;
   private Integer pageSize;
}
//支持 ServletRequest,Map,POJO 对象,需要配合 params 参数
// 1、如果是request 则需要请求的时候带上对应的参数。
// 2、如果是Map 则Map中需要包含pageNum,pageSize等选项。
// 3、如果是POJO  则需要在pojo中带上对应的属性。


PageHelper.startPage(request);

通过官网讲解常见的几种分页方式:

PageHelper.startPage传普通参数(ry使用的)。

PageHelper.startPage方法传POJO或Map或ServletRequest。

分析pagehelper源码

首先是需要分析分页拦截器。

分页插件在哪进行注入到SqlSessionFactory的?

这就不得不提到两个主动配置的类了:

图片

其中PageHelperProperties是为了去yml取出相应的配置,以供PageHelperAutoConfiguration在执行构造方法的时候找到。

PageHelperAutoConfiguration实现了InitializingBean接口,所以重写了afterPropertiesSet方法,该方法会在构造方法执行后执行。

接下来打俩断点,看看执行过程:

图片

我们的yml配置是这样写的:

pagehelper:  helperDialect: mysql  supportMethodsArguments: true  params: count=countSqldebug的时候需要注意,以上参数的默认值是什么?【debug讲述】

经过debug发现其实ry设置的几个参数全部不设置也可以。

helperDialect如果不设置,程序每次执行SQL都要分析方言,何不索性告诉分页插件,这样也让程序执行略快一点。

supportMethodsArguments虽然设置了,但是其实ry中根本没用过。

params设置了个寂寞,原本默认就是count=countSql,本来就是默认值,设置也是白设置。

分析ry如何使用pagehelper

ry在BaseController中封装了分页方法。也就是说我们自己写的controller只要继承了BaseController,直接调用startPage方法即可完成分页。

ry的分页源码也非常简单:​​​​​​​

    /**     * 设置请求分页数据     */    public static void startPage(){        PageDomain pageDomain = TableSupport.buildPageRequest();        Integer pageNum = pageDomain.getPageNum();        Integer pageSize = pageDomain.getPageSize();        String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());        Boolean reasonable = pageDomain.getReasonable();        PageHelper.startPage(pageNum, pageSize, orderBy).setReasonable(reasonable);    }

从源码可以发现,无非就是从请求中拿到从前端传来的pageNum,pageSize,reasonable,orderBy和isAsc这些分页参数,然后直接调用分页插件pagehelper的静态分页方法PageHelper.startPage。

5、ry中的Mybatis详解

5.1 mybatis和SpringBoot结合方式

经过以前的经验,我们直接看mybatis的自动配置类:​​​​​​​

 @Bean
 @ConditionalOnMissingBean
 public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
   SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
   factory.setDataSource(dataSource);
   factory.setVfs(SpringBootVFS.class);
   if (StringUtils.hasText(this.properties.getConfigLocation())) {
     factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
   }
   applyConfiguration(factory);
   if (this.properties.getConfigurationProperties() != null) {
     factory.setConfigurationProperties(this.properties.getConfigurationProperties());
   }
   if (!ObjectUtils.isEmpty(this.interceptors)) {
     factory.setPlugins(this.interceptors);
   }
   if (this.databaseIdProvider != null) {
     factory.setDatabaseIdProvider(this.databaseIdProvider);
   }
   if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
     factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
   }
   if (this.properties.getTypeAliasesSuperType() != null) {
     factory.setTypeAliasesSuperType(this.properties.getTypeAliasesSuperType());
   }
   if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
     factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
   }
   if (!ObjectUtils.isEmpty(this.typeHandlers)) {
     factory.setTypeHandlers(this.typeHandlers);
   }
   if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
     factory.setMapperLocations(this.properties.resolveMapperLocations());
   }
   Set<String> factoryPropertyNames = Stream
       .of(new BeanWrapperImpl(SqlSessionFactoryBean.class).getPropertyDescriptors()).map(PropertyDescriptor::getName)
       .collect(Collectors.toSet());
   Class<? extends LanguageDriver> defaultLanguageDriver = this.properties.getDefaultScriptingLanguageDriver();
   if (factoryPropertyNames.contains("scriptingLanguageDrivers") && !ObjectUtils.isEmpty(this.languageDrivers)) {
     // Need to mybatis-spring 2.0.2+
     factory.setScriptingLanguageDrivers(this.languageDrivers);
     if (defaultLanguageDriver == null && this.languageDrivers.length == 1) {
       defaultLanguageDriver = this.languageDrivers[0].getClass();
     }
   }
   if (factoryPropertyNames.contains("defaultScriptingLanguageDriver")) {
     // Need to mybatis-spring 2.0.2+
     factory.setDefaultScriptingLanguageDriver(defaultLanguageDriver);
   }
   return factory.getObject();

}

可以发现,无非就是创建SqlSessionFactoryBean并且进行一系列配置之后,getObject得到SqlSessionFactory(实际是DefaultSqlSessionFactory对象)对象。

so,ry也是如此,重写了一个方法来获得sqlSessionFactory:​​​​​​​

   @Bean
   public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
{
       String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
       String mapperLocations = env.getProperty("mybatis.mapperLocations");
       String configLocation = env.getProperty("mybatis.configLocation");
       typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
       VFS.addImplClass(SpringBootVFS.class);
       final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
       sessionFactory.setDataSource(dataSource);
       sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
       sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
       sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
       return sessionFactory.getObject();

 }

在SpringBoot项目中,把SqlSessionFactory接口的实例注入到Spring容器中,mybatis的配置也就随之完成。

经过debug源码,发现本质上ry的注入SqlSessionFactory和原本的自动注入没什么差别,如果一定要说有差别,那就是亲自去扫描了别名包typeAliasesPackage。但其实必要性不大,框架自己也会去扫。

通过以上的说明,我们发现其实可以把ry的mybatis配置必要性并不大,可以完全删除ry自己配置的bean,发现一点也不影响当前项目的功能。

5.2mybatis-plus集成

关于mybatis-plus只是部分同学的需求,我们现在来做一下。做完再解释!

ry集成mybatis-plus最简秘诀

第一步,引入mybatis-plus,在common模块中:​​​​​​​

        <dependency>
           <groupId>com.baomidou</groupId>
           <artifactId>mybatis-plus-boot-starter</artifactId>
           <version>3.5.2</version>

 </dependency>

第二步,删除冲突依赖:​​​​​​​

        <!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
</exclusions>

</dependency>

第三步,填写yml配置:​​​​​​​

mybatis-plus:
 configLocation: classpath:mybatis/mybatis-config.xml

 typeAliasesPackage: com.ruoyi.**.domain

第四步,删除MyBatisConfig,也就是删除ry自己的配置文件,删除下面这个文件:​​​​​​​

package com.wqj.test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import javax.sql.DataSource;
import com.baomidou.mybatisplus.autoconfigure.SpringBootVFS;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.io.VFS;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;
/**
* Mybatis支持*匹配扫描包
*
* @author ruoyi
*/
@Configuration
public class MyBatisConfig
{
   @Autowired
   private Environment env;
   static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
   public static String setTypeAliasesPackage(String typeAliasesPackage)
{
       ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
       MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
       List<String> allResult = new ArrayList<String>();
       try
       {
           for (String aliasesPackage : typeAliasesPackage.split(","))
           {
               List<String> result = new ArrayList<String>();
               aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
                       + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN;
               Resource[] resources = resolver.getResources(aliasesPackage);
               if (resources != null && resources.length > 0)
               {
                   MetadataReader metadataReader = null;
                   for (Resource resource : resources)
                   {
                       if (resource.isReadable())
                       {
                           metadataReader = metadataReaderFactory.getMetadataReader(resource);
                           try
                           {
                               result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
                           }
                           catch (ClassNotFoundException e)
                           {
                               e.printStackTrace();
                           }
                       }
                   }
               }
               if (result.size() > 0)
               {
                   HashSet<String> hashResult = new HashSet<String>(result);
                   allResult.addAll(hashResult);
               }
           }
           if (allResult.size() > 0)
           {
               typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0]));
           }
           else
           {
               throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包");
           }
       }
       catch (IOException e)
       {
           e.printStackTrace();
       }
       return typeAliasesPackage;
   }
   public Resource[] resolveMapperLocations(String[] mapperLocations)
   {
       ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
       List<Resource> resources = new ArrayList<Resource>();
       if (mapperLocations != null)
       {
           for (String mapperLocation : mapperLocations)
           {
               try
               {
                   Resource[] mappers = resourceResolver.getResources(mapperLocation);
                   resources.addAll(Arrays.asList(mappers));
               }
               catch (IOException e)
               {
                   // ignore
               }
           }
       }
       return resources.toArray(new Resource[resources.size()]);
   }
   @Bean
   public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
{
       String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
       String mapperLocations = env.getProperty("mybatis.mapperLocations");
       String configLocation = env.getProperty("mybatis.configLocation");
       typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
       VFS.addImplClass(SpringBootVFS.class);
       final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
       sessionFactory.setDataSource(dataSource);
       sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
       sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
       sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
       return sessionFactory.getObject();
   }

}

然后直接重启项目,成功!

解释疑问:

疑问一:为什么要排除pagehelper中的mybatis依赖?

答:因为mybatis-plus的启动器和pagehelper都引入了mybatis,mybatis-plus的启动器的mybatis版本比较高。

pagehelper引入的mybatis的版本比较低,mybatis-plus用到了高版本mybatis的方法。所以需要排除pagehelper中的mybatis。否则报错没找到方法。

疑问二:pagehelper中排除了mybatis,为啥不把mybatis-spring一块给排除掉?

答:确实可以一块排除掉,可以。但是mybatis-plus也引入了mybatis-spring,所以并不冲突,maven会自动排除一个。

疑问三:为啥在pagehelper中不把MybatisAutoConfiguration的依赖排除掉?不都有mybatis-plus了吗,我还要MybatisAutoConfiguration有啥用?

答:因为pagehelper的自动配置类用到了MybatisAutoConfiguration,虽然不起作用,但是也不能排除依赖,否则直接报【类没有找到异常】。那么在哪里用到的呢?

图片

疑问四:为啥yml配置中不写mapperLocations的相关配置?

答:可以写,但是默认就是classpath*:mapper/**/*Mapper.xml,写不写都一样,相关源码:

图片

疑问五:为啥要删除原本的MybatisConfig?

答:因为原来的MybatisConfig会生成一个名字为sqlSessionFactory的bean,那么mybatis-plus的自动配置bean失效,因为mybatis-plus的自动配置加了注解@ConditionalOnMissingBean,也就是说sqlSessionFactory若存在,mybatis-plus则不会注入sqlSessionFactory。相关代码:

图片

测试mybatis-plus

直接测试一波登录日志的查询!

先给mapper接口加buff:

public interface SysLogininforMapper extends BaseMapper<SysLogininfor>

然后直接查询即可:​​​​​​​

    @Override    public List<SysLogininfor> selectLogininforList(SysLogininfor logininfor) {        return logininforMapper.selectList(null);        //        return logininforMapper.selectLogininforList(logininfor);    }

报错!

然后生成的SQL:​​​​​​​

SELECT  info_id,  user_name,  STATUS,  ipaddr,  login_location,  browser,  os,  msg,  login_time,  search_value,  create_by,  create_time,  update_by,  update_time,  remark,  params   FROM  sys_logininfor     LIMIT ?

好玩的事情发生了,BaseEntity的属性也被写入了SQL中。对于这种残花败柳,我们直接标记它不存在:​​​​​​​

    /**     * 搜索值     */    @TableField(exist = false)    private String searchValue;
    /**     * 创建者     */    @TableField(exist = false)    private String createBy;
    /**     * 创建时间     */    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")    @TableField(exist = false)
    private Date createTime;
    /**     * 更新者     */    @TableField(exist = false)
    private String updateBy;
    /**     * 更新时间     */    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")    @TableField(exist = false)    private Date updateTime;
    /**     * 备注     */    @TableField(exist = false)    private String remark;
    /**     * 请求参数     */    @TableField(exist = false)    private Map<String, Object> params;

随之查询成功,mp集成到此结束!

3►扩展学习

请大家自主学习下面注解的含义。

网站一:

https://wenku.baidu.com/view/20631ddf0142a8956bec0975f46527d3240ca624.html

网站二:

https://blog.csdn.net/Lou_Lan/article/details/106192074

网站三:

https://blog.csdn.net/weixin_43808717/article/details/118214615

网站四:

https://baijiahao.baidu.com/s?id=1740059649839757132&wfr=spider&for=pc

图片一(引用自csdn:):

图片

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

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

相关文章

企业信息化过程----应用管理平台的构建过程

1.信息化的概念 信息化是一个过程&#xff0c;与工业化、现代化一样&#xff0c;是一个动态变化的过程。信息化已现代通信&#xff0c;网络、数据库技术为基础&#xff0c;将所有研究对象各个要素汇总至数据库&#xff0c;供特定人群生活、工作、学习、辅助决策等&#xff0c;…

前端基础(Vue的模块化开发)

目录 前言 响应式基础 ref reactive 学习成果展示 Vue项目搭建 总结 前言 前面学习了前端HMTL、CSS样式、JavaScript以及Vue框架的简单适用&#xff0c;接下来运用前面的基础继续学习Vue&#xff0c;运用前端模块化编程的思想。 响应式基础 ref reactive 关于ref和react…

linux:Temporary failure in name resolutionCouldn’t resolve host

所有域名无法正常解析。 ping www.baidu.com 等域名提示 Temporary failure in name resolution错误。 rootlocalhost:~# ping www.baidu.com ping: www.baidu.com: Temporary failure in name resolution rootlocalhost:~# 一、ubuntu/debian&#xff08;emporary failure i…

提升大数据技能,不再颓废!这6家学习网站是你的利器!

随着国家数字化转型&#xff0c;大数据领域对人才的需求越来越多。大数据主要研究计算机科学和大数据处理技术等相关的知识和技能&#xff0c;从大数据应用的三个主要层面&#xff08;即数据管理、系统开发、海量数据分析与挖掘&#xff09;出发&#xff0c;对实际问题进行分析…

学习笔记230810--get请求的两种传参方式

问题描述 今天写了一个对象方式传参的get请求接口方法&#xff0c;发现没有载荷&#xff0c;ip地址也没有带查询字符串&#xff0c;数据也没有响应。 代码展示 错误分析 实际上这里的query是对象方式带参跳转的参数名&#xff0c;而get方法对象方式传参的参数名是parmas 解…

华为OD机试 - 秘钥格式化 - 双指针(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…

条件判断语句

二、判断语句 # 判断语句result10>15 print("10>5的结果是&#xff1a;%s"% result,type(result))eq"yl""yl" print("\"ylyl\" %s"% eq,type(eq))bool_1True bool_2False print(f"打印出类型,{bool_1},类型是{ty…

【论文笔记】MetaBEV: Solving Sensor Failures for BEV Detection and Map Segmentation

原文链接&#xff1a;https://arxiv.org/abs/2304.09801 1. 引言 目前&#xff0c;多模态融合感知中的一大问题在于忽视了传感器失效带来的影响。之前工作的主要问题包括&#xff1a; 特征不对齐&#xff1a;通常使用CNN处理拼接后的特征图&#xff0c;存在几何噪声时可能导致…

2023-8-14 前缀和

原题链接&#xff1a;前缀和 #include <iostream> using namespace std;const int N 100010;int n, m;int a[N], s[N];int main () {scanf("%d%d", &n, &m);for(int i 1; i < n; i ) scanf("%d", &a[i]);for(int i 1; i < n;…

Oracle Database12c数据库官网下载和安装教程

文章目录 下载安装Oracle自带的客户端工具使用 下载 进入oracle官网 点击下载连接之后右上角会有一个下载 我们只需要数据库本体就够了 运行这个下载器 等待下好之后即可 出现 Complete 之后代表下载成功&#xff0c;然后我们解压即可 安装 双击 双击setup.exe 根据…

windows电脑安装了多个版本python 用vscode编程如何指定版本

在状态栏中找到 Python 版本号。这个版本号表示当前正在使用的 Python 解释器版本。 如果需要切换到其他版本的 Python&#xff0c;请点击版本号&#xff0c;然后从列表中选择所需的 Python 版本。列表中的 Python 版本是按照安装顺序排列的。这里一般会有多个版本可供选择

URL编码指南

URL简介 URL 是统一资源定位符&#xff08;Uniform Resource Locator&#xff09;的缩写。它是用于在互联网上定位并访问资源的一种标识方式。 URL通常由以下几个组成部分组成&#xff1a; 协议&#xff08;Protocol&#xff09;&#xff1a;指示要使用的协议&#xff0c;如…

ubuntu 搜狗输入法安装 和 无法输入中文

一、下载搜狗输入法Linux版本。 搜狗输入法linux-首页 二、安装fcitx输入框架&#xff0c;及相关的依赖库 sudo apt install fcitx-bin sudo apt-get install fcitx-table sudo apt --fix-broken install 三、安装搜狗输入法 sudo dpkg -i sougou....deb 四、通过 设置&…

【福建事业单位-综合基础知识】03行政法

【福建事业单位-综合基础知识】03行政法 1.行政法概述&#xff08;原则重点&#xff09;行政主体范围 行政行为总结 二.行政处罚2.1行政处罚的种类总结 行政法框架 1.行政法概述&#xff08;原则重点&#xff09; 行政法的首要原则是合法&#xff1b;自由裁量——合理行政&…

RequestRespons

文章目录 Request&Respons1 Request和Response的概述2 Request对象2.1 Request继承体系2.2 Request获取请求数据2.2.1 获取请求行数据2.2.2 获取请求头数据2.2.3 获取请求体数据2.2.4 获取请求参数的通用方式 2.3 IDEA快速创建Servlet2.4 请求参数中文乱码问题2.4.1 POST请…

标题:Python数据结构详解:列表、元组、字典和集合

文章目录 &#x1f340;引言&#x1f340;列表&#xff08;List&#xff09;&#xff1a;有序可变序列&#x1f340;特点&#x1f340;常见操作 &#x1f340;元组&#xff08;Tuple&#xff09;&#xff1a;有序不可变序列&#x1f340;特点&#x1f340;常见操作 &#x1f34…

18-组件化开发 根组件

组件化开发 & 根组件: 1. 组件化:一个页面可以拆分成一个个组件&#xff0c;每个组件有着自己独立的结构、样式、行为. 好处:便于维护&#xff0c;利于复用->提升开发效率 组件分类: 普通组件 , 根组件 2. 根组件:整个应用最上层的组件&#xff0c;包裹所有普通小组件…

Smartbi:大模型+ABI在企业数字化浪潮中“推波助澜”?

围绕着大模型进行开发的范式正在形成。 2023年以来&#xff0c;ChatGPT让各界认识到通用大模型的力量。随之而来的&#xff0c;是一场属于所有行业的科技盛宴&#xff0c;一个个行业大模型涌现&#xff0c;几乎所有科技企业都在计划或已经发布了自己的大语言模型&#xff08;L…

ACDU-数据库技术揭秘及应用实践

ACDU-数据库技术揭秘及应用实践 会议时间&#xff1a;2023-08-19 13&#xff1a;30 ~ 17:30 会议地点&#xff1a;杭州西溪万怡酒店 活动主题&#xff1a;本活动由中国数据库联盟组织&#xff0c;并汇集了数据库领域知名人士&#xff0c;一起探讨了数据库前沿技术的应用。 活动…

记录:win10物理机ping不通虚拟机上的docker子网(已解决)

【说明】 windows10&#xff1a;已关闭防火墙 linux发行版本&#xff1a;centos7.9&#xff08;已禁用SElinux、已关闭防火墙&#xff09; 虚拟机软件&#xff1a;VMware Workstation 17 虚拟机网络模式&#xff1a;NAT模式 docker版本&#xff1a;20.4.5 docker网络模式…