[英]How to eliminate special characters before hitting the controller in Java?
我有一個用例,我需要驗證傳入控制器的請求正文是否包含 Hybris 店面中的任何特殊字符。 雖然可以通過阻止任何特殊字符從前端實現,但我們需要后端驗證。
我嘗試使用HandlerIntercepterAdapter
來攔截請求並驗證任何特殊字符。 但是每當我使用request.getReader()
或request.getInputStream()
並讀取數據時,請求正文都會被清除。 我嘗試使用IOUtils.copy()
但這也從原始請求中讀取並使正文為空。 即使使用HttpServletRequestWrapper
或ContentCachingRequestWrapper
包裝請求后,請求正文也會被清除。 我猜在內部某個地方它使用相同的引用。 我嘗試關注此線程,但無法解決此問題。
我正在尋找一種解決方案,我可以在其中提取請求正文並對其進行驗證,而不會讓它被清除,以便它可以在不同的控制器中使用 [或] 任何有助於防止任何特殊字符擊中控制器的替代方法。
任何可以幫助防止任何特殊字符擊中控制器的替代方法。
如果您嘗試執行以下操作怎么辦...
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest originalRequest = (HttpServletRequest) request;
HttpServletResponse originalResponse = (HttpServletResponse) response;
/**
* 2.Read the original request body and change it
*/
String originalRequestBody = ServletUtil.readRequestBody(originalRequest); // Read the original request body
// Body is processed here !
String modifyRequestBody = processBody(originalRequestBody); // Modify request body (clear text)
HttpServletRequest orginalRequest = (HttpServletRequest) request;
ModifyRequestBodyWrapper requestWrapper = new ModifyRequestBodyWrapper(orginalRequest, modifyRequestBody);
/**
* 3. Build a new response object
*/
ModifyResponseBodyWrapper responseWrapper = new ModifyResponseBodyWrapper(originalResponse);
chain.doFilter(requestWrapper, responseWrapper);
String originalResponseBody = responseWrapper.getResponseBody(); // Original response body (clear text)
String modifyResponseBody = this.encryptBody(originalResponseBody); // Modified response volume (ciphertext)
/**
* 4.Output the modified response body with the output stream of the original response object
* To ensure that the response type is consistent with the original request, and reset the response body size
*/
originalResponse.setContentType(requestWrapper.getOrginalRequest().getContentType()); // Be consistent with the request
byte[] responseData = modifyResponseBody.getBytes(responseWrapper.getCharacterEncoding()); // The coding is consistent with the actual response
originalResponse.setContentLength(responseData.length);
@Cleanup ServletOutputStream out = originalResponse.getOutputStream();
out.write(responseData);
}
這是一個代碼示例,它實現了這一點。
輸入應設置在表單內。
在您的控制器中,您可以使用驗證器:
@RequestMapping(value = "/process", method = RequestMethod.POST)
public String doValidateAndPost(final MyForm form, final BindingResult bindingResult,
final HttpServletRequest request, final Model model){
getMyValidator().validate(form, bindingResult);
if (bindingResult.hasErrors())
{
return MY_PAGE;
}
驗證器將如下所示:
@Override
public void validate(final Object object, final Errors errors)
{
final MyForm form = (MyForm ) object;
final String data = form.getMyData();
Pattern p = Pattern.compile("[^a-z0-9 ]", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(data );
boolean b = m.find();
if (b)
{
errors.rejectValue("myData", "myData.invalid");
}
}
您還可以使用@Valid
注釋:
public String doValidateAndPost(@Valid final MyForm form ...
並以您的形式設置:
@Pattern(regexp = "[a-z0-9 ]")
private String myData;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.