class RepeatBodyRequestWrapper extends HttpServletRequestWrapper {

	private final byte[] bodyByteArray;

	private final Map<String, String[]> parameterMap;

	public RepeatBodyRequestWrapper(HttpServletRequest request) {
		super(request);
		this.bodyByteArray = getByteBody(request);
		this.parameterMap = super.getParameterMap();
	}

	@Override
	public BufferedReader getReader() {
		return ObjectUtils.isEmpty(this.bodyByteArray) ? null
				: new BufferedReader(new InputStreamReader(getInputStream()));
	}

	@Override
	public ServletInputStream getInputStream() {
		final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.bodyByteArray);
		return new ServletInputStream() {
			@Override
			public boolean isFinished() {
				return false;
			}

			@Override
			public boolean isReady() {
				return false;
			}

			@Override
			public void setReadListener(ReadListener readListener) {
				// doNoting
			}

			@Override
			public int read() {
				return byteArrayInputStream.read();
			}
		};
	}

	private static byte[] getByteBody(HttpServletRequest request) {<FILL_FUNCTION_BODY>}

	/**
	 * 重写 getParameterMap() 方法 解决 undertow 中流被读取后，会进行标记，从而导致无法正确获取 body 中的表单数据的问题
	 * @return Map<String, String [ ]> parameterMap
	 */
	@Override
	public Map<String, String[]> getParameterMap() {
		return this.parameterMap;
	}

}

		byte[] body = new byte[0];
		try {
			body = StreamUtils.copyToByteArray(request.getInputStream());
		}
		catch (IOException e) {
			log.error("解析流中数据异常", e);
		}
		return body;
	
<methods>public void <init>(jakarta.servlet.http.HttpServletRequest) ,public boolean authenticate(jakarta.servlet.http.HttpServletResponse) throws java.io.IOException, jakarta.servlet.ServletException,public java.lang.String changeSessionId() ,public java.lang.String getAuthType() ,public java.lang.String getContextPath() ,public jakarta.servlet.http.Cookie[] getCookies() ,public long getDateHeader(java.lang.String) ,public java.lang.String getHeader(java.lang.String) ,public Enumeration<java.lang.String> getHeaderNames() ,public Enumeration<java.lang.String> getHeaders(java.lang.String) ,public jakarta.servlet.http.HttpServletMapping getHttpServletMapping() ,public int getIntHeader(java.lang.String) ,public java.lang.String getMethod() ,public jakarta.servlet.http.Part getPart(java.lang.String) throws java.io.IOException, jakarta.servlet.ServletException,public Collection<jakarta.servlet.http.Part> getParts() throws java.io.IOException, jakarta.servlet.ServletException,public java.lang.String getPathInfo() ,public java.lang.String getPathTranslated() ,public java.lang.String getQueryString() ,public java.lang.String getRemoteUser() ,public java.lang.String getRequestURI() ,public java.lang.StringBuffer getRequestURL() ,public java.lang.String getRequestedSessionId() ,public java.lang.String getServletPath() ,public jakarta.servlet.http.HttpSession getSession() ,public jakarta.servlet.http.HttpSession getSession(boolean) ,public Map<java.lang.String,java.lang.String> getTrailerFields() ,public java.security.Principal getUserPrincipal() ,public boolean isRequestedSessionIdFromCookie() ,public boolean isRequestedSessionIdFromURL() ,public boolean isRequestedSessionIdValid() ,public boolean isTrailerFieldsReady() ,public boolean isUserInRole(java.lang.String) ,public void login(java.lang.String, java.lang.String) throws jakarta.servlet.ServletException,public void logout() throws jakarta.servlet.ServletException,public jakarta.servlet.http.PushBuilder newPushBuilder() ,public T upgrade(Class<T>) throws java.io.IOException, jakarta.servlet.ServletException<variables>