我们可以使用以下curl命令将包含压缩LDIF文件的ZIP文件上传到小型Spring Boot应用程序:
curl -k -X POST -F“file=@/dev/Cservice.zip;type=application/zip” https://sag01.xxaws.com:10006/Cservice --cert /dev/axis.pem --key /gx/dev/axis.key
Spring Boot 应用程序接收 ZIPPED LDIF 文件,将其解压缩,然后根据解压缩的 LDIF 文件中的行进行一些处理。
但在某些环境中,他们没有Linux,因此无法使用Curl,所以我现在尝试实现一个powershell脚本来执行与curl命令相同的上传,我发现这个线程较旧的Stackoverflow线程(Powershell在搜索如何实现这一目标时,无法使用多部分表单数据将超过 ~50MB 的 zip 文件上传到 REST API)。
我一直在尝试使用“Ralph”在早期 SO 线程中发布的第一个 powershell 脚本,位于Powershell 无法使用多部分表单数据将 zip 文件上传到 REST API ),但针对我们的环境进行了修改(主要区别是我们使用证书身份验证)_
这是我目前在 powershell 上的尝试:
# From: https://stackoverflow.com/questions/69038508/powershell-is-unable-to-upload-zip-file-over-50mb-using-multipart-form-data-to
Write-output "RUNNING: 8from-stackoverflow.ps1"
$Uri = 'https://sag01.gxaws.com:10006/CService'
$fileBytes = [System.IO.File]::ReadAllBytes("G:\Dev\CService.zip");
$enc = [System.Text.Encoding]::GetEncoding('utf-8')
$fileEnc = $enc.GetString($fileBytes)
Invoke-WebRequest -Uri $Uri -method POST -TimeoutSec 999999 -Certificate (Get-PfxCertificate axisWithKey.pfx) -SkipCertificateCheck `
-Headers @{ "accept"="*/*"} `
-ContentType "multipart/form-data; boundary=WebKitFormBoundaryT2XycANuthCIUwGk" `
-Body ([System.Text.Encoding]::UTF8.GetBytes("--WebKitFormBoundaryT2XycANuthCIUwGk$([char]13)$([char]10)Content-Disposition: form-data; name=`"file`"; filename=`"CService.zip`"$([char]13)$([char]10)Content-Type: application/x-zip-compressed$([char]13)$([char]10)$([char]13)$([char]10))$fileEnc($([char]13)$([char]10)-- WebKitFormBoundaryT2XycANuthCIUwGk--$([char]13)$([char]10)"))
当我运行上面的 powershell 脚本时,我跟踪正在接收上传的应用程序日志,看起来 powershell 脚本正在尝试上传“CService.zip”文件,并且 Spring Boot 应用程序正在看到上传请求,我可以看到似乎是 zip 文件的二进制数据。这是 powershell 脚本运行时 ZIP 文件日志记录的开始(我希望出现下面的行):
--WebKitFormBoundaryT2XycANuthCIUwGk
Content-Disposition: form-data; name="file"; filename="CService.zip"
Content-Type: application/x-zip-compressed
�*T*�d~��tb����Z▒¿½n�no4�lÏ¢S���y~t�y�r�a��ï¿m?m�í������l�_���^^���y����
但是,在应用程序收到 ZIP 文件后,它应该解压缩内容,然后记录行,但它似乎无法做到这一点:
2024-03-14 18:12:58,048 DEBUG m.n.g.m.c.u.StringUtils [https-jsse-nio-8888-exec-2] LDIF before reMap method:
2024-03-14 18:12:58,048 DEBUG m.n.g.m.c.u.StringUtils [https-jsse-nio-8888-exec-2] LDIF after reMap method:
2024-03-14 18:12:58,048 DEBUG m.n.g.m.c.s.LDAPService [https-jsse-nio-8888-exec-2] Lidf entries count = 0
当我运行工作的 Curl 命令时,我查看了相同的服务器端应用程序日志记录,并且它输出二进制数据的日志记录看起来与我运行 powershell 脚本时完全不同。以下是运行 curl 时的日志记录片段:
2024-03-14 18:38:50,916 DEBUG o.a.j.l.DirectJDKLog [https-jsse-nio-8888-exec-9] Received [--------------------------a18e445ef02489d2^M
Content-Disposition: form-data; name="file"; filename="CService.zip"^M
Content-Type: application/zip^M
^M
PK^C^D^T^@^@^@^H^@QmuVe^XÂ<86>(^O^@^@'~^B^@^S^@^@^@CService.ldif<9a>]kT ^VEß^Cù^Où^A*u¿êC^P&¦¡q µiõa<9e><86>2Vb^M±*T*Íd~ýÜtb<8e><8c>û<84>^^Z^O^[ön<90>no4®lÏ¢S¬ú¸y~tºyñrûaòå<9f>é³^?m?m<9e>í<9e><9d>ÿûr^?^Z<8f><9f>l¯_üºÚ^^¬<9e>¼yÿâõÏÇ·ÿúiûÓ<93>7/Þ?{ûìèçíï«Ýæój³^?ròâýÛÃ<83
此外,我注意到运行 powershell 时的内容长度大约是运行 Curl 时的长度的两倍。所以我认为我一定是对 powershell 脚本中编码 ZIP 文件的部分做错了什么?或者也许 Curl 上传到 Spring Boot 应用程序可以工作,因为 Curl 正在执行不同类型的编码或其他操作?
我希望这里有人能够提供帮助,因为我已经尝试让它工作几天了,而且我觉得我离解决方案越来越远,而不是更接近,所以我决定尝试在这里发帖.
如果有任何问题,请告诉我,我会尽力回答!
提前致谢, 吉姆
编辑:这是根据 mklement0(在评论中)的建议最终起作用的:
#FROM: https://stackoverflow.com/questions/78162873/problem-trying-to-use-powershell-to-upload-a-zip-file-to-a-spring-boot-applicati
#and:
#FROM: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-7.4#example-5-submit-a-multipart-form-data-file
$FilePath = 'G:\Dev\CService.zip'
$URL = 'https://sag02.xxaws.com:10006/CService'
Write-output "ZIP File: $FilePath"
Write-output "URL: $URL"
$FieldName = 'file'
$ContentType = 'application/zip'
$FileStream = [System.IO.FileStream]::new($filePath, [System.IO.FileMode]::Open)
$FileHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new('form-data')
$FileHeader.Name = $FieldName
$FileHeader.FileName = Split-Path -leaf $FilePath
$FileContent = [System.Net.Http.StreamContent]::new($FileStream)
$FileContent.Headers.ContentDisposition = $FileHeader
$FileContent.Headers.ContentType = [System.Net.Http.Headers.MediaTypeHeaderValue]::Parse($ContentType)
$MultipartContent = [System.Net.Http.MultipartFormDataContent]::new()
$MultipartContent.Add($FileContent)
$Response = Invoke-WebRequest -Body $MultipartContent -Method POST -Uri $URL -TimeoutSec 999999 -Certificate (Get-PfxCertificate geoaxisWithKey.pfx) -SkipCertificateCheck
Write-output $Response
前言:
可能无需将您的curl
调用转换为其
Invoke-WebRequest
等效项:
curl.exe
(和
tar.exe
),因此您通常可以使用现有的
curl
命令(可能需要对 PowerShell 的语法进行小调整) - 只需确保指定可执行文件为
curl.exe
,而不仅仅是
curl
,因为后者是 Windows PowerShell 中
Invoke-WebRequest
cmdlet 的内置别名。
Invoke-WebRequest
,请继续阅读。
示例 5,该主题展示了如何以多部分/表单数据提交方式上传给定文件(无论其内容如何,包括 二进制内容):
$url = 'https://sag02.xxaws.com:10006/CService'
# Prepare the metadata of the file to upload
$filePath = 'G:\Dev\CService.zip' # Be sure to specify a *full path*.
$contentType = 'application/zip' # Identify the mediate type (file type).
# Create a content-disposition header for the file.
$fileHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new('form-data')
$fileHeader.Name = 'file' # form field name.
$fileHeader.FileName = Split-Path -Leaf $filePath # file name
# Create a stream-content object with the file's binary data
# and the content-disposition header.
$fileContent = [System.Net.Http.StreamContent]::new(
[System.IO.FileStream]::new($filePath, [System.IO.FileMode]::Open)
)
$fileContent.Headers.ContentDisposition = $fileHeader
$fileContent.Headers.ContentType = $contentType
# Create a multipart form data instance with the the stream-content object
# of the file to upload (as the only part).
$multiPartContent = [System.Net.Http.MultipartFormDataContent]::new()
$multiPartContent.Add($fileContent)
# Call Invoke-WebRequest with the multipart form data as the -Body argument.
$response =
Invoke-WebRequest -Body $multiPartContent -Method POST -Uri $url -TimeoutSec 999999 -Certificate (Get-PfxCertificate geoaxisWithKey.pfx) -SkipCertificateCheck
# Output the response.
$response