133 lines
4.2 KiB
Java
133 lines
4.2 KiB
Java
package io.company.localhost.common.wrapper;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.nio.charset.Charset;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
|
|
import org.springframework.util.StreamUtils;
|
|
import org.springframework.util.StringUtils;
|
|
|
|
import com.fasterxml.jackson.core.type.TypeReference;
|
|
|
|
import io.company.localhost.utils.JacksonUtil;
|
|
import io.netty.handler.codec.ValueConverter;
|
|
import jakarta.servlet.ReadListener;
|
|
import jakarta.servlet.ServletInputStream;
|
|
import jakarta.servlet.http.HttpServletRequest;
|
|
import jakarta.servlet.http.HttpServletRequestWrapper;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
// body 읽어서 cash로 만듬
|
|
// 필요하면 filter로 사용
|
|
@Slf4j
|
|
public class CachedBodyRequestWrapper extends HttpServletRequestWrapper {
|
|
|
|
private final Charset encoding;
|
|
|
|
private final byte[] cachedBody;
|
|
|
|
private ValueConverter targetConvert;
|
|
|
|
public CachedBodyRequestWrapper(HttpServletRequest request) throws IOException {
|
|
super(request);
|
|
|
|
String characterEncoding = request.getCharacterEncoding();
|
|
if (StringUtils.hasText(characterEncoding) == false) {
|
|
characterEncoding = StandardCharsets.UTF_8.name();
|
|
}
|
|
|
|
// XSS 방지를 이곳에서 하지 않을 경우 아래주석 해제 후 아래 //XSS 방지 이후 코드 삭제
|
|
// InputStream requestInputStream = request.getInputStream();
|
|
// this.cachedBody = StreamUtils.copyToByteArray(requestInputStream);
|
|
this.encoding = Charset.forName(characterEncoding);
|
|
|
|
// XSS 방지
|
|
String requestBody = null;
|
|
try {
|
|
requestBody = StreamUtils.copyToString(request.getInputStream(), Charset.defaultCharset());
|
|
} catch (IOException e) {
|
|
log.error("StreamUtil.toString Exception", e);
|
|
}
|
|
|
|
|
|
if (requestBody == null) {
|
|
InputStream requestInputStream = request.getInputStream();
|
|
this.cachedBody = StreamUtils.copyToByteArray(requestInputStream);
|
|
return;
|
|
}
|
|
|
|
Object bodyObject = null;
|
|
if (requestBody.startsWith("[")) { // List
|
|
bodyObject = JacksonUtil.fromJson(requestBody, new TypeReference<List<Map<String, Object>>>() {
|
|
});
|
|
} else { // Map
|
|
bodyObject = JacksonUtil.fromJson(requestBody, new TypeReference<Map<String, Object>>() {
|
|
});
|
|
}
|
|
|
|
|
|
String newRequestBody = JacksonUtil.toJson(bodyObject);
|
|
if (Objects.isNull(newRequestBody)) {
|
|
newRequestBody = new String("");
|
|
}
|
|
this.cachedBody = newRequestBody.getBytes(StandardCharsets.UTF_8);
|
|
}
|
|
|
|
/** json body 관련 메소드 START */
|
|
@Override
|
|
public ServletInputStream getInputStream() throws IOException {
|
|
return new CachedBodyServletInputStream(this.cachedBody);
|
|
}
|
|
|
|
@Override
|
|
public BufferedReader getReader() throws IOException {
|
|
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.cachedBody);
|
|
return new BufferedReader(new InputStreamReader(byteArrayInputStream, encoding));
|
|
}
|
|
|
|
/** json body 관련 메소드 END */
|
|
|
|
private class CachedBodyServletInputStream extends ServletInputStream {
|
|
|
|
private InputStream cachedBodyInputStream;
|
|
|
|
public CachedBodyServletInputStream(byte[] cachedBody) {
|
|
this.cachedBodyInputStream = new ByteArrayInputStream(cachedBody);
|
|
}
|
|
|
|
@Override
|
|
public boolean isFinished() {
|
|
try {
|
|
return this.cachedBodyInputStream.available() == 0;
|
|
} catch (IOException e) {
|
|
log.error("", e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean isReady() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void setReadListener(ReadListener listener) {
|
|
throw new UnsupportedOperationException();
|
|
}
|
|
|
|
@Override
|
|
public int read() throws IOException {
|
|
return this.cachedBodyInputStream.read();
|
|
}
|
|
|
|
}
|
|
|
|
}
|