从零开始写项目第二篇【登陆注册、聊天、收藏夹模块】(二)

简介: 笔记

我是使用qq邮箱去发送邮件的:要去qq邮箱申请授权码才能发送

14.jpg

在看上边资料的时候,发现邮件其实用freemarker来做模版会很不错(因为邮箱的只有少部分内容是变的),于是又去找freemarker与spring整合的资料:

http://blog.csdn.net/lpjishu/article/details/51902024

http://blog.csdn.net/u013111003/article/details/52118514

http://www.jb51.net/article/43200.htm

上诉的maven坐标:

<!-- Javamail与Spring-context-support support包也与freemarker整合 -->
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>3.2.3.RELEASE</version>
        </dependency>
        <!--freemarker-->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.18</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>

首先构建出发送邮件的模版数据、然后使用JavaMail发送带HTML格式的数据就行了。

/**
 * 邮件服务类,提供发送邮件的功能
 */
@Service
public class EmailService {
    @Autowired
    private JavaMailSender mailSender;
    @Autowired
    private SimpleMailMessage simpleMailMessage;
    /**
     * 使用mimeMessage发送的HTML格式的邮件。
     * @param user
     * @param content
     * @throws Exception
     */
    public void sendEmail(User user, String content,String url) throws Exception {
        String returnText = createSendData(user, content,url);
        // TODO 问题是出在发送邮件很慢 6086ms,解析freemarker才60ms 待优化
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
        messageHelper.setFrom(simpleMailMessage.getFrom());
        messageHelper.setSubject(simpleMailMessage.getSubject());
        //接受人
        messageHelper.setTo(user.getUserEmail());
        //内容,是HTML格式
        messageHelper.setText(returnText, true);
        mailSender.send(mimeMessage);
    }
    /**
     * 使用freemarker创建要发送的邮件内容
     * @param user    封装了要发送邮件的信息
     * @param content  发送的目的是什么(一个模版、多种邮件)
     * @param url       操作的地址路径是什么
     * @return HTML页面的内容
     * @throws Exception
     */
    public String createSendData(User user, String content,String url) throws Exception {
        Map<String, Object> map = new HashMap();
        map.put("nickName", user.getUserNickname());
        map.put("content", content);
        map.put("url", url);
        map.put("encodeUrl", Base64Util.encodeData(url));
        String returnText = new FreeMarkerUtils().returnText("email.ftl", map);
        return returnText;
    }
}

freemarker在springmvc配置文件中的配置:

<!-- 同时开启json格式的支持 -->
    <mvc:annotation-driven></mvc:annotation-driven>
    <!-- 扫描所有的controller 但是不扫描service -->
    <context:component-scan base-package="zhongfucheng">
        <context:include-filter type="annotation"
                                expression="org.springframework.stereotype.Controller"/>
        <context:exclude-filter type="annotation"
                                expression="org.springframework.stereotype.Service"/>
    </context:component-scan>
    <!-- 配置Freemarker屬性文件路徑 -->
    <bean id="freemarkerConfiguration" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="location" value="classpath:freemarker.properties"/>
    </bean>
    <!-- 配置freeMarker模板加載地址 -->
    <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <!-- 視圖解析器會在/WEB-INF/ftl/路徑下掃描視圖文件 -->
        <property name="templateLoaderPath" value="/WEB-INF/ftl"/>
        <!-- 设置页面中文乱码问题 -->
        <property name="freemarkerSettings">
            <props>
                <prop key="defaultEncoding">UTF-8</prop>
            </props>
        </property>
        <property name="freemarkerVariables">
            <map>
                <entry key="xml_escape" value-ref="fmXmlEscape"/>
            </map>
        </property>
    </bean>
    <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape"/>
    <!-- 配置freeMarker視圖解析器 -->
    <bean id="freemakerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>
        <!-- 掃描路徑內所有以ftl結尾的文件 -->
        <property name="viewNames">
            <array>
                <value>*.ftl</value>
            </array>
        </property>
        <!-- 设置相关属性 -->
        <property name="cache" value="true"/>
        <property name="contentType" value="text/html; charset=UTF-8"/>
        <property name="exposeRequestAttributes" value="true"/>
        <property name="exposeSessionAttributes" value="true"/>
        <property name="exposeSpringMacroHelpers" value="true"/>
        <property name="requestContextAttribute" value="request"/>
        <!-- 給視圖解析器配置優先級,你可以給之前jsp視圖解析器的值配為2 -->
        <property name="order" value="1"/>
    </bean>
    <!--通用视图解析器-->
    <bean id="viewResolverCommon"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass">
            <value>org.springframework.web.servlet.view.InternalResourceView
            </value>
        </property>
        <property name="order" value="2"/>
    </bean>

在设置freemaker路径的时候发现自己对Java路径的相对路径、绝对路径、项目路径已有些混乱了。后来通过一篇资料又好好地整理一下:

http://www.cnblogs.com/franson-2016/p/5728280.html

  • 我的总结:凡是以“/"开头的都代表绝对路径,在Controller里边"/"前面代表着http://localhost:8080/项目名
  • 无论通过Servlet、还是API获取得到都是在本机上的路径。

很多时候我们的项目路径在不同机器上是不一样的。因此要做到更好的通用性,可以将其在配置文件中配置起来。

15.png

提供一个工具类提取它就行了:

/**
 * 根据key读取配置文件的内容
 *
 */
public class ReadPropertiesUtil {
    public static String readProp(String key) {
        InputStream in = ReadPropertiesUtil.class.getClassLoader().getResourceAsStream("system.properties");
        Properties prop = new Properties();
        try {
            prop.load(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return prop.getProperty(key);
    }
}

扯了这么一大堆,我们的邮件已经能够发出去了

20.jpg

url链接使用了base64进行编码了,其实没什么,就是为了装个逼而已..

maven坐标:

<!--base64编码解码-->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.6</version>
        </dependency>

base64工具类:

/**
 * base64的编码解码
 */
public class Base64Util {
    private static final String UTF_8 = "UTF-8";
    /**
     * 对给定的字符串进行base64解码操作
     */
    public static String decodeData(String inputData) {
        try {
            if (null == inputData) {
                return null;
            }
            return new String(Base64.decodeBase64(inputData.getBytes(UTF_8)), UTF_8);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 对给定的字符串进行base64加密操作
     */
    public static String encodeData(String inputData) {
        try {
            if (null == inputData) {
                return null;
            }
            return new String(Base64.encodeBase64(inputData.getBytes(UTF_8)), UTF_8);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }
}

那么接下来就是点击连接激活账户了,修改一下激活码值就行了。从上边我们已经写到了:激活链接24小时内有效,如果超过了一天用户再点击激活码的时候,那么我们就认为它无效,把数据库的记录删除了,让他重新注册。

/**
     * 激活账户(实际上就是修改表字段的值)
     *
     * @param userId
     * @return
     * @throws Exception
     */
    @RequestMapping("/activate.do")
    public String activate(String userId) throws Exception {
        User user = userService.selectByPrimaryKey(userId);
        String title = "";
        String content = "";
        String subject = "";
        if (user != null) {
            //得到当前时间和邮件时间对比,24小时内
            if (System.currentTimeMillis() - user.getTokenExptime().getTime() < 86400000) {
                user.setActiState(User.ACTIVATION_SUCCESSFUL);
                userService.updateByPrimaryKeySelective(user);
                title = "用户激活页面";
                subject = "用户激活";
                content = "恭喜您成功激活账户";
            } else {
                title = "激活失败页面";
                subject = "用户激活";
                content = "激活链接已超时,请重新注册";
                //删除记录已便用户再次注册
                userService.deleteByPrimaryKey(userId);
            }
        }
        //根据模版生成页面,重定向到页面中
        Map<String, Object> map = new HashedMap();
        map.put("title", title);
        map.put("content", content);
        map.put("subject", subject);
        map.put("path", getProjectPath());
        createCommonHtml("promptPages.ftl", "promptPages.html", map);
        return "redirect:/promptPages.html";
    }


编写登陆模块是用了我比较多的时间的,因为用了首次用了Shiro框架来进行做验证。当时候学的时候并不是学得很深入,于是出现了很多bug,改了几天才把它捋顺了。


登陆页面


登陆页面和注册页面其实是非常类似的,具体的步骤都和注册页面差不多。只不过我在登陆页面中加入了一个验证码:该验证码是动态的gif,是我之前看github项目的时候发现的。觉得挺好看的就拿过来用了。要想使用它就要导入它的相关java类:

16.png

来源github项目:https://github.com/baichengzhou/SpringMVC-Mybatis-Shiro-redis-0.2


登陆后台


我引入了Shiro框架来帮我做认证…

maven坐标:

<!--Shiro与Spring整合-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-web</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.8.3</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>
        <!--Shiro与ehcache整合-->
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache-core</artifactId>
            <version>2.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-ehcache</artifactId>
            <version>1.2.3</version>
        </dependency>

首先来post一下我的基础shiro博文:

https://zhongfucheng.bitcron.com/category/shiro

想要在shiro认证之前能够校验验证码的话,那么就需要我们去自定义表单过滤器了。

/**
 * 自定义一个表单过滤器的目的就是认证流程由自己控制
 */
public class UserFormAuthenticationFilter extends FormAuthenticationFilter {
}

当时候我重写了onAccessDenied()方法,在认证之前去校验验证码的正确性,并且使用ajax来进行提示用户是否有错误信息:

目录
相关文章
|
6月前
|
存储 小程序 前端开发
【易售小程序项目】小程序私聊页面完善(带尾巴聊天气泡组件封装、滑至顶端获取历史聊天数据逻辑优化)【后端基于若依管理系统开发】
【易售小程序项目】小程序私聊页面完善(带尾巴聊天气泡组件封装、滑至顶端获取历史聊天数据逻辑优化)【后端基于若依管理系统开发】
29 0
|
7月前
|
容器
美多商城项目(十二)-功能补充
美多商城项目(十二)-功能补充
|
11月前
|
编解码 数据可视化 定位技术
Axure交互大全 全交互案例模板及视频教程
Axure交互大全 全交互案例模板及视频教程
|
小程序 JavaScript 前端开发
目前为止最全的微信小程序项目实例
目前为止最全的微信小程序项目实例
250 0
|
Web App开发 JavaScript BI
|
小程序
视频号主页,实现一键添加个人微信功能,留客更方便,真香
在视频号主页放置添加微信的按钮,其实微信已经支持了,只不过只支持企业微信,不支持个人微信,那怎么办,只能自己实现了。
356 0
视频号主页,实现一键添加个人微信功能,留客更方便,真香
|
小程序 UED 开发者
小程序开发必备功能的吐血整理【个人中心界面样式大全】
小程序开发必备功能的吐血整理【个人中心界面样式大全】
427 1
小程序开发必备功能的吐血整理【个人中心界面样式大全】
|
前端开发 JavaScript 测试技术
接口测试平台代码实现番外:主页改版-6
本节我们来实现下那三个饼形图的后台逻辑,不过我这里只做其中一个的,其他俩个留着日后再用。 也就是用户的 资源占平台总的比。资源暂时定为项目数比 接口数比 用例数 。 这里大家可以自行设计,本教程只演示如何实现这个流程。
接口测试平台代码实现番外:主页改版-6
|
测试技术
接口测试平台代码实现番外:主页改版-7
接口测试平台代码实现番外:主页改版-7
接口测试平台代码实现番外:主页改版-7