SSH框架电子商城-系统技术分析

SSH

SSH即Struts+Spring+Hibernate,是典型的J2EE三层结构,分为表现层、中间层和数据访问层。三层体系将数据表现、业务逻辑和数据访问分开。业务逻辑、数据访问、权限拦截及合法性校验等工作放在中间层处理,客户端不直接与数据库交互,而是通过组件与中间层建立连接,再由中间层与数据库打交道。框架相当于一个工具,比如你在挖矿的时候,需要一把铲子,和一个动作,框架就是这把铲子和动作。在各种整合的方案中,SSH已成为JavaEE应用开发的主流体系,原理图如下:

MySQL

MySQL是一个开放源码的小型关联式数据库管理系统,凭借速度快、轻量级、成本低、优化的SQL查询算法、开源免费等优势被广泛地应用在Internet上的中小型网站中。

MySQL优点:

1.有效利用服务器资源:当单个服务器资源过盛时,可以充分利用剩余的资源来提供更多的服务。

2.节约服务器资源:当公司资金紧张,但数据库又需要数据库之间各自提供服务时,并且还想使用主从复制,这时多实例就再好不过了。

3.方便后期架构扩展:当公司的某个项目才启动时,启动初期并不一定有很大的用户量,因此可以用一组物理数据库服务器在上面部署多个实例,方便后续扩展、迁移。

jdbc.properties添加如下信息:

jdbc.driver = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/ITester_B2CShop
jdbc.user = root
jdbc.password =123

C3P0

C3p0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。它有效的提高了数据库与应用程序之间的访问效率,并且具有编码简单、易用性好、支持连接复用的特性。

具体如何使用c3p0连接池呢?

(1)下载jar包;

(2)配置文件;

作为一个数据库连接池自然有很多参数要设置,当然就算不设置也有默认的,不过那不一定能满足要求。配置文件没有什么特别的要求,可以是xml也可以是properties甚至与txt都行,下面是我们要做的电子商城的C3P0连接池配置:

 C3P0连接池配置:
* 引入外部属性文件:
* jdbc.properties
* 配置连接池:
  <!-- 配置连接池: -->
  <!-- 引入外部属性文件 -->
  <context:property-placeholder location="classpath:jdbc.properties"/>
  <!-- 配置C3P0连接池: -->
  <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driver}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.user}"/>
    <property name="password" value="${jdbc.password}"/>
  </bean>

连接池的好处是不必每次连接都新建一个连接,可以直接从池中取,节约内存资源。

EasyUI

JQuery EasyUI是一种基于jQuery、Angular.、Vue和React的用户界面插件集合。是基于JQuery的UI插件集合体,只需要开发者了解一些简单的HTML标签,就可以打造出功能丰富并且美观的UI界面,而且也有利于节省网页的开发时间和规模。

EasyUI优点:

1.可以创建现代化,互动,JavaScript应用程序,提供必要的功能。

2.不需要写很多代码,只需要通过编写一些简单HTML标记,就可以定义用户界面。

3.是个完美支持HTML5网页的完整框架。

4.节省网页开发的时间和规模。

5.很简单但功能强大。

EasyUI包括以下Demo:

JavaMail邮件服务

JavaMail是处理电子邮件的应用程序接口,它预置了一些最常用的邮件传送协议的实现方法。JavaMail协议包括定义了邮件客户端软件的简单邮件传输协议(SMTP )以及邮件客户端与POP3服务器的通讯规则的邮局协议(POP3)。JavaMail发送邮件的原理图如下:

JavaMail 下载地址: https://github.com/javaee/javamail/releases

下载的这个JavaMail版本,包含了SMTP, IMAP, 和 POP3 协议的实现。

JavaMail API 按照功能可以划分为如下三大类:

1.创建和解析邮件的API;

2.发送邮件的API;

3.接收邮件的API;

在理解下面通过代码实现邮件的发送时,我们可以将邮件发送假想为火箭运载卫星发送。其中Message 是卫星,Transport 是火箭,而卫星和火箭的构建都需要 Session 的帮助,这样的关系更加便于记忆。

使用 JavaMail 发送简单的纯文本邮件:

import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

/**
 * 邮件发送工具类
 * @author ITester.coco
 *
 */
public class MailUitls {
  /**
   * 发送邮件的方法
   * @param to  :收件人
   * @param code  :激活码
   */
  public static void sendMail(String to,String code){
    /**
     * 1.获得一个Session对象.
     * 2.创建一个代表邮件的对象Message.
     * 3.发送邮件Transport
     */
    // 1.获得连接对象
    Properties props = new Properties();
    props.setProperty("mail.host", "localhost");
    Session session = Session.getInstance(props, new Authenticator() {

      @Override
      protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication("service@shop.com", "111");
      }

    });
    // 2.创建邮件对象:
    Message message = new MimeMessage(session);
    // 设置发件人:
    try {
      message.setFrom(new InternetAddress("service@shop.com"));
      // 设置收件人:
      message.addRecipient(RecipientType.TO, new InternetAddress(to));
      // 抄送 CC   密送BCC
      // 设置标题
      message.setSubject("来自ITester商城官方激活邮件");
      // 设置邮件正文:
      message.setContent("<h1>ITester商城官方激活邮件!点下面链接完成激活操作!</h1><h3><a href='http://192.168.36.103:8080/shop/user_active.action?code="+code+"'>http://192.168.36.103:8080/shop/user_active.action?code="+code+"</a></h3>", "text/html;charset=UTF-8");
      // 3.发送邮件:
      Transport.send(message);
    } catch (AddressException e) {
      e.printStackTrace();
    } catch (MessagingException e) {
      e.printStackTrace();
    }

  }

  public static void main(String[] args) {
    sendMail("ITester@B2CShop.com","HelloWorld");
  }
}

邮件发送问题:

1.发件人的邮箱账户名和密码:有的邮箱设置了独立密码,还有的必须用授权码登录(qq邮箱)。

2.发件人的SMTP服务器地址:一般是 smtp.xxx.com,比如163邮箱是smtp.163.com,qq邮箱是smtp.qq.com。

3.有可能收件人地址,发件人地址等信息都正确,控制台也打印了正确的信息,但是在收件箱就是收不到信息。这是因为可能收件箱服务器拒收了你发的邮件(比如认为邮件是广告),这时候可能在垃圾箱里能找到,可能找不到。解决办法是重复的邮件内容不要多次发送,或者更换收件箱试试。

易宝支付

易宝支付是中国支付行业的开创者和领导者,也是互联网金融(ITFIN)和移动互联领军企业,国内领先的第三方电子支付服务提供商,为个人网上银行客户提供了网上消费支付结算方式,使客户真正做到足不出户,网上购物。其原理图如下:

方式:通过中间企业再连接到在线银行;

特征:风险大,适合小型的付款,维护容易;

创建Utils工具类 :PaymentUtil.java 这个类是用商户(企业)的密钥(易宝分配的)和一些付款的信息加起来产生验证字段。(以下展示部分代码)

public class PaymentUtil {
private static String encodingCharset = "UTF-8";
  /**
   * 生成hmac方法
   * @param p0_Cmd 业务类型
   * @param p1_MerId 商户编号
   * @param p2_Order 商户订单号
   * @param p3_Amt 支付金额
   * @param p4_Cur 交易币种
   * @param p5_Pid 商品名称
   * @param p6_Pcat 商品种类
   * @param p7_Pdesc 商品描述
   * @param p8_Url 商户接收支付成功数据的地址
   * @param p9_SAF 送货地址
   * @param pa_MP 商户扩展信息
   * @param pd_FrpId 银行编码
   * @param pr_NeedResponse 应答机制
   * @param keyValue 商户密钥
   * @return
   */
  public static String buildHmac(String p0_Cmd,String p1_MerId,
      String p2_Order, String p3_Amt, String p4_Cur,String p5_Pid, String p6_Pcat,
      String p7_Pdesc,String p8_Url, String p9_SAF,String pa_MP,String pd_FrpId,
      String pr_NeedResponse,String keyValue) {
    StringBuilder sValue = new StringBuilder();
    // 业务类型
    sValue.append(p0_Cmd);
    // 商户编号
    sValue.append(p1_MerId);
    // 商户订单号
    sValue.append(p2_Order);
    // 支付金额
    sValue.append(p3_Amt);
    // 交易币种
    sValue.append(p4_Cur);
    // 商品名称
    sValue.append(p5_Pid);
    // 商品种类
    sValue.append(p6_Pcat);
    // 商品描述
    sValue.append(p7_Pdesc);
    // 商户接收支付成功数据的地址
    sValue.append(p8_Url);
    // 送货地址
    sValue.append(p9_SAF);
    // 商户扩展信息
    sValue.append(pa_MP);
    // 银行编码
    sValue.append(pd_FrpId);
    // 应答机制
    sValue.append(pr_NeedResponse);

    return PaymentUtil.hmacSign(sValue.toString(), keyValue);
  }

  /**
   * 返回校验hmac方法
   * 
   * @param hmac 支付网关发来的加密验证码
   * @param p1_MerId 商户编号
   * @param r0_Cmd 业务类型
   * @param r1_Code 支付结果
   * @param r2_TrxId 易宝支付交易流水号
   * @param r3_Amt 支付金额
   * @param r4_Cur 交易币种
   * @param r5_Pid 商品名称
   * @param r6_Order 商户订单号
   * @param r7_Uid 易宝支付会员ID
   * @param r8_MP 商户扩展信息
   * @param r9_BType 交易结果返回类型
   * @param keyValue 密钥
   * @return
   */
  public static boolean verifyCallback(String hmac, String p1_MerId,
      String r0_Cmd, String r1_Code, String r2_TrxId, String r3_Amt,
      String r4_Cur, String r5_Pid, String r6_Order, String r7_Uid,
      String r8_MP, String r9_BType, String keyValue) {
    StringBuilder sValue = new StringBuilder();
    // 商户编号
    sValue.append(p1_MerId);
    // 业务类型
    sValue.append(r0_Cmd);
    // 支付结果
    sValue.append(r1_Code);
    // 易宝支付交易流水号
    sValue.append(r2_TrxId);
    // 支付金额
    sValue.append(r3_Amt);
    // 交易币种
    sValue.append(r4_Cur);
    // 商品名称
    sValue.append(r5_Pid);
    // 商户订单号
    sValue.append(r6_Order);
    // 易宝支付会员ID
    sValue.append(r7_Uid);
    // 商户扩展信息
    sValue.append(r8_MP);
    // 交易结果返回类型
    sValue.append(r9_BType);
    String sNewString = PaymentUtil.hmacSign(sValue.toString(), keyValue);
    return sNewString.equals(hmac);
  }

  /**
   * @param aValue
   * @param aKey
   * @return
   */
  public static String hmacSign(String aValue, String aKey) {
    byte k_ipad[] = new byte[64];
    byte k_opad[] = new byte[64];
    byte keyb[];
    byte value[];
    try {
      keyb = aKey.getBytes(encodingCharset);
      value = aValue.getBytes(encodingCharset);
    } catch (UnsupportedEncodingException e) {
      keyb = aKey.getBytes();
      value = aValue.getBytes();
    }

    Arrays.fill(k_ipad, keyb.length, 64, (byte) 54);
    Arrays.fill(k_opad, keyb.length, 64, (byte) 92);
    for (int i = 0; i < keyb.length; i++) {
      k_ipad[i] = (byte) (keyb[i] ^ 0x36);
      k_opad[i] = (byte) (keyb[i] ^ 0x5c);
    }

    MessageDigest md = null;
    try {
      md = MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException e) {

      return null;
    }
    md.update(k_ipad);
    md.update(value);
    byte dg[] = md.digest();
    md.reset();
    md.update(k_opad);
    md.update(dg, 0, 16);
    dg = md.digest();
    return toHex(dg);
  }

以上

That‘s all

下一期将具体的介绍系统设计

包括项目的运行环境

项目概要设计与详细设计

敬请期待

ITester软件测试小栈

本文分享自微信公众号 - ITester软件测试小栈(ITestingA)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-10-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏用户5521492的专栏

Spring 复盘(三) | Bean 的生命周期

在传统的 Java 应用中,bean 的生命周期很简单,使用 Java 关键字 new 进行Bean 的实例化,然后该 Bean 就能够使用了。一旦 bean ...

9430
来自专栏用户5521492的专栏

为什么要放弃 JSP ?

随着时代的发展,渐渐的许多大中小公司开始把前后端的界限分的越来越明确,前端工程师只负责前端的事情,后端工程师只管后端的事情。正所谓术业有专攻,一个人如果什么都会...

13360
来自专栏用户5521492的专栏

代码中太多 if else 怎么办?

前段时间,我将公司系统中的批量审单的功能进行了重构,用到了java的并发编程进行异步化处理,数据库的乐观锁机制处理多线程并发更新数据。其中批量审单的业务处理涉及...

10130
来自专栏爱敲代码的猫

Thymeleaf标准表达式语法

Thymeleaf的主要目标是为您的开发工作流程带来优雅的自然模板 - 可以在浏览器中正确显示的HTML,也可以用作静态原型,从而在开发团队中实现更强大的协作。

7820
来自专栏用户5521492的专栏

Java 基础 | Object 源码解

Java 是一门面向对象的语言,在 Java 里面一切都可以看作是一个对象,而 Java 里面所有的对象都默认继承于 Object 类,所以狗哥今天就从源码角度...

8320
来自专栏爱敲代码的猫

String,StringBuffrer,StringBuilder 三兄弟

String这个类是Java中使用得最频繁的类之一,并且又是各大公司面试喜欢问到的地方,今天就来和大家一起学习一下String、StringBuilder和St...

9240
来自专栏用户5521492的专栏

Java面试官:给Java面试者的八点建议

www.cnblogs.com/JavaArchitect/p/10011253.html

10130
来自专栏用户5521492的专栏

史上最难10道 Java 面试题!

这是我收集的10个最棘手的Java面试问题列表。这些问题主要来自 Java 核心部分 ,不涉及 Java EE 相关问题。你可能知道这些棘手的 Java 问题的...

12430
来自专栏用户5521492的专栏

面试官常问的 20 道 Java 题目(附答案)

2. Math.round(11.5)等于多少?Math.round(-11.5)等于多少?

7250
来自专栏爱敲代码的猫

Golang 包管理(一)

我们在使用其他语言,比如Java,是有包的概念的,它是Java语言中组织我们的Java文件的一个概念,比如java.lang这个包,他里面有很多我们常用的类,比...

7930

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励