攔截器獲取request的值之后,Controller拿不到值的解決
攔截器獲取request的值之后,Controller拿不到值
原因
在Spring中request的值只能被獲取一次,攔截器獲取之后就會導致Controller拿不到值
解決方法
將request的值進行備份,請求到達Controller的時候就會拿到這個值
創(chuàng)建一個自己的HttpServletRequestWrapper并繼承servlet的HttpServletRequestWrapper,為了備份request中的值。
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper {
private final byte[] buff;
public MyHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
InputStream is = request.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int len;
while ((len = is.read(b)) != -1) {
baos.write(b, 0, len);
}
buff = baos.toByteArray();
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(buff);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
}
};
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
}
創(chuàng)建一個Filter,將該過濾器配置在項目中,為了調(diào)用備份的HttpServletRequestWrapper
public class MyRequestBodyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
servletRequest = new MyHttpServletRequestWrapper(httpServletRequest);
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
創(chuàng)建一個工具類,在攔截器中獲取request的值
public class RequestUtils {
public static String getRequestValue(HttpServletRequest request) throws IOException {
StringBuffer sb = new StringBuffer();
MyHttpServletRequestWrapper myHttpServletRequestWrapper = new MyHttpServletRequestWrapper(request);
InputStream is = myHttpServletRequestWrapper.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String str;
while ((str = br.readLine()) != null) {
sb.append(str);
}
return sb.toString();
}
}
使用攔截器獲取Controller方法名和注解信息
在使用SpringMVC進行項目的時候用到了權限驗證。
表分為:
- 用戶表
- 角色表
- 資源表
用戶-角色-資源都是多對多的關系,驗證無非就是收到請求后,在攔截器循環(huán)判斷用戶是否有權限執(zhí)行操作。
方法一:通過request獲得用戶的URL
再逐一循環(huán)判斷是否可以操作
只是這種方法很讓人難受。
方法二:通過用戶要訪問的方法來判斷是否有權限
preHandle方法中handler實際為HandlerMethod,(看網(wǎng)上說的有時候不是HandlerMethod),加個instanceof驗證吧
- 可以得到方法名:h.getMethod().getName()
- 可以得到RequestMapping注解中的值:h.getMethodAnnotation(RequestMapping.class)
- 這種方法還是不太方便
方法三:自定義注解
自定義注解代碼:
@Retention(RUNTIME)
@Target(METHOD)
public @interface MyOperation {
String value() default "";//默認為空,因為名字是value,實際操作中可以不寫"value="
}
Controller代碼:
@Controller("testController")
public class TestController {
@MyOperation("用戶修改")//主要看這里
@RequestMapping("test")
@ResponseBody
public String test(String id) {
return "Hello,2018!"+id;
}
}
攔截器的代碼:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("進入攔截器");
if(handler instanceof HandlerMethod) {
HandlerMethod h = (HandlerMethod)handler;
System.out.println("用戶想執(zhí)行的操作是:"+h.getMethodAnnotation(MyOperation.class).value());
//判斷后執(zhí)行操作...
}
return HandlerInterceptor.super.preHandle(request, response, handler);
}
補充
在每個方法上面加注解太麻煩啦,可以在類上加注解
@Retention(RUNTIME)
@Target(TYPE)
public @interface MyOperation {
String value() default "";
}
//攔截器中這樣獲得
h.getMethod().getDeclaringClass().getAnnotation(MyOperation.class);
我可以獲取requestMapping,不用創(chuàng)建自定義注解啊,值得注意的是,不要使用GetMapping等,要使用requestMapping。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
使用Java解析JSON數(shù)據(jù)并提取特定字段的實現(xiàn)步驟(以提取mailNo為例)
在現(xiàn)代軟件開發(fā)中,處理JSON數(shù)據(jù)是一項非常常見的任務,無論是從API接口獲取數(shù)據(jù),還是將數(shù)據(jù)存儲為JSON格式,解析和提取JSON中的特定字段都是開發(fā)人員需要掌握的基本技能,本文將以一個實際案例為例,詳細介紹如何使用Java解析JSON數(shù)據(jù)并提取其中的mailNo字段2025-01-01
Java中的ArrayList和contains函數(shù)和擴容機制(源碼詳解)
這篇文章主要介紹了Java中的ArrayList和contains函數(shù)和擴容機制,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-10-10

