Java HttpServletRequest 转 CURL 命令
private static final String FORMAT_HEADER = "-H \"%1$s:%2$s\"";
private static final String FORMAT_METHOD = "-X %1$s";
private static final String FORMAT_BODY = "-d '%1$s'";
private static final String FORMAT_URL = "\"%1$s\"";
private static final String CONTENT_TYPE = "Content-Type";
/**
* <p>
* HttpServletRequest 转化为 CURL 命令
* </p>
*
* @param request request
* @return String
* @author Tophua
* @since 2021/8/19
*/
public String getCurl(HttpServletRequest request) {
String curl;
try {
List<String> parts = new ArrayList<>();
parts.add("curl");
String url = request.getRequestURL().toString();
String method = request.getMethod();
String contentType = request.getContentType();
String queryString = request.getQueryString();
parts.add(String.format(FORMAT_METHOD, method.toUpperCase()));
Map<String, String> headers = new HashMap<>(16);
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String key = headerNames.nextElement();
headers.put(key, request.getHeader(key));
}
headers.forEach((k, v) -> parts.add(String.format(FORMAT_HEADER, k, v)));
if (StrUtil.isNotEmpty(contentType) && !headers.containsKey(CONTENT_TYPE)) {
parts.add(String.format(FORMAT_HEADER, CONTENT_TYPE, contentType));
}
if (StrUtil.isNotEmpty(queryString)) {
url = HttpUtil.urlWithForm(url, queryString, CharsetUtil.CHARSET_UTF_8, false);
}
if (ContentType.isFormUrlEncode(contentType) && CollUtil.isNotEmpty(request.getParameterMap())) {
request.getParameterMap().forEach((k, v) ->
parts.add(StrUtil.format("--data-urlencode '{}={}'", k, ArrayUtil.get(v, 0))));
}
if (StrUtil.startWithIgnoreCase(contentType, ContentType.JSON.toString())) {
BodyReaderHttpServletRequestWrapper wrapper = (BodyReaderHttpServletRequestWrapper) request;
String body = StrUtil.utf8Str(wrapper.getCachedBody());
if (StrUtil.isNotEmpty(body)) {
parts.add(String.format(FORMAT_BODY, body));
}
}
parts.add(String.format(FORMAT_URL, url));
curl = StrUtil.join(" ", parts);
} catch (Exception e) {
e.printStackTrace();
curl = null;
}
return curl;
}
辅助类
/**
* <p>
* body 缓存ServletInputStream
* </p>
*
* @author Tophua
* @since 2021/8/22
*/
@Slf4j
public class CachedBodyServletInputStream extends ServletInputStream {
private final InputStream cachedBodyInputStream;
public CachedBodyServletInputStream(byte[] cachedBody) {
this.cachedBodyInputStream = new ByteArrayInputStream(cachedBody);
}
@Override
public boolean isFinished() {
try {
return cachedBodyInputStream.available() == 0;
} catch (IOException e) {
log.error(e.getMessage());
return false;
}
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
}
/**
* Reads the next byte of data from the input stream. The value byte is
* returned as an <code>int</code> in the range <code>0</code> to
* <code>255</code>. If no byte is available because the end of the stream
* has been reached, the value <code>-1</code> is returned. This method
* blocks until input data is available, the end of the stream is detected,
* or an exception is thrown.
*
* <p> A subclass must provide an implementation of this method.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* stream is reached.
* @throws IOException if an I/O error occurs.
*/
@Override
public int read() throws IOException {
return cachedBodyInputStream.read();
}
}
/**
* <p>
* body 缓存包装器
* </p>
*
* @author Tophua
* @since 2021/8/22
*/
@Slf4j
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
private final byte[] cachedBody;
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
InputStream requestInputStream = request.getInputStream();
this.cachedBody = StreamUtils.copyToByteArray(requestInputStream);
}
@Override
public ServletInputStream getInputStream() {
return new CachedBodyServletInputStream(this.cachedBody);
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
/**
* <p>
* 获取缓存body
* </p>
*
* @return byte[]
* @author Tophua
* @since 2021/8/21
*/
public byte[] getCachedBody() {
return cachedBody;
}
}
```