本篇爲系列文,不以目的爲目的,以學習爲目的。旨在學習,重在研究。
上一篇:SSM攔截器校驗JSON數據(2) -- 從Request中獲取json格式數據
創建AccountWrapper繼承HttpServletRequestWrapper
HttpServletRequestWrapper介紹
package sinosoft.project.sso.utils.wrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.springframework.util.StreamUtils;
/**
* @Description: Account--Request--請求包裝類,解決json只能接受一次的問題
*/
public class AccountWrapper extends HttpServletRequestWrapper{
private byte[] requestBody;
public AccountWrapper(HttpServletRequest request) throws IOException {
super(request);
requestBody = StreamUtils.copyToByteArray(request.getInputStream());
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream(),StandardCharsets.UTF_8));
}
@Override
public ServletInputStream getInputStream() throws IOException {
if(requestBody == null){
requestBody = new byte[0];
}
final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public boolean isReady() {
return false;
}
@Override
public boolean isFinished() {
return false;
}
};
}
}
修改preHandle的代碼
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
try{
AccountInfo accountInfo = ssoJsonUtil.getParam(request);
//省略業務判斷邏輯代碼
}catch (Exception e) {
return false;
}
}
/**
*@Description: 解析request裏的AccountInfo
*/
public AccountInfo getParam(HttpServletRequest request) throws IOException, SSOException {
String jsonString = null;
String submitMethod = request.getMethod();
if("GET".equals(submitMethod) || submitMethod.equals("get")){
jsonString = getParamStringByGet(request);
}else if(submitMethod.equals("POST") || submitMethod.equals("post")){
jsonString = getParamJsonStringByPost(request);
}else{
logger.error("GetRequestJsonUtil解析Request參數錯誤--"+submitMethod);
}
logger.info("解析出來的參數--getParam:{}",jsonString);
if(StringUtils.isBlank(jsonString)){
throw new SSOException(new ReturnMsg(EC.RTF_FALSE,EC.ERR_PARAM_NULL_CODE,EC.ERR_PARAM_NULL_MSG));
}
AccountInfo parse = JSONObject.parseObject(jsonString, AccountInfo.class);
return parse;
}
/**
*@Description: 解析post方式提交的json數據
*/
private String getParamJsonStringByPost(HttpServletRequest request) throws IOException {
//這裏修改了
AccountWrapper aWrapper = new AccountWrapper(request);
int contentLength = aWrapper.getContentLength();
if(contentLength<0){
return null;
}
byte buffer[] = new byte[contentLength];
for (int i = 0; i < contentLength; i++) {
int readlen = aWrapper.getInputStream().read(buffer,i,contentLength -i);
if(readlen == -1){
break;
}
i+=readlen;
}
return new String(buffer,"UTF-8");
}
/**
*@Description: 解析get方式提交的request參數
*/
private String getParamStringByGet(HttpServletRequest request) throws IOException {
//這裏修改了
AccountWrapper aWrapper = new AccountWrapper(request);
return new String(aWrapper.getQueryString().getBytes("ios-8859-1"),"utf-8").replaceAll("%22", "\"");
}
這樣並沒有解決問題,因爲request中的數據在複製給AccountWrapper 時讀取過了(調用了request.getInputstream方法),所以要用AccountWrapper 代替request傳到controller中。
這樣就需要用過濾器配合
配置過濾器AccountFilter
package sinosoft.project.sso.utils.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sinosoft.project.sso.utils.wrapper.AccountWrapper;
/**
* @Description: 過濾器,用於controller可以獲取json
*/
public class AccountFilter implements Filter{
Logger logger = LoggerFactory.getLogger(AccountFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
AccountWrapper accountWrapper = null;
logger.info("AccountFilter--doFilter");
if(request instanceof HttpServletRequest){
accountWrapper = new AccountWrapper((HttpServletRequest)request);
}
if(accountWrapper == null){
chain.doFilter(request, response);
}else {
chain.doFilter(accountWrapper, response);//在這裏將AccountWrapper代替request去了controller
}
}
@Override
public void destroy() {
}
}
web.xml配置過濾器
<filter>
<filter-name>ssoAccountFilter</filter-name>
<filter-class>sinosoft.project.sso.utils.filter.AccountFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ssoAccountFilter</filter-name>
<url-pattern>/sso/account/*</url-pattern>
</filter-mapping>
spring-mvc註冊攔截器 (如果在第一篇文章時配置了就不需要了)
<!-- 註冊攔截器 -->
<!--攔截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/sso/account/**" /> <! --攔截路徑 -- >
<bean class="sinosoft.project.sso.account.interceptor.AccountInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
大功告成