【续上集】 开源项目renren-fast解读,让java不再难懂(一)
3、安全防范模块-预防xss攻击和sql注入
XSS
1、百度百科的解释: XSS又叫CSS (Cross Site Script) ,跨站脚本攻击。它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。
2、它与SQL注入攻击类似,SQL注入攻击中以SQL语句作为用户输入,从而达到查询/修改/删除数据的目的,而在xss攻击中,通过插入恶意脚本,实现对用户游览器的控制,获取用户的一些信息。
Filter过滤器
Filter过滤器是一种比较实用的东西,可以过滤不良信息,对提交来的信息进行处理。是Request和Response之间的传输纽带。
HttpServletRequestWrapper
Filter是这样一种Java对象,它能能在request到达servlet的服务方法之前拦截HttpServletRequest对象,而在服务方 法转移控制后又能拦截HttpServletResponse对象。
你可以使用filter来实现特定的任务,比如验证用户输入,以及压缩web内容。但HttpServletRequest对象的参数是不可改变的,这极大地缩减了filter的应用范围。至少在一半的时间里,你希望可以改变准备传送给 filter的对象。
幸运的是,尽管你不能改变不变对象本身,但你却可以通过使用装饰模式来改变其状态。
所以:在Filter中修改后台Controller中获取到的HttpServletRequest中的参数,只需要在Filter中自定义一个类继承于HttpServletRequestWrapper,并复写getParameterNames、getParameter、getParameterValues等方法即可。
方法:
要创建HttpServletRequest的装饰类,你需要继承HttpServletRequestWrapper并且覆盖你希望改变的方法。
防XSS注入流程:
1、自定义包装类XssHttpServletRequestWrapper,继承HttpServletRequestWrapper,重写getInputStream(),getParameter(String name),getParameterValues(String name)等方法。
2、自定义过滤器XssFilter,过滤所有链接,这样所有方法中request.getParameter();就能调用自定义包装类里面重写的方法,进行xss过滤。
官方给出的redis使用原则:
1. 查询数据的时候,尽量减少DB查询,DB主要负责写数
2. 尽量不使用 LEFt JOIN 等关联查询,缓存命中率不高,还浪费内存
3. 多使用单表查询,缓存命中率最高
4. 数据库 insert 、 update 、 delete 时,同步更新缓存数据
5. 合理运用Redis数据结构,也许有质的飞跃
6. 对于访问量不大的项目,使用缓存只会增加项目的复杂性。
Redis切面处理类RedisAspect,使用切面定义是否启用redis缓存。
原理:
ProceedingJoinPoint:用于环绕通知,使用proceed()方法来执行目标方法,当不打开redis缓存时候,跳过RedisUtils的所有方法执行。
SwaggerConfig中开启swagger2配置的支持。app模块使用swagger的注解。
项目逻辑:
@SysLog("保存菜单")
后端效验使用的是Hibernate Validator校验框架。且自定义ValidatorUtils工具类,用来效验数据。
通过分析上面的代码,我们来理解Hibernate Validator校验框架的使用。
其中,username属性,表示保存或修改用户时,都会效验username属性; 而password属
性,表示只有保存用户时,才会效验password属性,也就是说,修改用户时,password可以
不填写,允许为空。
如果不指定属性的groups,则默认属于javax.validation.groups.Default.class分组,可以通
过ValidatorUtils.validateEntity(user)进行效验。
项目逻辑:
8、多数据源
多数据源的应用场景,主要针对跨多个MySQL实例的情况;如果是同实例中的多个数据库,则没必要使用多数据源。
实现数据源切换的功能就是自定义一个类扩展AbstractRoutingDataSource抽象类,其实该相当于数据源DataSourcer的路由中介,可以实现在项目运行时根据相应key值切换到对应的数据源DataSource上。
从源码可以看出AbstractRoutingDataSource继承了AbstractDataSource并实现了InitializingBean,AbstractRoutingDataSource的getConnection()方法调用了determineTargetDataSource()的该方法,这里重点看determineTargetDataSource()方法代码,方法里使用到了determineCurrentLookupKey()方法,它是AbstractRoutingDataSource类的抽象方法,也是实现数据源切换要扩展的方法,该方法的返回值就是项目中所要用的DataSource的key值,拿到该key后就可以在resolvedDataSource中取出对应的DataSource,如果key找不到对应的DataSource就使用默认的数据源。
自定义类扩展AbstractRoutingDataSource类时就是要重写determineCurrentLookupKey()方法来实现数据源切换功能。
实现多数据源:
步骤1,在spring boot中,增加多数据源的配置
步骤2,扩展Spring的AbstractRoutingDataSource抽象类,
AbstractRoutingDataSource中的抽象方法determineCurrentLookupKey是实现多数据
源的核心,并对该方法进行Override
步骤3,配置DataSource,指定数据源的信息
步骤4,通过注解,实现多数据源