攔截器獲取request的值之后,Controller拿不到值的解決
攔截器獲取request的值之后,Controller拿不到值
原因
在Spring中request的值只能被獲取一次,攔截器獲取之后就會(huì)導(dǎo)致Controller拿不到值
解決方法
將request的值進(jìn)行備份,請求到達(dá)Controller的時(shí)候就會(huì)拿到這個(gè)值
創(chuàng)建一個(gè)自己的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)建一個(gè)Filter,將該過濾器配置在項(xiàng)目中,為了調(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)建一個(gè)工具類,在攔截器中獲取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進(jìn)行項(xiàng)目的時(shí)候用到了權(quán)限驗(yàn)證。
表分為:
- 用戶表
- 角色表
- 資源表
用戶-角色-資源都是多對多的關(guān)系,驗(yàn)證無非就是收到請求后,在攔截器循環(huán)判斷用戶是否有權(quán)限執(zhí)行操作。
方法一:通過request獲得用戶的URL
再逐一循環(huán)判斷是否可以操作
只是這種方法很讓人難受。
方法二:通過用戶要訪問的方法來判斷是否有權(quán)限
preHandle方法中handler實(shí)際為HandlerMethod,(看網(wǎng)上說的有時(shí)候不是HandlerMethod),加個(gè)instanceof驗(yàn)證吧
- 可以得到方法名:h.getMethod().getName()
- 可以得到RequestMapping注解中的值:h.getMethodAnnotation(RequestMapping.class)
- 這種方法還是不太方便
方法三:自定義注解
自定義注解代碼:
@Retention(RUNTIME)
@Target(METHOD)
public @interface MyOperation {
String value() default "";//默認(rèn)為空,因?yàn)槊质莢alue,實(shí)際操作中可以不寫"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("進(jìn)入攔截器");
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);
}
補(bǔ)充
在每個(gè)方法上面加注解太麻煩啦,可以在類上加注解
@Retention(RUNTIME)
@Target(TYPE)
public @interface MyOperation {
String value() default "";
}
//攔截器中這樣獲得
h.getMethod().getDeclaringClass().getAnnotation(MyOperation.class);
我可以獲取requestMapping,不用創(chuàng)建自定義注解啊,值得注意的是,不要使用GetMapping等,要使用requestMapping。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
詳細(xì)介紹idea如何設(shè)置類頭注釋和方法注釋(圖文)
本篇文章主要介紹了idea如何設(shè)置類頭注釋和方法注釋(圖文),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-12-12
使用Java解析JSON數(shù)據(jù)并提取特定字段的實(shí)現(xiàn)步驟(以提取mailNo為例)
在現(xiàn)代軟件開發(fā)中,處理JSON數(shù)據(jù)是一項(xiàng)非常常見的任務(wù),無論是從API接口獲取數(shù)據(jù),還是將數(shù)據(jù)存儲(chǔ)為JSON格式,解析和提取JSON中的特定字段都是開發(fā)人員需要掌握的基本技能,本文將以一個(gè)實(shí)際案例為例,詳細(xì)介紹如何使用Java解析JSON數(shù)據(jù)并提取其中的mailNo字段2025-01-01
SpringBoot自定義定時(shí)任務(wù)的實(shí)現(xiàn)示例
本文主要介紹了SpringBoot自定義定時(shí)任務(wù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05
實(shí)例講解JAVA設(shè)計(jì)模式之備忘錄模式
這篇文章主要介紹了JAVA設(shè)計(jì)模式之備忘錄模式的的相關(guān)資料,文中示例代碼非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解下2020-06-06
Java中的ArrayList和contains函數(shù)和擴(kuò)容機(jī)制(源碼詳解)
這篇文章主要介紹了Java中的ArrayList和contains函數(shù)和擴(kuò)容機(jī)制,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-10-10
利用MultipartFile實(shí)現(xiàn)文件上傳功能
這篇文章主要為大家詳細(xì)介紹了利用MultipartFile實(shí)現(xiàn)文件上傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11

