优化这段代码:public void fixedSpProduct(List<CrmSpProduct> crmSpProductList,Long spApplyId) { if (CollectionUtils.isNotEmpty(crmSpProductList)) { Map<String,Object> map = new HashMap<>(); map.put("SP_APPLY_ID",spApplyId); List<CrmSpProduct> list = this.getBaseMapper().selectByMap(map); if (CollectionUtils.isNotEmpty(list)){ crmSpProductMapper.deleteByMap(map); } for (CrmSpProduct c : crmSpProductList){ c.setSpApplyId(spApplyId); } super.saveOrUpdateBatch(crmSpProductList); } else { throw new BusinessRuntimeException("当前没有任何产品清单,操作失败"); } }
时间: 2023-06-02 13:03:22 浏览: 145
可以考虑使用批量操作来优化代码:
```
public void fixedSpProduct(List<CrmSpProduct> crmSpProductList,Long spApplyId) {
if (CollectionUtils.isEmpty(crmSpProductList)) {
throw new BusinessRuntimeException("当前没有任何产品清单,操作失败");
}
Map<String,Object> map = new HashMap<>();
map.put("SP_APPLY_ID",spApplyId);
crmSpProductMapper.deleteByMap(map);
for (CrmSpProduct c : crmSpProductList){
c.setSpApplyId(spApplyId);
}
super.saveOrUpdateBatch(crmSpProductList);
}
```
相关问题
麻烦帮我生成SpringCloud Gateway 集成SpringSecurity 的代码,使用的是WebFlux 要求:需要详细的config、filter、和完整的登录鉴权代码,并且有详细的注释
好的,下面是SpringCloud Gateway 集成SpringSecurity 的代码示例:
### 1.添加依赖
在pom.xml文件中添加以下依赖:
```xml
<dependencies>
<!-- Spring Cloud Gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
```
### 2.配置Spring Security
在WebSecurityConfigurerAdapter中配置Spring Security,如下所示:
```java
@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http.authorizeExchange()
.pathMatchers("/auth/**").permitAll()
.pathMatchers(HttpMethod.OPTIONS).permitAll()
.anyExchange().authenticated()
.and()
.httpBasic().and()
.formLogin();
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
}
```
上述代码中,我们配置了一个SecurityWebFilterChain,用于授权和认证请求。 其中,我们允许/auth/**下的所有请求不需要认证,OPTIONS请求也不需要认证。其他请求都需要进行认证。
### 3.配置Gateway
在Gateway中配置Spring Security,如下所示:
```java
@Configuration
public class GatewayConfig {
@Autowired
private AuthenticationManager authenticationManager;
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http.authorizeExchange()
.pathMatchers("/auth/**").permitAll()
.pathMatchers(HttpMethod.OPTIONS).permitAll()
.anyExchange().authenticated()
.and()
.httpBasic().and()
.formLogin();
return http.build();
}
@Bean
public ReactiveAuthenticationManager reactiveAuthenticationManager() {
UserDetailsRepositoryReactiveAuthenticationManager authenticationManager =
new UserDetailsRepositoryReactiveAuthenticationManager(userDetailsService());
authenticationManager.setPasswordEncoder(passwordEncoder());
return authenticationManager;
}
@Bean
public ReactiveUserDetailsService userDetailsService() {
return new MapReactiveUserDetailsService(
User.withUsername("user")
.password(passwordEncoder().encode("password"))
.roles("USER")
.build()
);
}
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Bean
public SecurityContextRepository securityContextRepository() {
return new WebSessionServerSecurityContextRepository();
}
@Bean
public ServerAuthenticationSuccessHandler serverAuthenticationSuccessHandler() {
return new RedirectServerAuthenticationSuccessHandler("/index");
}
@Bean
public ServerAuthenticationFailureHandler serverAuthenticationFailureHandler() {
return new RedirectServerAuthenticationFailureHandler("/login?error");
}
@Bean
public ServerLogoutSuccessHandler serverLogoutSuccessHandler() {
return new RedirectServerLogoutSuccessHandler("/login");
}
@Bean
public ServerSecurityContextRepository serverSecurityContextRepository() {
return new WebSessionServerSecurityContextRepository();
}
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http
.csrf().disable()
.httpBasic().disable()
.formLogin().disable()
.logout().disable()
.authenticationManager(authenticationManager)
.securityContextRepository(securityContextRepository())
.authorizeExchange()
.pathMatchers("/auth/**").permitAll()
.anyExchange().authenticated()
.and().exceptionHandling()
.authenticationEntryPoint(new HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED))
.accessDeniedHandler(new HttpStatusServerAccessDeniedHandler(HttpStatus.FORBIDDEN))
.and().addFilterAt(new AuthenticationWebFilter(reactiveAuthenticationManager()), SecurityWebFiltersOrder.AUTHENTICATION)
.addFilterAt(new SecurityContextServerWebExchangeConfigurer(serverSecurityContextRepository()), SecurityWebFiltersOrder.SECURITY_CONTEXT)
.addFilterAt(new LogoutWebFilter(serverLogoutSuccessHandler()), SecurityWebFiltersOrder.LOGOUT)
.addFilterAt(new GatewayAuthFilter(), SecurityWebFiltersOrder.AUTHENTICATION)
.addFilterAt(new GatewayRateLimitFilter(), SecurityWebFiltersOrder.AUTHENTICATION);
return http.build();
}
}
```
上述代码中,我们配置了一个GatewayAuthFilter,用于验证请求的token是否有效,以及一个GatewayRateLimitFilter,用于限流。
### 4.编写GatewayAuthFilter
在GatewayAuthFilter中编写登录鉴权逻辑,如下所示:
```java
@Component
public class GatewayAuthFilter extends OncePerRequestFilter {
private static final String JWT_SECRET = "secret";
private static final long JWT_EXPIRE_TIME = 3600 * 1000; // 1 hour
@Override
protected void doFilterInternal(ServerHttpRequest request, ServerHttpResponse response, FilterChain filterChain) throws ServletException, IOException {
String token = request.getHeaders().getFirst("Authorization");
if (StringUtils.isNotEmpty(token) && token.startsWith("Bearer ")) {
token = token.substring(7);
try {
Jws<Claims> jwt = Jwts.parser().setSigningKey(JWT_SECRET).parseClaimsJws(token);
Claims claims = jwt.getBody();
String username = claims.getSubject();
if (StringUtils.isNotEmpty(username)) {
List<String> authorities = (List<String>) claims.get("authorities");
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, null, authorities.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
} catch (Exception e) {
// ignore
}
}
filterChain.doFilter(request, response);
}
public static String generateToken(String username, List<String> authorities) {
long now = System.currentTimeMillis();
return Jwts.builder()
.setSubject(username)
.claim("authorities", authorities)
.setIssuedAt(new Date(now))
.setExpiration(new Date(now + JWT_EXPIRE_TIME))
.signWith(SignatureAlgorithm.HS512, JWT_SECRET)
.compact();
}
}
```
上述代码中,我们编写了一个GatewayAuthFilter,用于验证请求的token是否有效。如果token有效,则设置用户的权限信息,并将用户信息保存在SecurityContextHolder中。
### 5.编写GatewayRateLimitFilter
在GatewayRateLimitFilter中编写限流逻辑,如下所示:
```java
@Component
public class GatewayRateLimitFilter extends AbstractGatewayFilterFactory<GatewayRateLimitFilter.Config> {
private final RateLimiter rateLimiter;
public GatewayRateLimitFilter(RateLimiter rateLimiter) {
super(Config.class);
this.rateLimiter = rateLimiter;
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
if (!rateLimiter.tryAcquire()) {
exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
};
}
public static class Config {
}
}
```
上述代码中,我们编写了一个GatewayRateLimitFilter,用于限流。我们使用了Google的Guava库中的RateLimiter进行限流。
### 6.测试
现在,我们已经完成了SpringCloud Gateway 集成SpringSecurity 的代码编写。我们可以启动应用程序并进行测试。首先,我们需要生成一个token,然后将其添加到Authorization头中,如下所示:
```bash
curl -X POST -d "username=user&password=password" http://localhost:8080/auth/login
# {"token":"eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ1c2VyIiwidXNlcl9uYW1lIjoidXNlciIsImF1dGhvcml0aWVzIjpbIlVTRVIiXSwiaWF0IjoxNjIzMjU4NTM5LCJleHAiOjE2MjMyNjI5MzksImp0aSI6ImM2YjMxYjU2LWY5ZjktNDIwOS04ZjU1LWYyY2E3ZjkwMWYxYyJ9.C9y2vBZ5qM0C2xL8lG24Lj5r5y-1o6wHqxJlC6BhYt8L4jZr2WJWvZb5vz7VQZbC7H7t0l2SJRn9y5kYJ4IBw"}
```
然后,我们可以测试请求,如下所示:
```bash
curl -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ1c2VyIiwidXNlcl9uYW1lIjoidXNlciIsImF1dGhvcml0aWVzIjpbIlVTRVIiXSwiaWF0IjoxNjIzMjU4NTM5LCJleHAiOjE2MjMyNjI5MzksImp0aSI6ImM2YjMxYjU2LWY5ZjktNDIwOS04ZjU1LWYyY2E3ZjkwMWYxYyJ9.C9y2vBZ5qM0C2xL8lG24Lj5r5y-1o6wHqxJlC6BhYt8L4jZr2WJWvZb5vz7VQZbC7H7t0l2SJRn9y5kYJ4IBw" http://localhost:8080/hello
```
如果请求成功,则可以看到返回的结果。如果请求失败,则可以看到错误信息。
阅读全文
相关推荐

















