18-out输出和response.getWrite输出的区别

本文详细解析了在JSP中out.write()和response.getWriter().write()的区别。尽管二者都能用于输出内容,但在实际使用中,推荐统一使用out.print()以确保页面内容的正确顺序。示例代码展示了两种方法的输出效果,并指出out.print()能处理任意类型数据并自动转换为字符串。

out输出response.getWrite输出的区别

代码演示

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
<%
  out.write("out输出1 <br>");
  out.flush();
  out.write("out输出2 <br>");
  response.getWriter().write("response输出1 <br>");
  response.getWriter().write("response输出2 <br>");
  /*out输出1
  response输出1
  response输出2
  out输出2*/
%>

  </body>
</html>


图解

在这里插入图片描述

out.write()和out.print()区别

由于jsp翻译之后,底层源码都是使用out来进行输出,所以一般情况下,我们在jsp页面统一使用out来进行输出。避免打乱页面输出内容的顺序

<%
  out.write(12);//
  out.print(12);//12
%>

<%--
    out.write()  输出字符串没有问题
    out.print()	 输出任意数据都没有问题(都转换成为字符串后调用的write输出)
    --%>

结论:在jsp页面中,可以统一使用 out.print() 来进行输出

你看看这两个版本“function Invoke-CurlRequest { [CmdletBinding()] param( [Parameter(Mandatory=$true, Position=0)] [string]$Url, [string]$Method = "GET", [hashtable]$Headers = @{}, [string]$Body, [string]$ContentType = "application/json", [ValidateSet("Raw", "Object")] [string]$OutputType = "Raw", [switch]$IncludeHeaders, [switch]$FollowRedirect, [int]$MaxRedirects = 10, [int]$Timeout = 0, [string]$OutputFile, [switch]$Insecure ) # 保存原始语言环境 $originalLang = $env:LANG $originalLC_ALL = $env:LC_ALL # 初始化响应对象 $response = [PSCustomObject]@{ Status = $null Content = $null Data = $null ErrorMessage = $null ErrorType = $null Url = $Url Method = $Method StatusCode = $null Headers = $null Latency = $null Size = $null Timestamp = (Get-Date) RawOutput = $null } # 内部辅助函数:提取curl错误信息 function ExtractCurlError([string]$content) { if ($content -match 'curl: \(\d+\) (.*)') { return $matches[1] } return $content } # 内部辅助函数:提取API错误信息 function ExtractApiError($responseData) { # 尝试从常见结构中提取错误信息 $errorKeys = @("error", "message", "detail", "description", "error_message") foreach ($key in $errorKeys) { if ($null -ne $responseData -and $responseData.PSObject.Properties.Name -contains $key) { $errorValue = $responseData.$key if ($errorValue -is [string]) { return $errorValue } elseif ($errorValue -is [psobject]) { return ($errorValue | Format-List | Out-String).Trim() } } } # 没有找到特定错误字段,返回整个响应 if ($null -ne $responseData) { return ($responseData | Format-List | Out-String).Trim() } return "Unknown API error" } # 计时器开始 $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() try { # 设置英文环境防止乱码 $env:LANG = 'C' $env:LC_ALL = 'C' # URL安全处理:包含空格时添加引号 $safeUrl = if ($Url -match '\s') { "`"$Url`"" } else { $Url } # 构建 curl 命令参数 $curlArgs = @( $safeUrl, # 使用安全处理的URL "-X", $Method, "--silent", "--show-error" ) # 添加可选参数 if ($IncludeHeaders) { $curlArgs += "-i" } if ($FollowRedirect) { $curlArgs += "-L" $curlArgs += "--max-redirs" $curlArgs += $MaxRedirects } if ($Timeout -gt 0) { $curlArgs += "--connect-timeout" $curlArgs += [math]::Ceiling($Timeout/2) $curlArgs += "--max-time" $curlArgs += $Timeout } if ($Insecure) { Write-Warning "SSL certificate validation disabled - security risk!" $curlArgs += "--insecure" } # 添加默认User-Agent if (-not $Headers.ContainsKey('User-Agent')) { $Headers['User-Agent'] = "PowerShell-CurlTools/1.0" } # 添加内容类型头 if (-not $Headers.ContainsKey("Content-Type") -and $Body) { $Headers["Content-Type"] = $ContentType } # 添加请求头(安全引号处理) foreach ($key in $Headers.Keys) { $headerValue = $Headers[$key] $curlArgs += "-H" $curlArgs += "`"$key`: $headerValue`"" } # 添加请求体 if ($Body) { $curlArgs += "-d" $curlArgs += $Body } Write-Verbose "Executing curl: $($curlArgs -join ' ')" # 特殊处理文件输出 if ($OutputFile) { # 确保输出目录存在 $outputDir = Split-Path $OutputFile -Parent if (-not [string]::IsNullOrWhiteSpace($outputDir) -and -not (Test-Path $outputDir)) { New-Item -ItemType Directory -Path $outputDir -Force | Out-Null } # 直接保存到文件 $fileArgs = $curlArgs + @("-o", $OutputFile) $process = Start-Process curl.exe -ArgumentList $fileArgs -NoNewWindow -PassThru -Wait $curlExitCode = $process.ExitCode if ($curlExitCode -eq 0 -and (Test-Path $OutputFile)) { $response.Status = "Success" $response.Content = "File saved successfully" $response.Size = (Get-Item $OutputFile).Length $response.StatusCode = 200 } else { $response.Status = "Error" $response.ErrorMessage = "File save failed (exit $curlExitCode)" $response.StatusCode = 0 } return $response } # 执行 curl 命令(非文件模式) $output = curl.exe @curlArgs 2>&1 $curlExitCode = $LASTEXITCODE # 处理输出编码(防乱码) $rawOutput = if ($null -ne $output) { if ($output -is [array]) { $output -join "`n" } else { $output.ToString() } } else { "" } $response.RawOutput = $rawOutput $response.Latency = $stopwatch.ElapsedMilliseconds # 处理 curl 错误 if ($curlExitCode -ne 0) { $response.Status = "Error" $response.ErrorMessage = ExtractCurlError $rawOutput $response.Content = $rawOutput $response.ErrorType = switch ($curlExitCode) { 6 { "DNSResolutionFailed" } 7 { "ConnectionFailed" } 28 { "Timeout" } default { "CurlError" } } $response.StatusCode = 0 # 明确设置为0表示网络错误 return $response } # 记录响应大小 $response.Size = $rawOutput.Length # 分离响应头内容 $headerSection = $null $responseBody = $rawOutput $statusCode = 0 # 增强头部分离逻辑 if ($IncludeHeaders -or $rawOutput -match '^HTTP/') { # 尝试不同换行符查找头部结束位置 $lineEndings = @("`r`n`r`n", "`n`n", "`r`r") $headerEnd = $null foreach ($ending in $lineEndings) { $pos = $rawOutput.IndexOf($ending) if ($pos -gt -1) { $headerEnd = $pos break } } # 分离头部主体 if ($null -ne $headerEnd -and $headerEnd -gt 0) { $headerSection = $rawOutput.Substring(0, $headerEnd) $responseBody = $rawOutput.Substring($headerEnd + $ending.Length) # 解析状态码 if ($headerSection -match 'HTTP/\d+\.\d+\s+(\d{3})') { $statusCode = [int]$matches[1] } # 解析响应头 $response.Headers = @{} $headerLines = $headerSection -split "`r`n|`n" foreach ($line in $headerLines) { if ($line -match '^([^:]+):\s*(.+)') { $response.Headers[$matches[1]] = $matches[2].Trim() } } } } # 设置状态码 $response.StatusCode = $statusCode # 设置响应状态 if ($statusCode -ge 400) { $response.Status = "Error" } elseif ($statusCode -eq 204) { $response.Status = "NoContent" } else { $response.Status = "Success" } # 处理空响应 if ([string]::IsNullOrWhiteSpace($responseBody) -and $statusCode -eq 204) { $response.Content = "" return $response } # 原始输出模式 if ($OutputType -eq "Raw") { $response.Content = $rawOutput return $response } # 对象模式 - 尝试解析JSON $response.Content = $responseBody try { $parsedData = $responseBody | ConvertFrom-Json -ErrorAction Stop # 智能提取嵌套数据 if ($parsedData.PSObject.Properties.Name -contains "json") { $response.Data = $parsedData.json } elseif ($parsedData.PSObject.Properties.Name -contains "data") { try { $response.Data = $parsedData.data | ConvertFrom-Json } catch { $response.Data = $parsedData.data } } else { $response.Data = $parsedData } # 如果是错误响应,提取错误信息 if ($response.Status -eq "Error") { $response.ErrorMessage = ExtractApiError $response.Data } return $response } catch { # 非JSON响应 if ($response.Status -eq "Success") { $response.Status = "NonJsonResponse" } # 智能检测内容类型 if ($responseBody -match '<!DOCTYPE html>') { $response.Headers['Content-Type'] = 'text/html' } elseif ($responseBody -match '^{') { $response.Headers['Content-Type'] = 'application/json' } elseif (-not $response.Headers['Content-Type']) { $response.Headers['Content-Type'] = 'text/plain' } # 如果是错误响应,设置错误信息 if ($response.Status -eq "Error") { $response.ErrorMessage = "Non-JSON error response" } return $response } } catch { $response.Status = "Error" $response.ErrorMessage = $_.Exception.Message $response.Content = $_.Exception.Message return $response } finally { # 恢复原始语言环境 $env:LANG = $originalLang $env:LC_ALL = $originalLC_ALL $stopwatch.Stop() } } # 导出模块函数 Export-ModuleMember -Function Invoke-CurlRequest” “function Invoke-CurlRequest { [CmdletBinding()] param( # ...现有参数保持不变... # 新增重试参数 [int]$RetryCount = 0, [int]$RetryInterval = 1, [int[]]$RetryOnStatusCodes = @(408, 429, 500, 502, 503, 504), [switch]$RetryOnTimeout ) # ...现有变量初始化... # 重试计数器 $attempt = 0 $success = $false do { $attempt++ try { # ...现有curl执行逻辑... # 检查是否需要重试 $shouldRetry = $false # 网络错误重试 (curl错误码) if ($response.ErrorType -in @("ConnectionFailed", "Timeout", "DNSResolutionFailed")) { $shouldRetry = $true Write-Verbose "网络错误重试 ($attempt/$RetryCount): $($response.ErrorType)" } # HTTP状态码重试 elseif ($response.StatusCode -in $RetryOnStatusCodes) { $shouldRetry = $true Write-Verbose "HTTP错误重试 ($attempt/$RetryCount): $($response.StatusCode)" } # 超时重试 elseif ($RetryOnTimeout -and $response.ErrorType -eq "Timeout") { $shouldRetry = $true Write-Verbose "超时重试 ($attempt/$RetryCount)" } # 成功执行 if (-not $shouldRetry) { $success = $true return $response } # 指数退避算法 if ($attempt -le $RetryCount) { $waitTime = $RetryInterval * [math]::Pow(2, $attempt - 1) $jitter = Get-Random -Minimum 0 -Maximum ($waitTime * 0.2) # 20%抖动 $totalWait = [math]::Ceiling($waitTime + $jitter) Write-Verbose "等待 ${totalWait}s 后重试 (尝试 $attempt/$RetryCount)" Start-Sleep -Seconds $totalWait } } catch { # 非预期异常处理 if ($attempt -gt $RetryCount) { $response.Status = "FatalError" $response.ErrorMessage = "重试后仍失败: $($_.Exception.Message)" return $response } # 指数退避 $waitTime = $RetryInterval * [math]::Pow(2, $attempt - 1) $jitter = Get-Random -Minimum 0 -Maximum ($waitTime * 0.2) $totalWait = [math]::Ceiling($waitTime + $jitter) Write-Verbose "异常重试 ($attempt/$RetryCount): $($_.Exception.Message)" Write-Verbose "等待 ${totalWait}s 后重试" Start-Sleep -Seconds $totalWait } } while ($attempt -le $RetryCount -and -not $success) # 所有重试失败 if (-not $success) { $response.Status = "MaxRetryExceeded" $response.ErrorMessage = "达到最大重试次数 ($RetryCount) 仍失败" } return $response } ”
08-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值