Spring AmazonS3 客户端序列化错误
Spring serialization error for AmazonS3 client
我遇到了一个我无法真正理解的奇怪问题。
我有一个代码可以使用 AmazonS3 客户端将文件上传到 AWS S3 存储桶。我有一个 try-catch 块,我在其中捕获任何异常,在 catch 块中,我抛出了我定义的异常,该异常由控制器方法 @ExceptionHandler 处理并且应该 return thymeleaf 模板 errorUpload.html.
@Service
public class UploadService {
private final AmazonS3 amazonS3;
private final String bucketName;
public UploadService(AmazonS3 amazonS3, @Value("${aws.bucketName}") String bucketName) {
this.amazonS3 = amazonS3;
this.bucketName = bucketName;
}
public void manualUpload(MultipartFile file) {
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(file.getContentType());
metadata.setContentLength(file.getSize());
try {
amazonS3.putObject(new PutObjectRequest(bucketName, file.getName(), file.getInputStream(), metadata));
} catch (Exception e) {
throw new UploadException(e.getMessage());
}
}
}
异常处理程序:
@ExceptionHandler({UploadException.class})
public String uploadError() {
return "errorPages/errorUpload";
}
当我在没有任何逻辑的情况下简单地在 manualUpload 方法中抛出异常时,它工作正常。但是,当使用 AmazonS3 对象并抛出异常时,逻辑会转到 ExceptionHandler,但会出现以下错误:
org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.Object] to type [byte[]] for value 'com.amazonaws.services.s3.AmazonS3Client@4b0ac28c'; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.amazonaws.services.s3.AmazonS3Client]
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47) ~[spring-core-5.3.9.jar:5.3.9]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:192) ~[spring-core-5.3.9.jar:5.3.9]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository.serialize(JdbcIndexedSessionRepository.java:623) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository.access0(JdbcIndexedSessionRepository.java:133) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository.setValues(JdbcIndexedSessionRepository.java:487) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.jdbc.core.JdbcTemplate.lambda$batchUpdate(JdbcTemplate.java:1042) ~[spring-jdbc-5.3.9.jar:5.3.9]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:651) ~[spring-jdbc-5.3.9.jar:5.3.9]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:691) ~[spring-jdbc-5.3.9.jar:5.3.9]
at org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:1034) ~[spring-jdbc-5.3.9.jar:5.3.9]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository.insertSessionAttributes(JdbcIndexedSessionRepository.java:479) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository.access00(JdbcIndexedSessionRepository.java:133) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository$JdbcSession.lambda$save(JdbcIndexedSessionRepository.java:854) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.transaction.support.TransactionOperations.lambda$executeWithoutResult[=13=](TransactionOperations.java:68) ~[spring-tx-5.3.9.jar:5.3.9]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.3.9.jar:5.3.9]
at org.springframework.transaction.support.TransactionOperations.executeWithoutResult(TransactionOperations.java:67) ~[spring-tx-5.3.9.jar:5.3.9]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository$JdbcSession.save(JdbcIndexedSessionRepository.java:836) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository$JdbcSession.access0(JdbcIndexedSessionRepository.java:665) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository.save(JdbcIndexedSessionRepository.java:422) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository.save(JdbcIndexedSessionRepository.java:133) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:226) ~[spring-session-core-2.5.1.jar:2.5.1]
at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access0(SessionRepositoryFilter.java:193) ~[spring-session-core-2.5.1.jar:2.5.1]
at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:145) ~[spring-session-core-2.5.1.jar:2.5.1]
at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:82) ~[spring-session-core-2.5.1.jar:2.5.1]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:103) ~[spring-web-5.3.9.jar:5.3.9]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:711) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:461) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:385) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:313) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:398) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:257) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:352) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:177) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1723) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at java.base/java.lang.Thread.run(Thread.java:831) ~[na:na]
Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.amazonaws.services.s3.AmazonS3Client]
at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:64) ~[spring-core-5.3.9.jar:5.3.9]
at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:33) ~[spring-core-5.3.9.jar:5.3.9]
at org.springframework.core.convert.support.GenericConversionService$ConverterAdapter.convert(GenericConversionService.java:386) ~[spring-core-5.3.9.jar:5.3.9]
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41) ~[spring-core-5.3.9.jar:5.3.9]
... 47 common frames omitted
Caused by: java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.amazonaws.services.s3.AmazonS3Client]
at org.springframework.core.serializer.DefaultSerializer.serialize(DefaultSerializer.java:43) ~[spring-core-5.3.9.jar:5.3.9]
at org.springframework.core.serializer.Serializer.serializeToByteArray(Serializer.java:56) ~[spring-core-5.3.9.jar:5.3.9]
at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:60) ~[spring-core-5.3.9.jar:5.3.9]
... 50 common frames omitted
我认为这可能与将 SPRING_SECURITY_CONTEXT 存储在 spring_session_attributes table 中有关,因此由于 AmazonS3 未序列化,因此会引发该错误。知道如何解决这个问题吗?
错误确实很奇怪。在我看来,您正在为 Java (https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3), so I would suggest you updating it to the new version (https://mvnrepository.com/artifact/software.amazon.awssdk/s3) 使用旧版本的 AWS SDK 并检查问题是否仍然存在。
有关更多详细信息,请查看有关如何迁移的 AWS 文档 https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration.html。
我找到了解决办法。
任何不可序列化的对象都不能创建为 bean 并使用,因为在这种情况下,当这个特定的 bean 将存储在 SPRING_SECURITY_CONTEXT 中时,会发生序列化异常。
因此,解决方案不是简单地创建 Bean,而是在我们想要使用它时使用“new”关键字创建对象。
@Service
public class UploadService {
private final String bucketName;
private final S3Client s3Client;
public UploadService(@Value("${aws.bucketName}") String bucketName,
@Value("${aws.accessKey}") String awsAccessKey,
@Value("${aws.secretKey}") String awsSecretKey) {
this.s3Client = S3Client.builder()
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(awsAccessKey, awsSecretKey)))
.region(Region.US_EAST_1)
.build();
this.bucketName = bucketName;
}
public void manualUpload(MultipartFile file) {
try {
s3Client.putObject(PutObjectRequest.builder().bucket(bucketName).key(file.getName()).build(),
RequestBody.fromBytes(file.getBytes()));
} catch (Exception e) {
throw new UploadException(e.getMessage());
}
}
}
我遇到了一个我无法真正理解的奇怪问题。
我有一个代码可以使用 AmazonS3 客户端将文件上传到 AWS S3 存储桶。我有一个 try-catch 块,我在其中捕获任何异常,在 catch 块中,我抛出了我定义的异常,该异常由控制器方法 @ExceptionHandler 处理并且应该 return thymeleaf 模板 errorUpload.html.
@Service
public class UploadService {
private final AmazonS3 amazonS3;
private final String bucketName;
public UploadService(AmazonS3 amazonS3, @Value("${aws.bucketName}") String bucketName) {
this.amazonS3 = amazonS3;
this.bucketName = bucketName;
}
public void manualUpload(MultipartFile file) {
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(file.getContentType());
metadata.setContentLength(file.getSize());
try {
amazonS3.putObject(new PutObjectRequest(bucketName, file.getName(), file.getInputStream(), metadata));
} catch (Exception e) {
throw new UploadException(e.getMessage());
}
}
}
异常处理程序:
@ExceptionHandler({UploadException.class})
public String uploadError() {
return "errorPages/errorUpload";
}
当我在没有任何逻辑的情况下简单地在 manualUpload 方法中抛出异常时,它工作正常。但是,当使用 AmazonS3 对象并抛出异常时,逻辑会转到 ExceptionHandler,但会出现以下错误:
org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.Object] to type [byte[]] for value 'com.amazonaws.services.s3.AmazonS3Client@4b0ac28c'; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.amazonaws.services.s3.AmazonS3Client]
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47) ~[spring-core-5.3.9.jar:5.3.9]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:192) ~[spring-core-5.3.9.jar:5.3.9]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository.serialize(JdbcIndexedSessionRepository.java:623) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository.access0(JdbcIndexedSessionRepository.java:133) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository.setValues(JdbcIndexedSessionRepository.java:487) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.jdbc.core.JdbcTemplate.lambda$batchUpdate(JdbcTemplate.java:1042) ~[spring-jdbc-5.3.9.jar:5.3.9]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:651) ~[spring-jdbc-5.3.9.jar:5.3.9]
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:691) ~[spring-jdbc-5.3.9.jar:5.3.9]
at org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:1034) ~[spring-jdbc-5.3.9.jar:5.3.9]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository.insertSessionAttributes(JdbcIndexedSessionRepository.java:479) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository.access00(JdbcIndexedSessionRepository.java:133) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository$JdbcSession.lambda$save(JdbcIndexedSessionRepository.java:854) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.transaction.support.TransactionOperations.lambda$executeWithoutResult[=13=](TransactionOperations.java:68) ~[spring-tx-5.3.9.jar:5.3.9]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.3.9.jar:5.3.9]
at org.springframework.transaction.support.TransactionOperations.executeWithoutResult(TransactionOperations.java:67) ~[spring-tx-5.3.9.jar:5.3.9]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository$JdbcSession.save(JdbcIndexedSessionRepository.java:836) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository$JdbcSession.access0(JdbcIndexedSessionRepository.java:665) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository.save(JdbcIndexedSessionRepository.java:422) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.session.jdbc.JdbcIndexedSessionRepository.save(JdbcIndexedSessionRepository.java:133) ~[spring-session-jdbc-2.5.1.jar:2.5.1]
at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:226) ~[spring-session-core-2.5.1.jar:2.5.1]
at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access0(SessionRepositoryFilter.java:193) ~[spring-session-core-2.5.1.jar:2.5.1]
at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:145) ~[spring-session-core-2.5.1.jar:2.5.1]
at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:82) ~[spring-session-core-2.5.1.jar:2.5.1]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:103) ~[spring-web-5.3.9.jar:5.3.9]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:711) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:461) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:385) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:313) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:398) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:257) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:352) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:177) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1723) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.50.jar:9.0.50]
at java.base/java.lang.Thread.run(Thread.java:831) ~[na:na]
Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.amazonaws.services.s3.AmazonS3Client]
at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:64) ~[spring-core-5.3.9.jar:5.3.9]
at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:33) ~[spring-core-5.3.9.jar:5.3.9]
at org.springframework.core.convert.support.GenericConversionService$ConverterAdapter.convert(GenericConversionService.java:386) ~[spring-core-5.3.9.jar:5.3.9]
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41) ~[spring-core-5.3.9.jar:5.3.9]
... 47 common frames omitted
Caused by: java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.amazonaws.services.s3.AmazonS3Client]
at org.springframework.core.serializer.DefaultSerializer.serialize(DefaultSerializer.java:43) ~[spring-core-5.3.9.jar:5.3.9]
at org.springframework.core.serializer.Serializer.serializeToByteArray(Serializer.java:56) ~[spring-core-5.3.9.jar:5.3.9]
at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:60) ~[spring-core-5.3.9.jar:5.3.9]
... 50 common frames omitted
我认为这可能与将 SPRING_SECURITY_CONTEXT 存储在 spring_session_attributes table 中有关,因此由于 AmazonS3 未序列化,因此会引发该错误。知道如何解决这个问题吗?
错误确实很奇怪。在我看来,您正在为 Java (https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3), so I would suggest you updating it to the new version (https://mvnrepository.com/artifact/software.amazon.awssdk/s3) 使用旧版本的 AWS SDK 并检查问题是否仍然存在。
有关更多详细信息,请查看有关如何迁移的 AWS 文档 https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration.html。
我找到了解决办法。 任何不可序列化的对象都不能创建为 bean 并使用,因为在这种情况下,当这个特定的 bean 将存储在 SPRING_SECURITY_CONTEXT 中时,会发生序列化异常。 因此,解决方案不是简单地创建 Bean,而是在我们想要使用它时使用“new”关键字创建对象。
@Service
public class UploadService {
private final String bucketName;
private final S3Client s3Client;
public UploadService(@Value("${aws.bucketName}") String bucketName,
@Value("${aws.accessKey}") String awsAccessKey,
@Value("${aws.secretKey}") String awsSecretKey) {
this.s3Client = S3Client.builder()
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(awsAccessKey, awsSecretKey)))
.region(Region.US_EAST_1)
.build();
this.bucketName = bucketName;
}
public void manualUpload(MultipartFile file) {
try {
s3Client.putObject(PutObjectRequest.builder().bucket(bucketName).key(file.getName()).build(),
RequestBody.fromBytes(file.getBytes()));
} catch (Exception e) {
throw new UploadException(e.getMessage());
}
}
}