Spring安全和LDAP-java.io.NotSerializableException:com.sun.jndi.LDAP.LdapCtx

Spring安全和LDAP-java.io.NotSerializableException:com.sun.jndi.LDAP.LdapCtx,java,spring,spring-boot,spring-security,spring-ldap,Java,Spring,Spring Boot,Spring Security,Spring Ldap,我已经通过ActiveDirectoryLdapAuthenticationProvider将我的应用程序与LDAP集成。当我使用正确的凭据登录时,一切都正常。错误的凭据会出现此问题: org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.Not

我已经通过
ActiveDirectoryLdapAuthenticationProvider
将我的应用程序与LDAP集成。当我使用正确的凭据登录时,一切都正常。错误的凭据会出现此问题:

org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.NotSerializableException: com.sun.jndi.ldap.LdapCtx
    at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:68)
    at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:35)
    at org.springframework.session.data.mongo.JdkMongoSessionConverter.serializeAttributes(JdkMongoSessionConverter.java:105)
    at org.springframework.session.data.mongo.JdkMongoSessionConverter.convert(JdkMongoSessionConverter.java:84)
    at org.springframework.session.data.mongo.AbstractMongoSessionConverter.convert(AbstractMongoSessionConverter.java:110)
    at org.springframework.session.data.mongo.MongoOperationsSessionRepository.convertToDBObject(MongoOperationsSessionRepository.java:141)
    at org.springframework.session.data.mongo.MongoOperationsSessionRepository.save(MongoOperationsSessionRepository.java:77)
    at org.springframework.session.data.mongo.MongoOperationsSessionRepository.save(MongoOperationsSessionRepository.java:44)
    at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:245)
    at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:217)
    at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:170)
    at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:677)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.NotSerializableException: com.sun.jndi.ldap.LdapCtx
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:441)
    at java.lang.Throwable.writeObject(Throwable.java:985)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1028)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:441)
    at java.lang.Throwable.writeObject(Throwable.java:985)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1028)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
    at java.util.HashMap.internalWriteEntries(HashMap.java:1777)
    at java.util.HashMap.writeObject(HashMap.java:1354)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1028)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
    at org.springframework.core.serializer.DefaultSerializer.serialize(DefaultSerializer.java:46)
    at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:63)
    ... 38 common frames omitted
我收到的是500而不是登录页面上的消息。登录页面由Spring Security生成

我使用
@EnableMongoHttpSession
JdkMongoSessionConverter
用作
AbstractMongoSessionConverter
的实现

我知道问题在于序列化
LdapCtx
,但我如何处理它?我的意思是简单地捕捉异常,并在登录页面上显示类似“错误凭证”的消息

Spring安全配置:

package xxx;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${spring.security.role.name}")
    private String roleName;

    @Autowired
    private AuthenticationProvider provider;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/app/**").fullyAuthenticated()
                .antMatchers("/operations/**").hasAuthority(roleName)
                .anyRequest().permitAll()
                .and()
                .formLogin()
                .loginProcessingUrl("/login");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(provider);
    }

    @Bean
    @Profile("dev-tests")
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(devUserDetailsService());
        ShaPasswordEncoder passwordEncoder = new ShaPasswordEncoder(1);
        authenticationProvider.setPasswordEncoder(passwordEncoder);
        return authenticationProvider;
    }

    @Bean
    @ConditionalOnMissingBean(AuthenticationProvider.class)
    public AuthenticationProvider ldapAuthenticationProvider() {
        ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(
                "****",
                "ldaps://****:3269",
                "OU=****,DC=****,DC=****,DC=****"
        );
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setSearchFilter("(&(objectClass=userProxy)(userPrincipalName={0}))");
        return provider;
    }

    private UserDetailsService devUserDetailsService() {
        List<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority(roleName));
        authorities.add(new SimpleGrantedAuthority("ROLE_ACTUATOR"));

        Collection<UserDetails> users = new ArrayList<>();
        users.add(new User("admin", "d033e22ae348aeb5660fc2140aec35850c4da997", authorities)); //pass: admin
        users.add(new User("read", "a7afddb68260a60f86c02a021efba7f216c2e7cf", new ArrayList<>())); //pass: read
        return new InMemoryUserDetailsManager(users);
    }

}
package xxxxx;

import xxxxx.SpringDataEnvServiceVersionRepository;
import com.mongodb.Mongo;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.core.convert.CustomConversions;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.session.data.mongo.JdkMongoSessionConverter;
import org.springframework.session.data.mongo.config.annotation.web.http.EnableMongoHttpSession;

import java.time.Instant;
import java.time.LocalDate;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static java.time.ZoneOffset.UTC;
import static java.time.ZonedDateTime.ofInstant;

@Configuration
@EnableMongoRepositories(
        basePackages = {"****"},
        basePackageClasses = {SpringDataEnvServiceVersionRepository.class})
@EnableMongoHttpSession(collectionName = "****")
public class MongoConfiguration extends AbstractMongoConfiguration {

    @Value("${spring.data.mongodb.uri}")
    private String uri;

    @Override
    protected String getDatabaseName() {
        return new MongoClientURI(uri).getDatabase();
    }

    @Bean
    @Override
    public Mongo mongo() {
        return new MongoClient(new MongoClientURI(uri));
    }

    @Bean
    public JdkMongoSessionConverter jdkMongoSessionConverter() {
        return new JdkMongoSessionConverter();
    }

    @Bean
    @Override
    public CustomConversions customConversions() {
        List<Converter> list = new ArrayList<>();
        list.add(new DateToZonedDateTimeConverter());
        list.add(new ZonedDateTimeToDateConverter());
        list.add(new LocalDateToDateConverter());
        list.add(new DateToLocalDateConverter());
        list.add(new StringToZonedDateTimeConverter());
        return new CustomConversions(list);
    }

    private static class DateToZonedDateTimeConverter implements Converter<Date, ZonedDateTime> {
        @Override
        public ZonedDateTime convert(Date source) {
            return source == null ? null : ofInstant(source.toInstant(), UTC);
        }
    }

    private static class ZonedDateTimeToDateConverter implements Converter<ZonedDateTime, Date> {
        @Override
        public Date convert(ZonedDateTime source) {
            return source == null ? null : Date.from(source.toInstant());
        }
    }

    private static class LocalDateToDateConverter implements Converter<LocalDate, Date> {
        @Override
        public Date convert(LocalDate source) {
            return Date.from(source.atStartOfDay(UTC).toInstant());
        }
    }

    private static class DateToLocalDateConverter implements Converter<Date, LocalDate> {
        @Override
        public LocalDate convert(Date source) {
            return Instant.ofEpochMilli(source.getTime()).atZone(UTC).toLocalDate();
        }
    }

    private static class StringToZonedDateTimeConverter implements Converter<String, ZonedDateTime> {

        @Override
        public ZonedDateTime convert(String s) {
            return s == null ? null : ZonedDateTime.parse(s);
        }
    }

}
xxx包;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.beans.factory.annotation.Value;
导入org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
导入org.springframework.context.annotation.Bean;
导入org.springframework.context.annotation.Configuration;
导入org.springframework.context.annotation.Profile;
导入org.springframework.security.authentication.AuthenticationProvider;
导入org.springframework.security.authentication.dao.DaoAuthenticationProvider;
导入org.springframework.security.authentication.encoding.ShaPasswordEncoder;
导入org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
导入org.springframework.security.config.annotation.web.builders.HttpSecurity;
导入org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
导入org.springframework.security.config.annotation.web.configuration.websecurityConfigureAdapter;
导入org.springframework.security.core.GrantedAuthority;
导入org.springframework.security.core.authority.SimpleGrantedAuthority;
导入org.springframework.security.core.userdetails.User;
导入org.springframework.security.core.userdetails.userdetails;
导入org.springframework.security.core.userdetails.userdetails服务;
导入org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider;
导入org.springframework.security.provisioning.InMemoryUserDetailsManager;
导入java.util.ArrayList;
导入java.util.Collection;
导入java.util.List;
@配置
@启用Web安全性
公共类SecurityConfig扩展了WebSecurity配置适配器{
@值(${spring.security.role.name})
私有字符串roleName;
@自动连线
私有身份验证提供者;
@凌驾
受保护的无效配置(HttpSecurity http)引发异常{
http
.csrf().disable()
.授权请求()
.antMatchers(“/app/**”).fullyaauthenticated()
.antMatchers(“/operations/**”).hasAuthority(roleName)
.anyRequest().permitAll()
.及()
.formLogin()
.loginProcessingUrl(“/login”);
}
@凌驾
受保护的无效配置(AuthenticationManagerBuilder auth)引发异常{
身份验证提供者(提供者);
}
@豆子
@概要(“开发测试”)
公共AuthenticationProvider AuthenticationProvider(){
DaoAuthenticationProvider authenticationProvider=新的DaoAuthenticationProvider();
setUserDetailsService(devUserDetailsService());
ShaPasswordEncoder passwordEncoder=新的ShaPasswordEncoder(1);
setPasswordEncoder(passwordEncoder);
返回authenticationProvider;
}
@豆子
@ConditionalOnMissingBean(AuthenticationProvider.class)
公共身份验证提供程序ldapAuthenticationProvider(){
ActiveDirectoryLdapAuthenticationProvider=新的ActiveDirectoryLdapAuthenticationProvider(
"****",
“ldaps://**:3269”,
OU=**,DC=**,DC=**,DC=**,DC=**
);
provider.setConvertSubErrorCodesToExceptions(true);
setSearchFilter((&(objectClass=userProxy)(userPrincipalName={0}));
退货供应商;
}
私有用户详细信息服务devuser详细信息服务(){
列表权限=新建ArrayList();
添加(新的SimpleGrantedAuthority(roleName));
增加(新的SimpleGrantedAuthority(“角色执行机构”);
集合用户=新建ArrayList();
添加(新用户(“管理员”,“d033e22ae348aeb5660fc2140aec35850c4da997”,权限));//通过:管理员
添加(新用户(“读取”、“a7afddb68260a60f86c02a021efba7f216c2e7cf”、新ArrayList());//通过:读取
返回新的InMemoryUserDetailsManager(用户);
}
}
Mongo配置:

package xxx;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${spring.security.role.name}")
    private String roleName;

    @Autowired
    private AuthenticationProvider provider;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/app/**").fullyAuthenticated()
                .antMatchers("/operations/**").hasAuthority(roleName)
                .anyRequest().permitAll()
                .and()
                .formLogin()
                .loginProcessingUrl("/login");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(provider);
    }

    @Bean
    @Profile("dev-tests")
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(devUserDetailsService());
        ShaPasswordEncoder passwordEncoder = new ShaPasswordEncoder(1);
        authenticationProvider.setPasswordEncoder(passwordEncoder);
        return authenticationProvider;
    }

    @Bean
    @ConditionalOnMissingBean(AuthenticationProvider.class)
    public AuthenticationProvider ldapAuthenticationProvider() {
        ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(
                "****",
                "ldaps://****:3269",
                "OU=****,DC=****,DC=****,DC=****"
        );
        provider.setConvertSubErrorCodesToExceptions(true);
        provider.setSearchFilter("(&(objectClass=userProxy)(userPrincipalName={0}))");
        return provider;
    }

    private UserDetailsService devUserDetailsService() {
        List<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority(roleName));
        authorities.add(new SimpleGrantedAuthority("ROLE_ACTUATOR"));

        Collection<UserDetails> users = new ArrayList<>();
        users.add(new User("admin", "d033e22ae348aeb5660fc2140aec35850c4da997", authorities)); //pass: admin
        users.add(new User("read", "a7afddb68260a60f86c02a021efba7f216c2e7cf", new ArrayList<>())); //pass: read
        return new InMemoryUserDetailsManager(users);
    }

}
package xxxxx;

import xxxxx.SpringDataEnvServiceVersionRepository;
import com.mongodb.Mongo;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.core.convert.CustomConversions;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.session.data.mongo.JdkMongoSessionConverter;
import org.springframework.session.data.mongo.config.annotation.web.http.EnableMongoHttpSession;

import java.time.Instant;
import java.time.LocalDate;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static java.time.ZoneOffset.UTC;
import static java.time.ZonedDateTime.ofInstant;

@Configuration
@EnableMongoRepositories(
        basePackages = {"****"},
        basePackageClasses = {SpringDataEnvServiceVersionRepository.class})
@EnableMongoHttpSession(collectionName = "****")
public class MongoConfiguration extends AbstractMongoConfiguration {

    @Value("${spring.data.mongodb.uri}")
    private String uri;

    @Override
    protected String getDatabaseName() {
        return new MongoClientURI(uri).getDatabase();
    }

    @Bean
    @Override
    public Mongo mongo() {
        return new MongoClient(new MongoClientURI(uri));
    }

    @Bean
    public JdkMongoSessionConverter jdkMongoSessionConverter() {
        return new JdkMongoSessionConverter();
    }

    @Bean
    @Override
    public CustomConversions customConversions() {
        List<Converter> list = new ArrayList<>();
        list.add(new DateToZonedDateTimeConverter());
        list.add(new ZonedDateTimeToDateConverter());
        list.add(new LocalDateToDateConverter());
        list.add(new DateToLocalDateConverter());
        list.add(new StringToZonedDateTimeConverter());
        return new CustomConversions(list);
    }

    private static class DateToZonedDateTimeConverter implements Converter<Date, ZonedDateTime> {
        @Override
        public ZonedDateTime convert(Date source) {
            return source == null ? null : ofInstant(source.toInstant(), UTC);
        }
    }

    private static class ZonedDateTimeToDateConverter implements Converter<ZonedDateTime, Date> {
        @Override
        public Date convert(ZonedDateTime source) {
            return source == null ? null : Date.from(source.toInstant());
        }
    }

    private static class LocalDateToDateConverter implements Converter<LocalDate, Date> {
        @Override
        public Date convert(LocalDate source) {
            return Date.from(source.atStartOfDay(UTC).toInstant());
        }
    }

    private static class DateToLocalDateConverter implements Converter<Date, LocalDate> {
        @Override
        public LocalDate convert(Date source) {
            return Instant.ofEpochMilli(source.getTime()).atZone(UTC).toLocalDate();
        }
    }

    private static class StringToZonedDateTimeConverter implements Converter<String, ZonedDateTime> {

        @Override
        public ZonedDateTime convert(String s) {
            return s == null ? null : ZonedDateTime.parse(s);
        }
    }

}
xxxxx包;
导入xxxxx.SpringDataEnvServiceVersionRepository;
导入com.mongodb.Mongo;
导入com.mongodb.MongoClient;
导入com.mongodb.MongoClientURI;
导入org.springframework.beans.factory.annotation.Value;
导入org.springframework.context.annotation.Bean;
导入org.springframework.context.annotation.Configuration;
导入org.springframework.core.convert.converter.converter;
导入org.springframework.data.mongodb.config.AbstractMongoConfiguration;
导入org.springframework.data.mongodb.core.convert.CustomConversions;
导入org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
导入org.springframework.session.data.mongo.JdkMongoSessionConverter;
导入org.springframework.session.data.mongo.config.annotation.web.http.EnableMongoHttpSession;
导入java.time.Instant;
导入java.time.LocalDate;
导入java.time.ZonedDateTime;
导入java.util.ArrayList;
导入java.util.Date;
导入java.util.List;
导入静态java.time.ZoneOffset.UTC;
导入静态java.time.ZonedDateTime.ofInstant;
@配置
@使能性假设(
basePackages={“**”},
basePackageClasses={SpringDataEnvServiceVersionRepository.class})
@使能