リクエスト入力フローの取得
23672 ワード
文書ディレクトリ前言 POST要求の入力フローを取得し、 を修正する.まとめ 前言
私たちはリクエストをブロックするときによくこのような問題に遭遇します.私たちはブロックfilterでrequestのリクエストを取得したいと思っています.リクエストのデフォルトのgetInputStream()メソッドやgetReader()メソッドを使用してデータを取得しますが、後のControllerで@ResquestBody注釈を使用してrequestのbodyの値が読めません.これはrequestのbodyのデータはgetInputStream()とgetReader()メソッドで1回しか読み取れないため、この問題を解決するにはrequestリクエストを書き換えるgetInputStream()とgetReader()メソッドを使用します.
POST要求の入力フローを取得し、修正する
一般的にPOSTリクエストで私たちが持っている情報はアプリケーション/json形式です.いくつかのシナリオでは、これらのPOSTリクエストのアプリケーション/json情報を取得、解析します.まずコードを見てください.
まとめ
分析:Post要求入力フローを取得し、データが失われないことを保証する手順は以下の通りです.親の構築方法を継承し、独自の方法でデータの初期化 を行う.データの初期化は,入力ストリームを取得し,本クラスのchar[]bytesに を書き込むことである.再getInputStream()メソッドとgetReader()メソッドで、getInputStream()メソッドはbytesバイトストリーム情報 を直接読み出すアプリケーション/jsonデータを解析し、JsonNodeクラス を利用する
私たちはリクエストをブロックするときによくこのような問題に遭遇します.私たちはブロックfilterでrequestのリクエストを取得したいと思っています.リクエストのデフォルトのgetInputStream()メソッドやgetReader()メソッドを使用してデータを取得しますが、後のControllerで@ResquestBody注釈を使用してrequestのbodyの値が読めません.これはrequestのbodyのデータはgetInputStream()とgetReader()メソッドで1回しか読み取れないため、この問題を解決するにはrequestリクエストを書き換えるgetInputStream()とgetReader()メソッドを使用します.
POST要求の入力フローを取得し、修正する
一般的にPOSTリクエストで私たちが持っている情報はアプリケーション/json形式です.いくつかのシナリオでは、これらのPOSTリクエストのアプリケーション/json情報を取得、解析します.まずコードを見てください.
public class XssRequestWrapper extends HttpServletRequestWrapper {
private static Policy policy = null;
private static final AntiSamy antiSamy = new AntiSamy();
/**
* Body String
*/
private String body;
/**
* application/json Map
*/
private Map<String, String> parameters = new HashMap<String, String>();
/**
*
*/
private byte[] bytes;
/**
*
*/
private boolean isInit = false;
/**
*
*/
private static final String DEFAULT_CHARSET_NAME = "UTF-8";
private ObjectMapper objectMapper = new ObjectMapper();
public XssRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
try {
String contentType = request.getContentType();
if(contentType.contains(";")){
contentType = contentType.substring(0,contentType.indexOf(";"));
}
// bytes
initBytes();
// application/json
if(contentType.equals(MediaType.APPLICATION_JSON_VALUE)){
parseJsonParameters();
}
} catch (IOException e) {
throw new RuntimeException("IOException", e);
}
}
/**
*
* @throws IOException
*/
private void initBytes() throws IOException {
isInit = true;
StringBuilder buffer = new StringBuilder();
BufferedReader reader = this.getHttpServletRequest().getReader();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
body = buffer.toString();
//
bytes = body.getBytes(DEFAULT_CHARSET_NAME);
}
/**
* ApplicationJson , XSS
* @throws IOException
*/
private void parseJsonParameters() throws IOException {
StringBuilder stringBuilder = new StringBuilder("{");
if (null != body && body.length() > 0) {
JsonNode node = objectMapper.readTree(body);
Iterator<String> fieldNames = node.getFieldNames();
for (; fieldNames.hasNext();) {
String key = fieldNames.next();
String value = node.get(key).toString();
if (value.length() > 2 && value.startsWith("\"")) {
String valueTemp = value.substring(1,value.length()-1);
valueTemp = StringEscapeUtils.unescapeJava(valueTemp);
//TODO:XSS
valueTemp = StringEscapeUtils.escapeJava(valueTemp);
valueTemp = "\"" + valueTemp + "\"";
parameters.put(key, valueTemp);
} else {
parameters.put(key, value);
}
}
}
for(String key:parameters.keySet()){
String value = parameters.get(key);
stringBuilder.append("\""+key+"\":"+value+",");
}
stringBuilder.deleteCharAt(stringBuilder.length()-1);
stringBuilder.append("}");
try {
bytes = stringBuilder.toString().getBytes(DEFAULT_CHARSET_NAME);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
private HttpServletRequest getHttpServletRequest() {
return (HttpServletRequest) super.getRequest();
}
/**
* getReader
* @return
* @throws IOException
*/
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
/**
* getInputStream()
* body
* @return
* @throws IOException
*/
@Override
public ServletInputStream getInputStream() throws IOException {
if (!isInit)
initBytes();
final ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
}
};
}
まとめ
分析:Post要求入力フローを取得し、データが失われないことを保証する手順は以下の通りです.