springmvc基于注解的权限控制
一、权限码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * @Title: AuthCode.java * @Package cn.com.kamfu.auth * @Description: TODO(用一句话描述该文件做什么) * @author: liandy * @date: 2019年7月15日 下午10:07:45 * @version V1.0 */ package cn.com.kamfu.auth; /** * @ClassName: AuthCode * @Description:TODO(这里用一句话描述这个类的作用) * @author: liandy * @date: 2019年7月15日 下午10:07:45 * */ public enum AuthCode { index("1", "001", "首页"), userAdd("2", "002", "新增用户", "新增用户"), userDelete("3", "003", "删除用户", "删除用户"), userEdit("4", "004", "修改用户", "修改用户"), userQuery("5", "005", "查询用户", "查询用户"); private String authId; private String authCode; private String authName; private String authDesc; private AuthCode(String authId, String authCode, String authName) { this.authId = authId; this.authCode = authCode; this.authName = authName; } private AuthCode(String authId, String authCode, String authName, String authDesc) { this.authId = authId; this.authCode = authCode; this.authName = authName; this.authDesc = authDesc; } public String getAuthId() { return authId; } public void setAuthId(String authId) { this.authId = authId; } public String getAuthCode() { return authCode; } public void setAuthCode(String authCode) { this.authCode = authCode; } public String getAuthName() { return authName; } public void setAuthName(String authName) { this.authName = authName; } public String getAuthDesc() { return authDesc; } public void setAuthDesc(String authDesc) { this.authDesc = authDesc; } }
二、权限校验标识
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * @Title: AuthValidate.java * @Package cn.com.kamfu.auth * @Description: TODO(用一句话描述该文件做什么) * @author: liandy * @date: 2019年7月15日 下午10:07:08 * @version V1.0 */ package cn.com.kamfu.auth; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @ClassName: AuthValidate * @Description:权限校验标识 * @author: liandy * @date: 2019年7月15日 下午10:07:08 * */ @Target({ ElementType.METHOD, ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) public @interface AuthValidate { AuthCode value() ; }
三、业务异常类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * @Title: BusinessException.java * @Package cn.com.kamfu.exception * @Description: TODO(用一句话描述该文件做什么) * @author: liandy * @date: 2019年7月15日 下午10:16:50 * @version V1.0 */ package cn.com.kamfu.exception; /** * * 项目名称:--- * 模块名称:接入层 * 功能描述:异常类 * 创建人: mao2080@sina.com * 创建时间:2017年5月9日 下午8:22:21 * 修改人: mao2080@sina.com * 修改时间:2017年5月9日 下午8:22:21 */ public class BusinessException extends Exception{ public BusinessException() { } public BusinessException(String message) { super(message); } }
四、拦截器
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * @Title: UserLoginInterceptor.java * @Package cn.com.kamfu.interceptor * @Description: TODO(用一句话描述该文件做什么) * @author: liandy * @date: 2019年7月15日 下午10:13:50 * @version V1.0 */ package cn.com.kamfu.interceptor; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.context.support.StaticApplicationContext; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import cn.com.kamfu.auth.AuthCode; import cn.com.kamfu.auth.AuthValidate; import cn.com.kamfu.exception.BusinessException; import cn.com.kamfu.model.User; import cn.com.kamfu.util.JsonUtil; /** * * 项目名称:--- * 模块名称:接入层 * 功能描述:用户访问拦截器(利用SpringMVC自定义拦截器实现) * 创建人: mao2080@sina.com * 创建时间:2017年4月25日 下午8:53:49 * 修改人: mao2080@sina.com * 修改时间:2017年4月25日 下午8:53:49 */ public class UserAccessInterceptor implements HandlerInterceptor { /** * * 描述:构造函数 * @author mao2080@sina.com * @created 2017年4月28日 下午5:20:34 * @since * @param accessService */ public UserAccessInterceptor() { } /** * * 描述:执行方法前 * @author mao2080@sina.com * @created 2017年4月25日 下午9:01:44 * @since * @param request HttpServletRequest * @param response HttpServletResponse * @param handler handler * @return * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { try { //校验登录 this.userLoginValidate(request,response); //校验权限 this.userAuthValidate(request, handler); } catch (Exception e) { e.printStackTrace(); printMessage(response,e.getMessage()); return false; } return true; } /** * * 描述:输出到前端 * @author mao2080@sina.com * @created 2017年4月28日 上午11:00:25 * @since * @param response 响应 * @param res 对象 * @throws Exception */ public static void printMessage(HttpServletResponse response, Object res) throws Exception{ PrintWriter writer = null; response.setCharacterEncoding("UTF-8"); response.setContentType("text/html; charset=utf-8"); try { writer = response.getWriter(); writer.print(res.toString()); } catch (Exception e) { e.printStackTrace(); } finally { if (writer != null){ writer.close(); } } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } /** * * 描述:用户登录校验 * @author mao2080@sina.com * @created 2017年5月9日 下午8:27:25 * @since * @param request * @throws BusinessException * @throws IOException */ private void userLoginValidate(HttpServletRequest request,HttpServletResponse response) throws BusinessException, IOException { //校验代码 HttpSession session = request.getSession(); String token =(String) session.getAttribute("token"); if(null==token) { return; } } /** * * 描述:用户权限校验 * @author mao2080@sina.com * @created 2017年5月4日 下午8:34:09 * @since * @param request HttpServletRequest * @param handler * @return * @throws BusinessException */ private void userAuthValidate(HttpServletRequest request, Object handler) throws BusinessException { if(handler instanceof HandlerMethod) { AuthValidate validate = ((HandlerMethod) handler).getMethodAnnotation(AuthValidate.class); if(validate == null){ return;//默认权限开放 } String authId = validate.value().getAuthId(); List<String> auths = new ArrayList<String>();//模拟从缓存或者从数据库中查询出对应用户的权限 auths.add("1"); auths.add("5"); if(!auths.contains(authId)){ throw new BusinessException("权限不足"); } } } }
五、配置拦截规则
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package cn.com.kamfu.interceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class WebMvcConfiguration extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { // addPathPatterns 用于添加拦截规则 // excludePathPatterns 用户排除拦截 // 映射为 user 的控制器下的所有映射 // registry.addInterceptor(new UserAccssInterceptor()).addPathPatterns("/user"); } }
六、配置拦截器
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd"> <!-- 注解扫描包 --> <context:component-scan base-package="cn.com.kamfu" /> <!-- 开启注解 --> <mvc:annotation-driven /> <!-- 配置静态资源,直接映射到对应的文件夹,不被DispatcherServlet处理 --> <mvc:resources mapping="/images/**" location="/WEB-INF/images/" /> <mvc:resources mapping="/script/**" location="/WEB-INF/script/" /> <mvc:resources mapping="/css/**" location="/WEB-INF/css/" /> <mvc:resources mapping="/html/**" location="/WEB-INF/html/" /> <!-- 定义跳转的文件的前后缀 ,视图模式配置--> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 这里的配置我的理解是自动给后面action的方法return的字符串加上前缀和后缀,变成一个 可用的url地址 --> <property name="prefix" value="/WEB-INF/jsp" /> <property name="suffix" value=".jsp" /> </bean> <!--配置拦截器, 多个拦截器,顺序执行 --> <mvc:interceptors> <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" /> <mvc:interceptor> <!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller --> <mvc:mapping path="/**" /> <bean class="cn.com.kamfu.interceptor.UserAccessInterceptor"></bean> </mvc:interceptor> <!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 --> </mvc:interceptors> </beans>
七、拦截器的使用
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * @Title: UserController.java * @Package cn.com.kamfu.controller * @Description: TODO(用一句话描述该文件做什么) * @author: liandy * @date: 2019年7月12日 上午2:53:59 * @version V1.0 */ package cn.com.kamfu.controller; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import cn.com.kamfu.auth.AuthCode; import cn.com.kamfu.auth.AuthValidate; import cn.com.kamfu.model.User; import cn.com.kamfu.service.UserService; @Controller @RequestMapping("/user") public class UserController { @Autowired private UserService userService; protected Logger log = Logger.getLogger(UserController.class); @RequestMapping("/login") public String login(){ return "/user/login"; } @RequestMapping("checkUser") public String checkUser(String name,String password,HttpServletRequest request){ request.getSession().setAttribute("token","token123"); return "redirect:/user/index"; } @AuthValidate(AuthCode.index) @RequestMapping("/index") public String index(){ return "/user/index"; } //match automatically @RequestMapping("/list") @AuthValidate(AuthCode.userQuery) public String list(HttpServletRequest request){ // List<User> listUser = userService.findAllUser(); // request.setAttribute("listUser",listUser); // log.debug("服务器启动了,log4j开始工作了"); // log.error("服务器启动了,log4j开始工作了"); return "/user/list"; } @RequestMapping(value="/pagedList",method=RequestMethod.POST,produces ={"application/json;charset=UTF-8"}) @ResponseBody public Map<String, Object> pagedList(HttpServletRequest request) throws IOException{ String currentPage=request.getParameter("page"); String pageSize=request.getParameter("rows"); List<User> fList=new ArrayList<User>(); User user=new User(); user.setId(1); user.setUsername("username"); user.setPassword("password"); fList.add(user);fList.add(user);fList.add(user);fList.add(user);fList.add(user);fList.add(user);fList.add(user);fList.add(user);fList.add(user);fList.add(user); Map<String, Object> map=new HashMap<String,Object>(); map.put("total", 21); map.put("rows", fList); return map; } //boxing automatically @RequestMapping("/add") public String add(User user){ System.out.println(user.toString()); return "/user/add"; } //pass the parameters to front-end @RequestMapping("/showUser") public String showUser(Map<String,Object> map){ User p =new User(); map.put("p", p); p.setUsername("jack"); return "show"; } //pass the parameters to front-end using ajax @RequestMapping("/getUser") public void getPerson(String name,PrintWriter pw){ pw.write("hello,"+name); } //redirect @RequestMapping("/redirect") public String redirect(){ return "redirect:hello"; } @RequestMapping("/file") public String file(){ return "/file"; } //文件上传 @RequestMapping(value="/upload",method=RequestMethod.POST) public String upload(HttpServletRequest req) throws Exception{ MultipartHttpServletRequest mreq = (MultipartHttpServletRequest)req; MultipartFile file = mreq.getFile("file"); String fileName = file.getOriginalFilename(); SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); FileOutputStream fos = new FileOutputStream(req.getSession().getServletContext().getRealPath("/")+ "upload/"+sdf.format(new Date())+fileName.substring(fileName.lastIndexOf('.'))); fos.write(file.getBytes()); fos.flush(); fos.close(); return "success"; } }