springboot将请求封装到配置文件思路

本文介绍了一种基于XML配置文件的请求映射方法,详细解析了如何将请求路径与后端处理逻辑进行绑定,并利用Java线程读取配置信息,实现动态请求处理。同时,文中展示了如何通过过滤器拦截并处理HTTP请求,确保只有经过身份验证的用户才能访问特定资源。
将请求写到配置文件中

base.xml

<?xml version="1.0" encoding="UTF-8"?>
<controller>
	<!-- 
		- allUse  是否需要登录才能使用   1是   0否  2需要登陆才能访问,但无需授权    默认为否
	 -->
	 
	<!-- 公共请求开始 -->
	<url id="common001" path="/post/RmTypeController/queryRmTypeAllList" val="获取所有小程序分类" allUse="2">
	</url>
	<url id="common002" path="/post/RmGroupController/queryRmGroupAllList" val="获取所有小程序分组根据小程序分类ID" allUse="2">
		<property id="parentId" name="id" ref="required" var="小程序分类ID"/>
	</url>
	<url id="common003" path="/post/CommonController/uploadFile" val="上传文件" allUse="0">
		<property id="type" name="type" ref="required,num" var="图片类型"/>
	</url>
	<url id="common004" path="/post/CommonController/uploadFileBase64" val="上传文件Base64" allUse="2">
		<property id="type" name="type" ref="required,num" var="图片类型"/>
		<property id="images" name="images" ref="required" var="图片Base64"/>
	</url>
	
	<url id="commontarea001" path="/post/SysTAreaController/querySysTAreaProvinceList" val="获取一级省行政区划信息" allUse="2">
	</url>
	<url id="commontarea002" path="/post/SysTAreaController/querySysTAreaCityList" val="获取二级市行政区划信息" allUse="2">
		<property id="rowId" name="id" ref="required" var="省级行政区划id"/>
	</url>
	<url id="commontarea003" path="/post/SysTAreaController/querySysTAreaChildAreaList" val="获取三级县行政区划信息" allUse="2">
		<property id="rowId" name="id" ref="required" var="市级行政区划id"/>
	</url>
	<url id="commontarea004" path="/post/SysTAreaController/querySysTAreaTownShipList" val="获取四级镇行政区划信息" allUse="2">
		<property id="rowId" name="id" ref="required" var="县级行政区划id"/>
	</url>
	<url id="sys033" path="/post/SysEveUserController/editUserDetailsMationByUserId" val="修改个人信息" allUse="2">
		<property id="userSex" name="userSex" ref="required,num" var="性别" />
		<property id="userIdCard" name="userIdCard" ref="idcard" var="身份证" />
		<property id="userPhoto" name="userPhoto" ref="required" var="头像" />
		<property id="userEmail" name="userEmail" ref="email" var="邮箱" />
		<property id="userQq" name="userQq" ref="" var="QQ" />
		<property id="userPhone" name="userPhone" ref="phone" var="手机号" />
		<property id="userHomePhone" name="userHomePhone" ref="" var="家庭电话" />
		<property id="userSign" name="userSign" ref="" var="签名" />
	</url>
</controller>
读取配置文件(可以不是用线程去读取)
#请求路径url----
java.request.url.mappimg=mapping/base.xml,\
mapping/knowledge.xml,\
@Component
public class InitServlet implements ApplicationRunner{
	
	@Value("${java.request.url.mappimg}")
	private String REQUEST_URL;

	private static Logger log = LoggerFactory.getLogger(InitServlet.class);

	@Override
	public void run(ApplicationArguments arg0) throws Exception {
		//启动线程读取配置文件
		new Thread(new TokenThread(REQUEST_URL)).start();
		log.info("启动线程读取配置文件成功");
	}
}
public class TokenThread implements Runnable{
	
	private String REQUEST_URL;
	
	private static Logger log = LoggerFactory.getLogger(TokenThread.class);
	
	public TokenThread(String REQUEST_URL) {
		this.REQUEST_URL = REQUEST_URL;
	}

	@Override
	public void run() {
		try {
			log.info("线程读取配置信息路径开始");
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = factory.newDocumentBuilder();
			String[] filePath = REQUEST_URL.split(",");
			//Constants是一个自定义的类,当常量使用。
			Constants.REQUEST_MAPPING = new HashMap<>();
			for(String str : filePath){
				if(!ToolUtil.isBlank(str)){
					Document doc = db.parse(getClass().getResourceAsStream("/" + str));
					Element controller = doc.getDocumentElement();
					NodeList controllerNodes = controller.getElementsByTagName("url");
					List<Map<String, Object>> controllerBeans;
					Map<String, Object> controllerBean;
					Map<String,Object> actionBean;
					for (int i = 0; i < controllerNodes.getLength(); i++) {
						controllerBeans = new ArrayList<Map<String,Object>>();
						controllerBean = new HashMap<>();
						Element action = (Element)controllerNodes.item(i);
						NodeList actionNodes = action.getElementsByTagName("property");
						for(int j = 0;j < actionNodes.getLength(); j++){
							actionBean = new HashMap<String, Object>();
							Element property = (Element)actionNodes.item(j);
							actionBean.put("id", property.getAttribute("id"));//前端传递的key
							actionBean.put("name", property.getAttribute("name"));//后端接收的key
							actionBean.put("ref", property.getAttribute("ref"));//参数要求:require、num等
							controllerBeans.add(actionBean);
						}
						controllerBean.put("list", controllerBeans);
						//是否需要登录才能使用
						if(action.getAttribute("allUse") != null && !"".equals(action.getAttribute("allUse"))){
							controllerBean.put("allUse", action.getAttribute("allUse"));
						}else{
							controllerBean.put("allUse", 0);//是否需要登录才能使用   1是   0否  2需要登陆才能访问,但无需授权    默认为否
						}
						controllerBean.put("path", action.getAttribute("path"));
						controllerBean.put("val", action.getAttribute("val"));
						Constants.REQUEST_MAPPING.put(action.getAttribute("id").toString(), controllerBean);
					}
				}
			}
			System.out.println("请求路径文件读取完毕:共计" + Constants.REQUEST_MAPPING.size() + "条接口。");
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
使用过滤器拦截请求
@Configuration
public class FilterConfig {
	/**
	 * 配置过滤器
	 * 
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Bean
	public FilterRegistrationBean someFilterRegistration() {
		FilterRegistrationBean registration = new FilterRegistrationBean();
		registration.setFilter(sessionFilter());
		registration.addUrlPatterns("/*");
		registration.addInitParameter("paramName", "paramValue");
		registration.setName("sessionFilter");
		return registration;
	}

	/**
	 * 创建一个bean
	 * 
	 * @return
	 */
	@Bean(name = "sessionFilter")
	public Filter sessionFilter() {
		return new SessionFilter();
	}
}
public class SessionFilter implements Filter {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(SessionFilter.class);
	
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		
	}

	/**
	 * 过滤器
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// 获得在下面代码中要用的request,response,session对象
		HttpServletRequest servletRequest = (HttpServletRequest) request;
		HttpServletResponse servletResponse = (HttpServletResponse) response;
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		servletResponse.setCharacterEncoding("UTF-8");  
		servletResponse.setContentType("text/html;charset=UTF-8");
		servletResponse.setHeader("Access-Control-Allow-Origin", "*");
		//获取请求路径
		String url = servletRequest.getContextPath() + servletRequest.getServletPath();

		//1.文件目录过滤
		for(String str : Constants.FILTER_FILE_CATALOG_OPTION){
			if (url.indexOf(str) != -1) {
				chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response);
				return;
			}
		}
		
		//2.文件后缀过滤
		for(String str : Constants.FILTER_FILE_SUFFIX_OPTION){
			if (url.contains(str)) {
				chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response);
				return;
			}
		}
		
		if (url.indexOf("/upload") != -1) {//upload请求通过
			chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response);
			return;
		}
		
		//3.转换请求过滤
		if(request.getParameter("sessionKey") != null){
			for(String str : Constants.FILTER_FILE_REQUEST_OPTION){
				if (url.contains(str)) {
					chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response);
					return;
				}
			}
		}else{
			for(String str : Constants.FILTER_FILE_NO_SESSION_REQUEST_OPTION){
				if (url.contains(str)) {
					chain.doFilter(request, response);
					return;
				}else if(url.indexOf(str) != -1){
					chain.doFilter(request, response);
					return;
				}
			}
		}
		
		//4.请求过滤
		//如果不是设定的请求类型,则根据mapping.xml配置信息转化为请求信息
		if(ToolUtil.isBlank(url.replaceAll("/", ""))){
			servletResponse.sendRedirect(Constants.LOGIN_PAGE);
		}else{
			if(Constants.REQUEST_MAPPING == null){
				servletResponse.sendRedirect(Constants.LOGIN_PAGE);
			}else{
				if(Constants.REQUEST_MAPPING.containsKey(url.replaceAll("/", ""))){
					String key = url.replaceAll("/", "");
					String allUse = Constants.REQUEST_MAPPING.get(key).get("allUse").toString();
					if("1".equals(allUse) || "2".equals(allUse)){//是否需要登录才能使用   1是   0否  2需要登陆才能访问,但无需授权    默认为否
						JedisClientServiceImpl jedisClient = SpringUtils.getBean(JedisClientServiceImpl.class);
						if(ToolUtil.isBlank(request.getParameter("userToken")) 
								|| !jedisClient.exists("userMation:" + request.getParameter("userToken").toString())){
							servletResponse.setHeader("SESSIONSTATUS", "TIMEOUT");
							return;
						}else{
							//重置redis时间
							Map<String, Object> userMation = JSONObject.fromObject(jedisClient.get("userMation:" + request.getParameter("userToken").toString()));//用户信息
							List<Map<String, Object>> authPoints = JSONArray.fromObject(jedisClient.get("authPointsMation:" + request.getParameter("userToken").toString()));//所有权限信息
							if(authPoints(authPoints, key) || "2".equals(allUse)){//权限校验通过
								
								url = Constants.REQUEST_MAPPING.get(key).get("path").toString();
								
								//设置日志
								MDC.put("userName", userMation.get("userCode"));
								MDC.put("realPath", url);
								MDC.put("ip", ToolUtil.getIpByRequest(servletRequest));
								LOGGER.info(Constants.REQUEST_MAPPING.get(key).get("val").toString());
								request.getRequestDispatcher(url + "?sessionKey=" + key + "&allUse=" + allUse).forward(request, response);
							}else{
								System.out.println(key + "被强行访问.");
								servletResponse.setHeader("SESSIONSTATUS", "NOAUTHPOINT");
								return;
							}
						}
					}else{
						url = Constants.REQUEST_MAPPING.get(key).get("path").toString();
						request.getRequestDispatcher(url + "?sessionKey=" + key + "&allUse=" + allUse).forward(request, response);
					}
				}else{
					servletResponse.sendRedirect(Constants.LOGIN_PAGE);
				}
			}
		}
		return;
	}
	
	/**
	 * 权限点校验
	 * @param authPoints
	 * @param key
	 * @return
	 */
	public boolean authPoints(List<Map<String, Object>> authPoints, String key){
		for(Map<String, Object> bean : authPoints){
			if(key.equals(bean.get("menuUrl").toString())){
				return true;
			}
		}
		return false;
	}

	@Override
	public void destroy() {
		System.out.println("结束");
	}
	
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值