mysqls压力测试怎么用_用 Swagger 测试接口,怎么在请求头中携带 Token?

松哥周末抽空给 Spring Security 系列也录制了一套视频,目录如下:

d3f8011f0cd4bf629a23d15b1def2f92.png

感兴趣的小伙伴戳这里-->Spring Boot+Vue+微人事视频教程

今天的话题来自一个小伙伴在微信上的提问:

7a52f6ca39bf98c2eb145bd01fe77578.png

看到这个问题,松哥忽然想到我自己之前写过 Spring Boot+Swagger 的用法:

  • SpringBoot 整合 Swagger2

也写过 OAuth2 + Jwt 的用法:

  • 想让 OAuth2 和 JWT 在一起愉快玩耍?请看松哥的表演

但是还没有将这两个结合在一起写过,所以小伙伴们对此有了疑问,想一想这还是一个非常常见的问题,因为现在使用令牌登录的场景越来越多,在这种情况下,如果使用 Swagger 来测试接口,要怎么在请求头中携带 Token 呢?今天松哥就来和大家聊一聊。

1.项目规划

如果小伙伴们没有看过松哥之前发的 OAuth2 系列文章,建议一定先看下(公众号江南一点雨后台回复 OAuth2 获取),再来看本文内容,否则接下来的内容可能会犯迷糊。

这里松哥搭建一个 OAuth2+JWT 的环境来做演示。一共搭建两个服务:

服务名端口备注
auth-server8080授权服务器
user-server8081资源服务器

我稍微解释一下:

  • auth-server 就是我的资源服务器,用来颁发 JWT 令牌。
  • user-server 则是资源服务器,访问 user-server 上的资源,都需要携带令牌才能访问。
  • swagger 则用来给 user-server 上的接口生成文档。

OK,这是我们项目的一个大致规划。

2.环境搭建

接下来我们来搭建 OAuth2 测试环境。

2.1 授权服务器搭建

首先我们搭建一个名为 auth-server 的授权服务,搭建的时候,选择如下三个依赖:

  • Web
  • Spring Cloud Security
  • Spirng Cloud OAuth2
452d39ff4b93b04ef8d03daef5d01b28.png

项目创建完成后,首先提供一个 Spring Security 的基本配置:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("sang")
                .password(passwordEncoder().encode("123"))
                .roles("admin")
                .and()
                .withUser("javaboy")
                .password(passwordEncoder().encode("123"))
                .roles("user");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().formLogin();
    }
}

在这段代码中,为了代码简洁,我就不把 Spring Security 用户存到数据库中去了,直接存在内存中。

这里我创建了一个名为 sang 的用户,密码是 123,角色是 admin。同时我还配置了一个表单登录。

这段配置的目的,实际上就是配置用户。例如你想用微信登录第三方网站,在这个过程中,你得先登录微信,登录微信就要你的用户名/密码信息,那么我们在这里配置的,其实就是用户的用户名/密码/角色信息。

需要注意的是,在当前案例中,我将采用 OAuth2 中的 password 模式进行登录,因此这里还需要明确的提供一个 AuthenticationManager 的 Bean。

基本的用户信息配置完成后,接下来我们来配置授权服务器。

首先来配置 TokenStore:

@Configuration
public class AccessTokenConfig {
    @Bean
    TokenStore tokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    @Bean
    JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("javaboy");
        return converter;
    }
}
  1. TokenStore 我们使用 JwtTokenStore 这个实例。使用了 JWT,access_token 实际上就不用存储了(无状态登录,服务端不需要保存信息),因为用户的所有信息都在 jwt 里边,所以这里配置的 JwtTokenStore 本质上并不是做存储。
  2. 另外我们还提供了一个 JwtAccessTokenConverter,这个 JwtAccessTokenConverter 可以实现将用户信息和 JWT 进行转换(将用户信息转为 jwt 字符串,或者从 jwt 字符串提取出用户信息)。
  3. 另外,在 JWT 字符串生成的时候,我们需要一个签名,这个签名需要自己保存好。

接下来对授权服务器进行详细配置:

@EnableAuthorizationServer
@Configuration
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
    @Autowired
    TokenStore tokenStore;
    @Autowired
    ClientDetailsService clientDetailsService;
    @Autowired
    AuthenticationManager authenticationManager;
    @Autowired
    PasswordEncoder passwordEncoder;
    @Autowired
    JwtAccessTokenConverter jwtAccessTokenConverter;

    @Bean
    AuthorizationServerTokenServices tokenServices() {
        DefaultTokenServices services = new DefaultTokenServices();
        services.setClientDetailsService(clientDetailsService);
        services.setSupportRefreshToken(true);
        services.setTokenStore(tokenStore);
        services.setAccessTokenValiditySeconds(60 * 60 * 24 * 2);
        services.setRefreshTokenValiditySeconds(60 * 60 * 24 * 7);
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(jwtAccessTokenConverter));
        services.setTokenEnhancer(tokenEnhancerChain);
        return services;
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.allowFormAuthenticationForClients();
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("javaboy")
                .secret(passwordEncoder.encode("123"))
                .resourceIds("res1")
                .authorizedGrantTypes("password", "refresh_token")
                .scopes("all")
                .redirectUris("http://localhost:8082/index.html");
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                .authenticationManager(authenticationManager)
                .tokenServices(tokenServices());
    }
}

这段代码有点长,我来给大家挨个解释:

  1. 创建 AuthorizationServer 类继承自 AuthorizationServerConfigurerAdapter,来对授权服务器做进一步的详细配置,AuthorizationServer 类记得加上 @EnableAuthorizationServer 注解,表示开启授权服务器的自动化配置。
  2. 在 AuthorizationServer 类中,我们其实主要重写三个 configure 方法。
  3. AuthorizationServerSecurityConfigurer 用来配置令牌端点的安全约束,也就是这个端点谁能访问,谁不能访问。
  4. ClientDetailsServiceConfigurer 用来配置客户端的详细信息,在之前文章中,松哥和大家讲过,授权服务器要做两方面的检验,一方面是校验客户端,另一方面则是校验用户,校验用户,我们前面已经配置了,这里就是配置校验客户端。客户端的信息我们可以存在数据库中,这其实也是比较容易的,和用户信息存到数据库中类似,但是这里为了简化代码,我还是将客户端信息存在内存中,这里我们分别配置了客户端的 id,secret、资源 id、授权类型、授权范围以及重定向 uri。授权类型我在之前文章中和大家一共讲了四种,四种之中不包含 refresh_token 这种类型,但是在实际操作中,refresh_token 也被算作一种。
  5. AuthorizationServerEndpointsConfigurer 这里用来配置令牌的访问端点和令牌服务。
  6. tokenServices 这个 Bean 主要用来配置 Token 的一些基本信息,例如 Token 是否支持刷新、Token 的存储位置、Token 的有效期以及刷新 Token 的有效期等等。Token 有效期这个好理解,刷新 Token 的有效期我说一下,当 Token 快要过期的时候,我们需要获取一个新的 Token,在获取新的 Token 时候,需要有一个凭证信息,这个凭证信息不是旧的 Token,而是另外一个 refresh_token,这个 refresh_token 也是有有效期的。

好了,如此之后,我们的授权服务器就算是配置完成了,接下来我们启动授权服务器。

如果小伙伴们对于上面的配置感到迷糊,可以在公众号后台回复 OAuth2,先系统的学习一下松哥的 OAuth2 教程。

2.2 资源服务器搭建

接下来我们搭建一个资源服务器。大家网上看到的例子,资源服务器大多都是和授权服务器放在一起的,如果项目比较小的话,这样做是没问题的,但是如果是一个大项目,这种做法就不合适了。

资源服务器就是用来存放用户的资源,例如你在微信上的图像、openid 等信息,用户从授权服务器上拿到 access_token 之后,接下来就可以通过 access_token 来资源服务器请求数据。

我们创建一个新的 Spring Boot 项目,叫做 user-server ,作为我们的资源服务器,创建时,添加如下依赖:

452d39ff4b93b04ef8d03daef5d01b28.png

项目创建成功之后,先把前面的 AccessTokenConfig 拷贝到资源服务器上,然后添加如下配置:

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Autowired
    TokenStore tokenStore;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId("res1").tokenStore(tokenStore);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("admin")
                .anyRequest().authenticated();
    }
}

这段配置代码很简单,我简单的说一下:

  1. 首先在 configure 方法中配置资源 ID 和 TokenStore,这里配置好之后,会自动调用 JwtAccessTokenConverter 将 jwt 解析出来,jwt 里边就包含了用户的基本信息,所以就不用远程校验 access_token 了。
  2. 最后配置一下资源的拦截规则,这就是 Spring Security 中的基本写法,我就不再赘述。

接下来我们再来配置两个测试接口:

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
    @GetMapping("/admin/hello")
    public String admin() {
        return "admin";
    }
}

如此之后,我们的资源服务器就算配置成功了。

2.3 测试

分别启动授权服务器和资源服务器,先访问授权服务器获取 access_token:

f7ac741bb215c8d9e29b4970d1962e37.png

再利用拿到的 access_token 去访问资源服务器:

5fd3eeb734ef45c42e6a297ae5861e80.png

OK,测试没问题。

3.整合 Swagger

接下来,我们在 user-server 中加入 swagger 功能,首先我们加入 swagger 依赖:

 <dependency>
     <groupId>io.springfoxgroupId>
     <artifactId>springfox-swagger2artifactId>
     <version>2.9.2version>
 dependency>
 <dependency>
     <groupId>io.springfoxgroupId>
     <artifactId>springfox-swagger-uiartifactId>
     <version>2.9.2version>
 dependency>

这里加入的依赖有两个,一个用来生成接口数据,另一个 swagger-ui 用来做数据展示。

3.1 认证方式一

请求头加参数,这里给大家介绍两种,先来看第一种。

先配置一个 Docket 实例,如下:

@Configuration
@EnableSwagger2
public class Swagger2Config {
    @Bean
    Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage("org.javaboy.oauth2.res.controller"))
                .paths(PathSelectors.any())
                .build()
                .securityContexts(Arrays.asList(securityContexts()))
                .securitySchemes(Arrays.asList(securitySchemes()))
                .apiInfo(new ApiInfoBuilder()
                        .description("接口文档的描述信息")
                        .title("微人事项目接口文档")
                        .contact(new Contact("javaboy","http://www.javaboy.org","wangsong0210@gmail.com"))
                        .version("v1.0")
                        .license("Apache2.0")
                        .build());
    }
    private SecurityScheme securitySchemes() {
        return new ApiKey("Authorization", "Authorization", "header");
    }

    private SecurityContext securityContexts() {
        return SecurityContext.builder()
                        .securityReferences(defaultAuth())
                        .forPaths(PathSelectors.any())
                        .build();
    }

    private List defaultAuth() {
        AuthorizationScope authorizationScope = new AuthorizationScope("xxx", "描述信息");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        return Arrays.asList(new SecurityReference("Authorization", authorizationScopes));
    }
}

这里的配置稍微有点长,我来给大家解释下:

  • 首先通过 @EnableSwagger2 注解启用 Swagger2。
  • 配置一个 Docket Bean,这个 Bean 中,配置映射路径和要扫描的接口的位置。
  • 在 apiInfo 中,主要配置一下 Swagger2 文档网站的信息,例如网站的 title,网站的描述,联系人的信息,使用的协议等等。
  • 通过 securitySchemes 来配置全局参数,这里的配置是一个名为 Authorization 的请求头(OAuth2 中需要携带的请求头)。
  • securityContexts 则用来配置有哪些请求需要携带 Token,这里我们配置了所有请求。

配置完成后,我们还需要给 swagger-ui 放行,否则 swagger-ui 相关的静态资源会被 Spring Security 拦截下来:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/swagger-ui.html")
                .antMatchers("/webjars/**")
                .antMatchers("/v2/**")
                .antMatchers("/swagger-resources/**");
    }
}

配置完成后,重启 user-server,浏览器输入 http://localhost:8081/swagger-ui.html,结果如下:

22bd22e41e29f7229fb5d4fb5da80c1f.png

大家可以看到,页面中多了一个 Authorize 按钮,点击该按钮,输入 Bearer ${token},如下:

4af5777bf39bf5e773f408ca853339f8.png

输入完成后,点击 Authorize 按钮,完成认证,接下来,user-server 中的各种接口就可以直接调用测试了。

上面这种方式比较通用,不仅仅适用于 OAuth2,也适用于其他一些自定义的 token 登录方式。

但是这种方式需要开发者先通过其他途径获取到 access_token,有的人会觉得这样有点麻烦,那么有没有更好的办法呢?请看方式二。

3.2 认证方式二

认证方式二就是直接在 Swagger 中填入认证信息,这样就不用从外部去获取 access_token 了,效果如下:

7b7eb0817eca574769a990caab878850.png30263bf5b00268fbeb41a457641fae0b.png

我们来看下这个怎么配置。

由于 swagger 去请求 /oauth/token 接口会跨域,所以我们首先要修改 auth-server ,使之支持跨域:

主要是两方面的修改,首先是配置 CorsFilter,允许跨域,如下:

@Configuration
public class GlobalCorsConfiguration {
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }
}

然后在 SecurityConfig 中开启跨域支持:

@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    ...
    ...
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .requestMatchers().antMatchers(HttpMethod.OPTIONS, "/oauth/**")
                .and()
                .csrf().disable().formLogin()
                .and()
                .cors();
    }
}

经过这两步的配置,服务端的跨域支持就开启了。

接下来我们在 user-server 中修改关于 Docket bean 的定义:

@Configuration
@EnableSwagger2
public class Swagger2Config {
    @Bean
    Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.basePackage("org.javaboy.oauth2.res.controller"))
                .paths(PathSelectors.any())
                .build()
                .securityContexts(Arrays.asList(securityContext()))
                .securitySchemes(Arrays.asList(securityScheme()))
                .apiInfo(new ApiInfoBuilder()
                        .description("接口文档的描述信息")
                        .title("微人事项目接口文档")
                        .contact(new Contact("javaboy","http://www.javaboy.org","wangsong0210@gmail.com"))
                        .version("v1.0")
                        .license("Apache2.0")
                        .build());
    }

    private AuthorizationScope[] scopes() {
        return new AuthorizationScope[]{
                new AuthorizationScope("all", "all scope")
        };
    }

    private SecurityScheme securityScheme() {
        GrantType grant = new ResourceOwnerPasswordCredentialsGrant("http://localhost:8080/oauth/token");
        return new OAuthBuilder().name("OAuth2")
                .grantTypes(Arrays.asList(grant))
                .scopes(Arrays.asList(scopes()))
                .build();
    }

    private SecurityContext securityContext() {
        return SecurityContext.builder()
                .securityReferences(Arrays.asList(new SecurityReference("OAuth2", scopes())))
                .forPaths(PathSelectors.any())
                .build();
    }
}

这段配置跟前面的类似,主要是 SecurityScheme 不同。这里采用了 OAuthBuilder 来构建,构建时即得配置 token 的获取地址。

好了,配置完成,重启 auth-server 和 user-server 进行测试。测试效果就是松哥前面给出的图片,不再赘述。

这种方式最大的好处就是不用通过其他途径获取 access_token,直接在 swagger-ui 页面输入 password 模式的认证参数即可。非常方便,仅限于 OAuth2 模式。

4.小结

好了,今天就和小伙伴们介绍了在 Swagger 请求中,如何修改请求头的问题,感兴趣的小伙伴可以下来试试哦~

本文案例下载地址:https://github.com/lenve/spring-security-samples

好啦,小伙伴们如果觉得有收获,记得点个在看鼓励下松哥哦~

今日干货

a87b54679ba0bb574cb14076618a6028.png刚刚发表查看:66666回复:666

公众号后台回复 ssm,免费获取松哥纯手敲的 SSM 框架学习干货。

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

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

相关文章

安卓手机背景变黑色怎么改_别着急扔掉旧手机 你的电脑可能需要它

PC玩家中&#xff0c;不少人都会有在玩游戏时观测电脑硬件状态的习惯。比如查看游戏帧数、CPU频率、GPU频率或是温度等。大多数人都是通过第三方软件&#xff0c;在游戏内把监测数据显示到电脑显示屏角落。可就算是在角落&#xff0c;这些数据依旧会阻挡游戏画面&#xff0c;在…

JDeps入门–分析项目的依赖关系

JDeps是Java依赖关系分析工具 &#xff0c;这是一个命令行工具&#xff0c;它处理Java字节码&#xff08;意味着.class文件或包含它们的JAR&#xff09;&#xff0c;并分析类之间静态声明的依赖关系。 可以用各种方式过滤结果&#xff0c;并可以将其汇总到包或JAR级别。 JDeps还…

禅道开源版用户手册_Docker搭建开源版禅道以及项目基本流程介绍

对于自学软件测试的同学来说&#xff0c;经常会遇到这样的困惑&#xff1a;测试用例怎么写&#xff1f;有啥好的模板&#xff1f;缺陷提交的模板是什么样的&#xff1f;bug的生命周期是啥&#xff1f;项目的流程是啥&#xff1f;以上这些困惑&#xff0c;在你仔细看完这篇文章后…

f12 卡 谷歌浏览器_抢券第二课:利用浏览器F12获取优惠券请求链接

抢券第二课为什么迟迟不来呢&#xff1f;因为最近京东没有那种神券需要定点抢购的&#xff0c;我也没法测试我的理论。现在京东的券随时可以领取到&#xff0c;我多没法测试的东西不想就这样欺骗你们。所以今天的第二课我们讲一讲神奇的谷歌浏览器F1201 工具准备一、浏览器这里…

Java命令行界面(第5部分):JewelCli

细算在Java命令行处理与Apache的百科全书CLI &#xff0c; args4j &#xff0c; jbock和命令行中先前的文章&#xff0c;我把注意力转向在这个岗位使用JewelCli完成的命令行参数相似的处理Java中。 几个Java命令行处理库使用批注来定义命令行选项。 到目前为止&#xff0c;本系…

dnf用虚拟机会被制裁吗_DNF: 神豪奶妈扬言, 战斗力没有超过他的, 都不配被加buff!...

要说到现在的年轻人们的交友方式绝对少不了游戏交友&#xff0c;以前的人们只要不出门那就是与世隔绝&#xff0c;而现在就算是不出门也可以在网络上结交一大帮朋友&#xff0c;游戏就是现在的年轻人们交友最多的地方之一。科技的发展让游戏进入了一个繁荣的春天&#xff0c;不…

什么叫轻量瓷_为什么说陶瓷是华夏文明的徽章?

一、先说何为徽章&#xff1f;徽&#xff0c;最基本的解释是标志、符号&#xff1b;章&#xff0c;基本释义较多&#xff0c;其之一为佩戴在身上的标志&#xff0c;如领章、胸章等。徽章&#xff0c;也就是佩戴在身上用以表示身份、职业或者荣誉的标志。徽章的作用是明确身份、…

Java命令行界面(第10部分):picocli

picocli主页面将picocli描述为“强大的微小命令行界面”&#xff0c;“ picocli”是一个文件Java框架&#xff0c;用于解析命令行参数并生成精美&#xff0c;易于定制的用法帮助消息。 有颜色。” 这篇文章简要介绍了如何使用Picocli 0.9.7处理Java代码中的命令行参数。 像本系…

workunit 的指的工作单元是什么_分频器是做什么用的?

由于现在的音箱几乎都采用多单元分频段重放的设计方式&#xff0c;所以必须有一种装置&#xff0c;能够将功放送来的全频带音乐信号按需要划分为高音、低音输出或者高音、中音、低音输出&#xff0c;才能跟相应的喇叭单元连接&#xff0c;分频器就是这样的装置。如果把全频带信…

合并不同gdb下的相同要素_GDB调试学习

简介GDB是GCC的调试工具。其功能如下&#xff1a;启动程序&#xff0c;使程序按自定义形式运行&#xff1b;使程序停止指定断点位置&#xff1b;程序停止后&#xff0c;检查程序执行中的相应情况&#xff1b;动态改变程序执行环境。gdb调试能进行GDB调试&#xff0c;一般在编译…

endnote文献顺序编号不对_把Endnote装进大脑:行走的文献管理者

是否还迷失在茫茫的文献海洋&#xff0c;东翻西找&#xff0c;仍无法获得需要的文献信息&#xff1f;是否还在半手动导入参考文献&#xff0c;费时费力&#xff1f;别着急&#xff0c;文献管理神器-Endnote轻松帮你搞定这些问题。把Endnote“装进”大脑&#xff0c;你就能成为行…

蔡司三坐标_蔡司三坐标测针的安装指南

1、装配和辅助工具合适的辅助工具可以在组装测针组时有效防止各部件的损坏&#xff0c;确保安装的安全进行。下面是几种最重要的装配和辅助工具。2、正确调整MT/VAST吸盘MT/VAST吸盘可以通过顶部的三个螺丝进行旋转调节。必须使用不超过2Nm的扭力紧固&#xff0c;为了防止螺丝的…

三电平igbt死区时间计算_IGBT基础与运用-2

IGBT基础与运用-1尝试去计算IGBT的开启过程&#xff0c;主要是时间和门电阻的散热情况。C.GE 栅极-发射极电容C.CE 集电极-发射极电容C.GC 门级-集电极电容(米勒电容)Cies CGE CGC 输入电容Cres CGC 反向电容Coes CGC CCE 输出电容根据充电的详细过程&#xff0c;可以下图…

在2017年从Maven工件生成P2存储库

几年前&#xff0c;我写了一篇博客文章&#xff0c;介绍如何基于Maven工件生成P2存储库。 如今&#xff0c;这种描述的方法已经过时了&#xff0c;我想展示一种基于p2-maven-plugin的新方法&#xff0c;该方法是为解决该问题而创建的。 Maven构建生命周期中的P2-Maven-Plugin集…

循环次数几次_圆柱模板循环使用次数是多少呢

对于同一处做同样的工程&#xff0c;如果需要使用的是圆柱模板&#xff0c;用户一定考虑到底该进多少货&#xff0c;备多少料(圆柱模板)呢&#xff1f;这就需要考虑到圆柱模板循环使用次数和错开的程度来进行决定的&#xff1f;建筑圆柱模板能周转几次&#xff1f;这可能是所有…

network 拦截不到东西是怎么做到的?_都说读中职院校学不到东西,中职学生到底是怎么学习的?...

中职院校在社会中的影响一直并不是很好&#xff0c;一直都是负面影响高于正面影响&#xff0c;那么&#xff0c;我们不禁就要问了&#xff0c;一直在喊提升中职院校的教学质量&#xff0c;质量提升到哪里去了呢&#xff01;那些中职院校里的学生到底又是怎么学习的呢&#xff1…

数组中查找並返回数组_java数组查找常见情况

一.最简单的查找元素方法&#xff08;依次比较&#xff09;&#xff1a;给一个数组&#xff0c;在数组里面查找某个元素在数组中的位置&#xff0c;并返回它的位置。public static void main(String[] args) {int arr[] new int[]{12, 4, 54, 57, 87, 3, 41, 1, 3, 4, 1, 3, 4…

阿帕奇跨域_阿帕奇骆驼遇见Redis

阿帕奇跨域键值商店的兰博基尼 Camel是最好的面包集成框架&#xff0c;在本文中&#xff0c;我将向您展示如何通过利用另一个出色的项目Redis使它更加强大。 Camel 2.11即将发布&#xff0c;具有许多新功能&#xff0c;错误修复和组件。 这些新组件中的几个是我创作的&#…

误码率越高越好还是越低越好_ISO永远都是越低越好?不一定!这些情况下要用高 ISO!...

关于摄影中的参数&#xff0c;在说到 ISO(感光度)的时候&#xff0c;大家脑海中肯定都会想到那句摄影中的定律——“使用尽可能低的 ISO ”&#xff0c;这是为什么呢&#xff1f;通过下面这张典型的高 ISO 照片我们能知道原因在图片里&#xff0c;那些不自然的、充斥整个画面的…

如何在Java 8中创建线程安全的ConcurrentHashSet?

在JDK 8之前&#xff0c;还没有办法在Java中创建大型的线程安全的ConcurrentHashSet。 java.util.concurrent包甚至没有一个名为ConcurrentHashSet的类&#xff0c;但是从JDK 8开始&#xff0c;您可以使用新添加的keySet&#xff08;默认值&#xff09;和newKeySet&#xff08;…