美文网首页我爱编程
第11章 我们可做的更好

第11章 我们可做的更好

作者: cuzz_ | 来源:发表于2018-05-21 18:57 被阅读0次

对关键配置信息进行DES加密

利用PropertyPlaceholderConfigurer实现对称加密

  • 编写一个DESUtil的类对称加密
package com.imooc.o2o.util;

import java.security.Key;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class DESUtil {

    private static Key key;
    private static String KEY_STR = "myKey";
    private static String CHARSETNAME = "UTF-8";
    private static String ALGORITHM = "DES";

    static {
        try {
            // 生成DES算法对象
            KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);
            // 运行SHA1安全策略
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(KEY_STR.getBytes());
            generator.init(secureRandom);
            // 生成秘钥对象
            key = generator.generateKey();
            generator = null;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String getEncryptString(String str) {
        // 基于BADE64编码  接受byte[]并转化为String
        BASE64Encoder base64encoder = new BASE64Encoder();
        try {
            // 按UTF8编码
            byte[] bytes = str.getBytes(CHARSETNAME);
            // 获取加密对象
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            // 初始化密码信息
            cipher.init(Cipher.ENCRYPT_MODE, key);
            // 加密
            byte[] doFinal = cipher.doFinal(bytes);
            // byte[] to encode好的string返回
            return base64encoder.encode(doFinal);
        } catch (Exception e) {
            // TODO: handle exception
            throw new RuntimeException(e);
        }
    }


    public static String getDecryptString(String str) {
        BASE64Decoder base64decoder = new BASE64Decoder();
        try {
            byte[] bytes = base64decoder.decodeBuffer(str);
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] doFinal = cipher.doFinal(bytes);
            return new String(doFinal, CHARSETNAME);
        } catch (Exception e) {
            // TODO: handle exception
            throw new RuntimeException(e);
        }
    }
    
    public static void main(String[] args) {
        System.out.println(getEncryptString("root"));
        System.out.println(getEncryptString("123456"));
    }

}

输出
WnplV/ietfQ=
QAHlVoUc49w=

  • 在jdbc.properties中把关键信息改为加密的
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/o2o?useUnicode=true&characterEncoding=utf8
jdbc.username=WnplV/ietfQ=
jdbc.password=QAHlVoUc49w=

解密

  • EncryptPropertyPlaceholderConfigurer类
package com.imooc.o2o.util;

import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;

public class EncryptPropertyPlaceholderConfigurer extends
        PropertyPlaceholderConfigurer {
    // 需要解密的数组
    private String[] encryptPropNames = { "jdbc.username", "jdbc.password" };

    @Override
    protected String convertProperty(String propertyName, String propertyValue) {
        if (isEncryptProp(propertyName)) {
            String decryptValue = DESUtil.getDecryptString(propertyValue);
            return decryptValue;
        } else {
            return propertyValue;
        }
    }

    private boolean isEncryptProp(String propertyName) {
        for (String encryptpropertyName : encryptPropNames) {
            if (encryptpropertyName.equals(propertyName))
                return true;
        }
        return false;
    }
}

配置

    <!-- <context:property-placeholder location="classpath:jdbc.properties" /> -->
    <bean class="com.imooc.o2o.util.EncryptPropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
            </list>
        </property>
        <property name="fileEncoding" value="UTF-8"></property>
    </bean>

加入缓冲技术

学习目标

  • 了解什么是redis和Jedis
  • Redis配置
  • Jedis的基本通用函数配置以及使用

Reids理论知识

redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。 [1]

Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。

redis的官网地址,非常好记,是redis.io。(特意查了一下,域名后缀io属于国家域名,是british Indian Ocean territory,即英属印度洋领地)

应用场景

把不经常更改的数据,放到缓存中


image.png

redis配置

  • 在pom.xml中添加依赖包
    <!-- redis客户端:Jedis -->
    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.9.0</version>
    </dependency>
  • 在resources/spring的配置文件下新进一个spring-redis.xml文件
<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

    <!--Redis 连接池的设置-->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!--总数-->
        <property name="maxTotal" value="${redis.pool.maxActive}" />
        <!--最大空闲数-->
        <property name="maxIdle" value="${redis.pool.maxIdle}" />
        <property name="maxWaitMillis" value="${redis.pool.maxWait}" />
        <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
    </bean>

    <!--创建Redis连接池 并做相关配置-->
    <bean id="jedisWritePool" class="com.imooc.o2o.cache.JedisPoolWriper"
        depends-on="jedisPoolConfig">
        <constructor-arg index="0" ref="jedisPoolConfig" />
        <constructor-arg index="1" value="${redis.hostname}" />
        <constructor-arg index="2" value="${redis.port}" type="int" />
    </bean>

    <!--创建Redis工具类 封装好Redis的连接以进行相关操作-->
    <bean id="jedisUtil" class="com.imooc.o2o.cache.JedisUtil" scope="singleton">
        <property name="jedisPool">
            <ref bean="jedisWritePool" />
        </property>
    </bean>

    <bean id="jedisKeys" class="com.imooc.o2o.cache.JedisUtil$Keys"
          scope="singleton">
        <constructor-arg ref="jedisUtil"></constructor-arg>
    </bean>
    <bean id="jedisStrings" class="com.imooc.o2o.cache.JedisUtil$Strings"
        scope="singleton">
        <constructor-arg ref="jedisUtil"></constructor-arg>
    </bean>
    <bean id="jedisLists" class="com.imooc.o2o.cache.JedisUtil$Lists"
        scope="singleton">
        <constructor-arg ref="jedisUtil"></constructor-arg>
    </bean>
    <bean id="jedisSets" class="com.imooc.o2o.cache.JedisUtil$Sets"
        scope="singleton">
        <constructor-arg ref="jedisUtil"></constructor-arg>
    </bean>
    <bean id="jedisHash" class="com.imooc.o2o.cache.JedisUtil$Hash"
        scope="singleton">
        <constructor-arg ref="jedisUtil"></constructor-arg>
    </bean>


</beans>   
  • 添加redis.properties文件
redis.hostname=127.0.0.1
redis.port=6379
redis.database=0
redis.pool.maxActive=600
redis.pool.maxIdle=300
redis.pool.maxWait=3000
redis.pool.testOnBorrow=true
  • JedisPoolWriper类
package com.imooc.o2o.cache;

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * 强指定redis的JedisPool接口构造函数,这样才能在centos成功创建jedispool
 * 
 * @author xiangze
 *
 */
public class JedisPoolWriper {
    private JedisPool jedisPool;

    public JedisPoolWriper(final JedisPoolConfig poolConfig, final String host,
            final int port) {
        try {
            jedisPool = new JedisPool(poolConfig, host, port);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public JedisPool getJedisPool() {
        return jedisPool;
    }

    public void setJedisPool(JedisPool jedisPool) {
        this.jedisPool = jedisPool;
    }

}
  • jedisUtil
public class JedisUtil {
    /**
     * 缓存生存时间
     */
    private final int expire = 60000;
    /**
     * 操作Key的方法
     */
    public Keys KEYS;
    /**
     * 对存储结构为String类型的操作
     */
    public Strings STRINGS;
    /**
     * 对存储结构为List类型的操作
     */
    public Lists LISTS;
    /**
     * 对存储结构为Set类型的操作
     */
    public Sets SETS;
    /**
     * 对存储结构为HashMap类型的操作
     */
    public Hash HASH;

    private JedisPool jedisPool;
}

添加平台账号

Spring拦截器

学习目标

  • 实现登入验证
  • 实现店铺权限验证
  • 掌握拦截器

添加拦截器

  • 在sping-web.xml中添加
    <!-- 5.权限拦截器 -->
    <mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/shop/**" />
        <mvc:exclude-mapping path="/shop/ownerlogin" />
        <mvc:exclude-mapping path="/shop/ownerlogincheck" />
        <mvc:exclude-mapping path="/shop/logout" />
        <mvc:exclude-mapping path="/shop/register" />
        <bean id="ShopInterceptor" class="com.imooc.o2o.interceptor.shop.ShopLoginInterceptor" />
    </mvc:interceptor>
    <mvc:interceptor>
        <mvc:mapping path="/shop/**" />
        <mvc:exclude-mapping path="/shop/ownerlogin" />
        <mvc:exclude-mapping path="/shop/ownerlogincheck" />
        <mvc:exclude-mapping path="/shop/register" />
        <!-- shoplist page -->
        <mvc:exclude-mapping path="/shop/shoplist" />
        <mvc:exclude-mapping path="/shop/logout" />
        <mvc:exclude-mapping path="/shop/list" />
        <!-- changepsw page -->
        <mvc:exclude-mapping path="/shop/changepsw" />
        <mvc:exclude-mapping path="/shop/changelocalpwd" />
        <!-- ownerbind page -->
        <mvc:exclude-mapping path="/shop/ownerbind" />
        <mvc:exclude-mapping path="/shop/bindlocalauth" />
        <!-- shopmanage page -->
        <mvc:exclude-mapping path="/shop/shopmanage" />
        <!-- shopedit page -->
        <mvc:exclude-mapping path="/shop/shopedit" />
        <mvc:exclude-mapping path="/shop/getshopbyid" />
        <mvc:exclude-mapping path="/shop/getshopinitinfo" />
        <mvc:exclude-mapping path="/shop/registershop" />
        <bean id="ShopPermissionInterceptor"
              class="com.imooc.o2o.interceptor.shop.ShopPermissionInterceptor" />
    </mvc:interceptor>
    <mvc:interceptor>
        <mvc:mapping path="/superadmin/**" />
        <mvc:exclude-mapping path="/superadmin/login" />
        <mvc:exclude-mapping path="/superadmin/logincheck" />
        <mvc:exclude-mapping path="/superadmin/main" />
        <mvc:exclude-mapping path="/superadmin/top" />
        <bean id="SuperAdminInterceptor"
              class="com.imooc.myo2o.interceptor.superadmin.SuperAdminLoginInterceptor" />
    </mvc:interceptor>
    </mvc:interceptors>
  • 添加一个HandlerInterceptorAdapter继承类
public class ShopLoginInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        // 从session中取出用户信息来
        Object userObj = request.getSession().getAttribute("user");
        if (userObj != null) {
            // 
            PersonInfo user = (PersonInfo) userObj;
            if (user != null && user.getUserId() != null
                    && user.getUserId() > 0 && user.getEnableStatus() == 1)
                return true;
        }
        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println("<script>");
        out.println("window.open ('" + request.getContextPath()
                + "/shop/ownerlogin','_self')");
        out.println("</script>");
        out.println("</html>");
        return false;
    }
}
  • 添加一个ShopPermissionInterceptor,我们要排除一些不能拦截的东西
public class ShopPermissionInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        Shop currentShop = (Shop) request.getSession().getAttribute(
                "currentShop");
        @SuppressWarnings("unchecked")
        List<Shop> shopList = (List<Shop>) request.getSession().getAttribute(
                "shopList");
        if (currentShop != null && shopList != null) {
            for (Shop shop : shopList) {
                if (shop.getShopId() == currentShop.getShopId()) {
                    return true;
                }
            }
        }
        return false;
    }
}

相关文章

  • 第11章 我们可做的更好

    对关键配置信息进行DES加密 利用PropertyPlaceholderConfigurer实现对称加密 编写一个...

  • 做更好的我们

    什么是合适在一起? 我觉得只有在一起共同进步,互相理解并支持才是合适的。婚姻生活不仅有家里的小日子,而且还...

  • 我们可以做的更好!

    本人有轻微“强迫症”,尤其无法容忍微信上的“小红点”,逢点儿必点。 春节期间,微信上的小红点数字每天均过百,无法一...

  • 感觉好才会做更好

    感觉好才会做更好——教育心理学分享第438天 感觉好才会做更好,有人说,我感觉好的时候,也做不好,为什么呢? 我们...

  • 我们可以做的更好2

    加入缓存技术,使用Redis数据库 1、首先在pom.xml中加入,jedis是java对redis操作的jar包...

  • 我们可以做的更好1

    一、加密连接数据库明文密码 步骤:1、对jdbc.property文件的用户名和密码进行加密,我们就需要创建一个加...

  • 我们本可以做的更好

    前一阵看到一篇文章《人生最痛苦的事情,不是我不行,而是我本可以》,一个农民工在一所中学务工中午休息时在教室黑板上写...

  • 我们,还可以做的更好!

    精雕细琢的精品,出自匠心独具的耐心习作的匠人之手。 兜兜转转社会20多年,除了8岁之外的不懂事的那几年,我已在这个...

  • 偶悟

    做人:诚实、守信、笃行。 读书:只是遇到更好的自己。 生活:证明我更坚强。 未来:可期,可遇。 做更好的自...

  • 如果人生可以重来

    正如那部电视剧,如果岁月可回首 或许我们会牢牢珍惜我们拥有的 或许我们会将自己的做的更好 如果人生可以重来,我是一...

网友评论

    本文标题:第11章 我们可做的更好

    本文链接:https://www.haomeiwen.com/subject/vjrwrftx.html