因为服务器Windows版本问题,无法使用curl,所以只能使用wget。
C:\Windows\System32\wget.exe
需求背景:
传入客户端参数,请求服务端。
将请求参数保存到文本文件中,命令行读取文本文件,然后分割字符串,循环发起http请求。
参数文本文件:
参数1,参数2,参数3,... ...
命令行脚本文件:
@echo off & setlocal enabledelayedexpansion
chcp 65001 > NUL
set /p param_list=< "./参数文本文件.txt"
echo %param_list%
call :loop_block
goto :eof
:loop_block
for /f "tokens=1,* delims=," %%i in ("!param_list!") do (
echo %%i
set param=%%i
wget --header="User-Agents: Chrome" --header="Content-Type: application/json" --post-data='{"\"key"\":"\"!param!"\"}' http://localhost:8090/execute -q -O -
set param_list=%%j
goto loop_block
)
goto :eof
测试执行:
服务端controller接收不到请求,控制台有以下信息:
2025-01-17 19:04:00.586 [http-nio-8090-exec-7] WARN o.s.w.s.m.support.DefaultHandlerExceptionResolver - Resolved [org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public java.util.Map<java.lang.String, java.lang.String> com.controller.MyController.execute(java.lang.String)]
但是将参数改为英文字符,就可以正常接收到请求参数。
然后自定义一个Filter,看下请求到底是怎么回事,发现当参数为中文时会有以下报错:
2025-01-17 16:14:17.019 [http-nio-8090-exec-2] ERROR o.a.c.c.C.[.[localhost].[/].[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:281)
at org.apache.tomcat.util.buf.B2CConverter.convert(B2CConverter.java:239)
at org.apache.catalina.connector.InputBuffer.realReadChars(InputBuffer.java:403)
at org.apache.catalina.connector.InputBuffer.checkCharBufferEof(InputBuffer.java:610)
at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:435)
at org.apache.catalina.connector.CoyoteReader.read(CoyoteReader.java:108)
at org.apache.catalina.connector.CoyoteReader.readLine(CoyoteReader.java:163)
at com.MyRequestWrapper.<init>(MyFilter.java:121)
at com.MyFilter.doFilter(MyFilter.java:75)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:190)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:163)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1723)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
然后无论是客户端还是服务端,尝试各种各样网罗来的解决方法,均无效😂
wget --local-encoding=utf-8 --remote-encoding=utf-8 --header="User-Agents: Chrome" --header="Accept-Charset: UTF-8" --header="Content-Type: text/plain;charset=UTF-8"
最后实在没办法了,只好暂时使用native2ascii将参数文件转为unicode,问题可以解决
native2ascii -encoding UTF-8 旧参数文件.txt 新参数文件.txt
如果有更好的、更直接的解决方法,希望大家随时交流😉。
加个计数器:
@echo off & setlocal enabledelayedexpansion
chcp 65001 > NUL
set /a counter=0
set /p param_list=< "./参数文本文件.txt"
echo %param_list%
call :loop_block
goto :eof
:loop_block
for /f "tokens=1,* delims=," %%i in ("!param_list!") do (
set /a counter+=1
echo 第!counter!个参数:%%i
set param=%%i
wget --local-encoding=utf-8 --remote-encoding=utf-8 --header="User-Agents: Chrome" --header="Accept-Charset: UTF-8" --header="Content-Type: text/plain;charset=UTF-8" --post-data='{"\"key"\":"\"!param!"\"}' http://localhost:8090/execute -q -O -
set param_list=%%j
goto loop_block
)
goto :eof
因为set 变量长度有限制1023(中文按3个字符),可以考虑按行读取文件,同时再加一个耗时统计,脚本改进如下:
@echo off & setlocal enabledelayedexpansion
chcp 65001 > NUL
set param1=xxx
set /a counter=0
for /f "delims=" %%a in ('echo %time%') do set "startTime=%%a"
for /f "tokens=*" %%a in (./参数文件.txt) do (
set /a counter+=1
echo 第!counter!个参数:%%a
REM set key=%%a
wget --local-encoding=utf-8 --remote-encoding=utf-8 --header="User-Agents: Chrome" --header="Accept-Charset: UTF-8" --header="Content-Type: text/plain;charset=UTF-8" --post-data='{"\"key"\":"\"%%a"\"}' http://localhost:8090/execute -q -O -
)
for /f "delims=" %%a in ('echo %time%') do set "endTime=%%a"
for /f "tokens=1-4 delims=:." %%i in ("%startTime%") do (
set /a "startHour=%%i"
set /a "startMinute=%%j"
set /a "startSecond=%%k"
set /a "startMillisec=%%l"
)
for /f "tokens=1-4 delims=:." %%i in ("%endTime%") do (
set /a "endHour=%%i"
set /a "endMinute=%%j"
set /a "endSecond=%%k"
set /a "endMillisec=%%l"
)
set /a "startTimeSec=%startHour%*3600 + %startMinute%*60 + %startSecond%"
set /a "endTimeSec=%endHour%*3600 + %endMinute%*60 + %endSecond%"
set /a "diff=%endTimeSec% - %startTimeSec%"
:: 输出耗时结果
echo 耗时: %diff% 秒
endlocal