1.DispatcherServlet
- SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过DispatcherServlet。
- DispatcherServlet是前置控制器,拦截匹配的请求,依据某某规则分发到目标Controller来处理。 所以我们现在web.xml中加入以下配置:
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 下面init-param是自定义servlet.xml配置文件的位置和名称,默认为WEB-INF目录下,名称为[<servlet-name>]-servlet.xml,如spring-servlet.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<!-- 此处可以配置成*.do,对应struts的后缀习惯 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
2.静态资源不拦截
如果配置拦截类似于*.do格式的url,则对静态资源的访问是没有问题的,但是如果配置拦截了所有的请求,如我们上面配置的“/”,就会造成js文件、css文件、图片文件等静态资源无法访问。
要过滤掉静态资源一般有两种方式,
2.1第一种
采用<mvc:default-servlet-handler />(一般Web应用服务器默认的Servlet名称是"default",所以这里我们激活Tomcat的defaultServlet来处理静态文件,在web.xml里配置如下代码即可:)
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/js/*</url-pattern>
<url-pattern>/css/*</url-pattern>
<url-pattern>/images/*</url-pattern>
<url-pattern>/fonts/*</url-pattern>
</servlet-mapping>
如果你所有的Web应用服务器的默认Servlet名称不是"default",则需要通过default-servlet-name属性显示指定:
<mvc:default-servlet-handler default-servlet-name="所使用的Web服务器默认使用的Servlet名称" />
2.2第二种
是采用<mvc:resources />,在springmvc的配置文件中加入以下代码:
<!-- 静态资源必须写到拦截器中才能防止被拦截 -->
<mvc:resources location="/css/" mapping="/css/**" />
<mvc:resources location="/easyui/" mapping="/easyui/**" />
<mvc:resources location="/image/" mapping="/image/**" />
<mvc:resources location="/My97DatePicker/" mapping="/My97DatePicker/**" />
<mvc:resources location="/uploadFiles/" mapping="/uploadFiles/**" />
<mvc:resources location="/js/" mapping="/js/**" />
<mvc:resources location="/plugin/" mapping="/plugin/**" />
3.自定义拦截器
- SpringMVC的拦截器HandlerInterceptorAdapter对应提供了三个preHandle,postHandle,afterCompletion方法。
- preHandle在业务处理器处理请求之前被调用
- postHandle在业务处理器处理请求执行完成后,生成视图之前执行
- afterCompletion在DispatcherServlet完全处理完请求后被调用,可用于清理资源等 。
- 所以要想实现自己的权限管理逻辑,需要继承HandlerInterceptorAdapter并重写其三个方法。
3.1案例
首先在springmvc.xml中加入自己定义的拦截器我的实现逻辑CommonInterceptor,
<mvc:interceptors>
<mvc:interceptor>
<!-- 对所有的.do结尾的进行拦截,/**表示/下面任何字段,起初我用/*/*.do后来发现/*不能代表所有的字段,要使用/** -->
<mvc:mapping path="/**/*.do" />
<!-- 登录 -->
<mvc:exclude-mapping path="/**/login.do" />
<mvc:exclude-mapping path="/**/findDepartmentsBeforLogin.do" />
<!--退出 -->
<mvc:exclude-mapping path="/**/loginOut.do" />
<!-- 跳转登录页面 -->
<mvc:exclude-mapping path="/**/toLogin.do" />
<!-- 登录页面验证 -->
<mvc:exclude-mapping path="/**/loginValidate.do" />
<!--静态资源 -->
<!-- <mvc:exclude-mapping path="/css/**"/> <mvc:exclude-mapping path="/easyui/**"/>
<mvc:exclude-mapping path="/image/**"/> <mvc:exclude-mapping path="/My97DatePicker/**"/>
<mvc:exclude-mapping path="/uploadFiles/**"/> -->
<bean class="cn.xiniu.interceptor.basicUser.LoginInterceptor">
<!--adminId 配置是为了开发人员使用的权限 -->
<!-- <property name="adminId" value="1"/> -->
</bean>
</mvc:interceptor>
<mvc:interceptor>
<!-- 对所有的/js/下的所有js文件进行拦截,对所有的.js的url添加时间簇 -->
<mvc:mapping path="/js/**" />
<!-- <mvc:exclude-mapping path="/js/**"/> -->
<bean class="cn.xiniu.interceptor.common.URlInterceptor">
</bean>
</mvc:interceptor>
</mvc:interceptors>
代码
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
/**
*
* @ClassName LoginInterceptor
* @Description TODO(处理上下文)
* @author feizhou
* @Date 2017年9月22日 下午1:40:26
* @version 1.0.0
*/
public class LoginInterceptor implements HandlerInterceptor{
@Autowired
private SessionProvider sessionProvider;
private Integer adminId;//管理员,给开发人员用,默认注入adminId=1
//方法前 /buyer/
//对请求路径 http://localhost:8080/buyer/index.shtml ---- /buyer/ 所请求的方法进行拦截,如果用户没有登录,
//不执行后面的方法,如果用户有登录,执行后面的方法
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
UserInfo newUserInfo = (UserInfo) sessionProvider.getAttribute(request, Constans.USER_SESSION,response);
// TODO Auto-generated method stub
if(adminId != null){//开发阶段不走正常流程,默认拦截器返回都是true,不走拦截url代码
UserInfo userInfo = new UserInfo();
userInfo.setUserID(1);
userInfo.setUserName("周凯");
int uid=1;
sessionProvider.setAttribute(request, "uid", uid,response);
sessionProvider.setAttribute(request, "userInfo", userInfo,response);
return true;
}else if(StringUtil.isEmpty(newUserInfo)){
//获取用户是否登录
// UserInfo userInfo = (UserInfo) sessionProvider.getAttribute(request, Constans.USER_SESSION,response);
//请求路径 http://localhost:8080/buyer/index.shtml
//getRequestURL()==http://localhost:8080/buyer/index.shtml
// getRequestURI()== /buyer/index.shtml
//不是以 INTERCEPTOR_URL为开头的方法都放过,是这开头的,但是用户登录了都放过
response.sendRedirect("/basic/toLogin.do");
return false;//用户没有登录,方法就不走了,调回登录页面让用户登录
}
return true;
}
//方法后
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
}
//页面渲染后
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub
}
public void setAdminId(Integer adminId) {
this.adminId = adminId;
}
}