第4章 店铺注册功能模块

学习目标

  • 连接数据库
  • Mybatis数据表映射关系的配置
  • dao -> service -> controller层代码的编写,Junit的使用
  • Session,图片处理工具Thumbnailator的使用
  • suimobile前端设计与开发

Dao层

创建店铺

  • 创建ShopDao 接口
package com.imooc.o2o.dao;

import com.imooc.o2o.entity.Shop;

public interface ShopDao {
    // 新增店铺 返回1成功 返回-1失败
    int insertShop(Shop shop);
}
  • 创建ShopDao.xml映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.imooc.o2o.dao.ShopDao">
    <!--useGeneratedKeys 返回主键-->
    <!--数据的列keyColumn="shop_id" 与属性对应keyProperty="shopId"-->
    <insert id="insertShop" useGeneratedKeys="true" keyColumn="shop_id" keyProperty="shopId">
      INSERT INTO
      tb_shop(owner_id, area_id, shop_category_id,shop_name,
      shop_desc, shop_addr, phone, shop_img, priority, create_time,
      last_edit_time, enable_status, advice)
      VALUES
      (#{owner.userId}, #{area.areaId}, #{shopCategory.shopCategoryId},
      #{shopName}, #{shopDesc}, #{shopAddr}, #{phone},
      #{shopImg}, #{priority}, #{createTime},
       #{lastEditTime}, #{enableStatus}, #{advice})
    </insert>
</mapper>
  • 测试,新建ShopDaoTest
    测试前,由于要用到两个外键,所有先在数据表中先添加两条数据


    image.png
package com.imooc.o2o.dao;

import com.imooc.o2o.BaseTest;
import com.imooc.o2o.entity.Area;
import com.imooc.o2o.entity.PersonInfo;
import com.imooc.o2o.entity.Shop;
import com.imooc.o2o.entity.ShopCategory;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;

import static org.junit.Assert.assertEquals;

public class ShopDaoTest extends BaseTest {
    @Autowired
    private ShopDao shopDao;

    @Test
    public void testInsertShop() {
        Shop shop = new Shop();

        PersonInfo owner = new PersonInfo();
        Area area = new Area();
        ShopCategory shopCategory = new ShopCategory();

        owner.setUserId(1L);
        area.setAreaId(2);
        shopCategory.setShopCategoryId(1L);

        shop.setOwner(owner);
        shop.setArea(area);
        shop.setShopCategory(shopCategory);
        shop.setShopName("测试的店铺");
        shop.setShopDesc("test");
        shop.setPhone("test");
        shop.setShopImg("test");
        shop.setCreateTime(new Date());
        shop.setEnableStatus(1);
        shop.setAdvice("审核中");
        int effectedNum = shopDao.insertShop(shop);
        assertEquals(1, effectedNum);
    }
}
  • 测试结果


    image.png

    image.png

更新店铺

  • 在ShopDao接口中,新增一个更新商铺的方法
    // 更新店铺信息
    int updateShop(Shop shop);
  • 在mapper/ShopDao.xml文件里添加相应的映射
    <!--更新商店-->
    <!--支持动态sql-->
    <update id="updateShop" parameterType="com.imooc.o2o.entity.Shop">
        UPDATE tb_shop
        <set>
            <if test="shopName != null">shop_name=#{shopName},</if>
            <if test="shopDesc != null">shop_desc=#{shopDesc},</if>
            <if test="shopAddr != null">shop_addr=#{shopAddr},</if>
            <if test="phone != null">phone=#{phone},</if>
            <if test="shopImg != null">shop_img=#{shopImg},</if>
            <if test="priority != null">priority=#{priority},</if>
            <if test="lastEditTime != null">last_edit_time=#{lastEditTime},</if>
            <if test="enableStatus != null">enable_status=#{enableStatus},</if>
            <if test="advice != null">advice=#{advice},</if>
            <if test="area != null">area_id=#{area.areaId},</if>
            <if test="shopCategory != null">shop_category_id=#{shopCategory.shopCategoryId}</if>
        </set>
        WHERE shop_id = #{shopId}
    </update>
  • 添加一个update的测试方法
    @Test
    public void testUpdateShop() {
        Shop shop = new Shop();
        shop.setShopId(1L);

        PersonInfo owner = new PersonInfo();
        Area area = new Area();
        ShopCategory shopCategory = new ShopCategory();

        owner.setUserId(5L);
        area.setAreaId(2);
        shopCategory.setShopCategoryId(1L);

        shop.setOwner(owner);
        shop.setArea(area);
        shop.setShopCategory(shopCategory);
        shop.setShopName("测试的店铺");

//        shop.setShopDesc("test");
//        shop.setPhone("test");
//        shop.setShopImg("test");

        shop.setShopDesc("测试");
        shop.setPhone("测试");
        shop.setShopImg("测试");

        shop.setCreateTime(new Date());
        shop.setEnableStatus(1);
        shop.setAdvice("审核中");
        int effectedNum = shopDao.updateShop(shop);
        assertEquals(1, effectedNum);
    }
  • 测试结果


    image.png

    image.png

Thumbnailator图片处理和封装Util

可以看看这个博客
https://blog.csdn.net/zmx729618/article/details/78729049

    <!--图片处理-->
    <!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator -->
    <dependency>
      <groupId>net.coobird</groupId>
      <artifactId>thumbnailator</artifactId>
      <version>0.4.8</version>
    </dependency>

这样就成功引入底层的架包

  • 新建一个com.imooc.o2o.util包
  • 在utli包中新建imageUtil类
package com.imooc.o2o.util;

import net.coobird.thumbnailator.Thumbnails;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

import static com.imooc.o2o.util.PathUtil.getImgBasePath;

public class ImageUtil {
    private static String basePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
    private static final SimpleDateFormat sDateFormate = new SimpleDateFormat("yyyyMMddHHmmss");
    private static final Random random = new Random();
    /**
     * 创建缩略图
     */
    public static String generateThumbnail(CommonsMultipartFile thumbnail, String targetAddr) {
        // 获取图片的随机图片名
        String realFileName = getRandomFileName();
        // 获取图片的拓展名
        String extension = getFileExtension(thumbnail);
        makeDirPath(targetAddr);
        String relativeAddr = targetAddr + realFileName + extension;
        File dest = new File(getImgBasePath() + relativeAddr);
        try {
            Thumbnails.of(thumbnail.getInputStream()).size(200, 200).outputQuality(0.25f).toFile(dest);
        } catch (IOException e) {
            throw new RuntimeException("创建缩略图失败:" + e.toString());
        }
        return relativeAddr;
    }

    /**
     * 创建路径  /home/work/cuzz/xx.jpg
     * 那么 home work xiangze 这三个文件都自动创建
     * @param targetAddr
     */
    private static void makeDirPath(String targetAddr) {
        String realFileParentPath = PathUtil.getImgBasePath() + targetAddr;
        File dirPath = new File(realFileParentPath);
        // 如果路径不存在就递归的创建
        if (!dirPath.exists()) {
            dirPath.mkdirs();
        }
    }

    /**
     * 获取输入文件流的拓展名
     * @param thumbnail
     * @return
     */
    private static String getFileExtension(CommonsMultipartFile cFile) {
        // 获取原来的文件名
        String originalFileName = cFile.getOriginalFilename();
        return originalFileName.substring(originalFileName.lastIndexOf("."));
    }

    /**
     * 生成随机文件名,当前年月日时分秒 + 5位随机数
     * @return
     */
    private static String getRandomFileName() {
        // 获取随机的5位数
        int rannum = random.nextInt(89999) + 10000;
        String nowTimestr = sDateFormate.format(new Date());
        return nowTimestr + rannum;
    }
}
  • 创建一个路径PathUtil类,获取存放图片的路径
package com.imooc.o2o.util;

public class PathUtil {
    // 获取系统分隔符
    private static String separator = System.getProperty("file.separator");

    public static String getImgBasePath() {
        // 根据不同的系统去选择根路径
        String os = System.getProperty("os.name");
        String basePath = "";
        if (os.toLowerCase().startsWith("win")) {
            basePath = "F/project/image";
        } else {
            basePath =  "home/cuzz/image";
        }
        basePath = basePath.replace("/", separator);
        return basePath;
    }

    public static String getShopImagePath(long shopId) {
        String imagePath = "/upload/item/shop" + shopId + "/";
        return imagePath.replace("/", separator);
    }
}

Dto之ShopExecution的实现

数据传输对象(DTO)(Data Transfer Object),是一种设计模式之间传输数据的软件应用系统。数据传输目标往往是数据访问对象从数据库中检索数据。数据传输对象与数据交互对象或数据访问对象之间的差异是一个以不具有任何行为除了存储和检索的数据(访问和存取器)

  • ShopExecution
package com.imooc.o2o.dto;

import com.imooc.o2o.enmus.ShopStateEnum;
import com.imooc.o2o.entity.Shop;

import java.util.List;

public class ShopExecution {
    // 结果状态
    private int state;

    // 状态标识
    private String stateInfo;
    
    // 店铺数量
    private int count;

    // 返回的shop列表
    private List<Shop> shopList;

    // 操作的shop(增删改查的时候用到)
    private Shop shop;
    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public String getStateInfo() {
        return stateInfo;
    }

    public void setStateInfo(String stateInfo) {
        this.stateInfo = stateInfo;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public List<Shop> getShopList() {
        return shopList;
    }

    public void setShopList(List<Shop> shopList) {
        this.shopList = shopList;
    }

    public Shop getShop() {
        return shop;
    }

    public void setShop(Shop shop) {
        this.shop = shop;
    }

    // 无参构造器
    public ShopExecution() {

    }

    // 操作失败有参构造器
    public ShopExecution(ShopStateEnum stateEnum) {
        this.state = stateEnum.getState();
        this.stateInfo = stateEnum.getStateInfo();
    }

    // 成功的有参构造器
    public ShopExecution(ShopStateEnum stateEnum, Shop shop) {
        this.state = stateEnum.getState();
        this.stateInfo = stateEnum.getStateInfo();
        this.shop = shop;
    }

    // 成功的有参构造器2
    public ShopExecution(ShopStateEnum stateEnum, List<Shop> shopList) {
        this.state = stateEnum.getState();
        this.stateInfo = stateEnum.getStateInfo();
        this.shopList = shopList;
    }
}
  • 同时我们需要一个枚举类型
package com.imooc.o2o.enmus;

public enum ShopStateEnum {
    CHECK(0,"审核中"),
    OFFLINE(-1, "非法商铺"),
    SUCCESS(1, "操作成功"),
    PASS(2, "通过认证");

    private int state;
    private String stateInfo;

    ShopStateEnum(int state, String stateInfo) {
       this.state = state;
       this.stateInfo = stateInfo;
    }


    public int getState() {
        return state;
    }

    public String getStateInfo() {
        return stateInfo;
    }


    /**
     * 依据传入的state返回相应的enum值
     */

    public static ShopStateEnum stateOf(int state) {
        for (ShopStateEnum stateEnum : values()) {
            if (stateEnum.getState() == state) {
                return stateEnum;
            }
        }
        return null;
    }
}

店铺注册之service层

  • 新建shopService接口
package com.imooc.o2o.service;


import com.imooc.o2o.dto.ShopExecution;
import com.imooc.o2o.entity.Shop;
import org.springframework.web.multipart.commons.CommonsMultipartFile;


public interface ShopService {
    ShopExecution addShop(Shop shop, CommonsMultipartFile shopImg);
}
  • 先封装一些RuntimeExpection
    这样的好处是知道错误类型,出错的就知道是店铺相关的错误
package com.imooc.o2o.exceptiopns;

public class ShopOperationException extends RuntimeException {
    public ShopOperationException(String msg) {
        super(msg);
    }
}
  • 实现类
package com.imooc.o2o.service.impl;

import com.imooc.o2o.dao.ShopDao;
import com.imooc.o2o.dto.ShopExecution;
import com.imooc.o2o.enmus.ShopStateEnum;
import com.imooc.o2o.entity.Shop;
import com.imooc.o2o.exceptiopns.ShopOperationException;
import com.imooc.o2o.service.ShopService;
import com.imooc.o2o.util.ImageUtil;
import com.imooc.o2o.util.PathUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.util.Date;

@Service
public class ShopServiceImpl implements ShopService{
    @Autowired
    private ShopDao shopDao;

    @Override
    // 事务的支持
    @Transactional
    public ShopExecution addShop(Shop shop, CommonsMultipartFile shopImg) {
        // 空值判断
        if (shop == null) {
            return new ShopExecution(ShopStateEnum.NULL_SHOP);
        }

        try {
            // 给店铺信息赋值初始值
            shop.setEnableStatus(0);
            shop.setCreateTime(new Date());
            shop.setLastEditTime(new Date());
            // 添加店铺信息
            int effectedNum = shopDao.insertShop(shop);

            // 判断是否插入成功
            if (effectedNum <= 0) {
                throw new ShopOperationException("店铺创建失败");
            } else {
                if (shopImg != null) {
                    // 存储图片
                    try {
                        addShopImg(shop, shopImg);
                    } catch (Exception e) {
                        throw new ShopOperationException("addShopImg error" + e.getMessage());
                    }
                    // 更新图片信息
                    effectedNum = shopDao.updateShop(shop);
                    if (effectedNum <= 0) {
                        throw new ShopOperationException("更新图片地址失败");
                    }

                }
            }

        } catch (Exception e) {
            throw new ShopOperationException("addShop error" + e.getMessage());
        }


        return new ShopExecution(ShopStateEnum.CHECK, shop);
    }

    private void addShopImg(Shop shop, CommonsMultipartFile  shopImg) {
        // 获取shop图片目录的相对值路径
        String dest = PathUtil.getShopImagePath(shop.getShopId());
        String shopImgAddr = ImageUtil.generateThumbnail(shopImg, dest);
        shop.setShopImg(shopImgAddr);
    }
}

Controller层

  • 新建一个ShopAdminController类
package com.imooc.o2o.web.shopadmin;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping(value = "shop", method = RequestMethod.GET)
public class ShopAdminController {
    @RequestMapping(value="/shopoperation")
    public String shopOperation() {
        return "shop/shopedit";
    }
}
  • 效果图


    image.png
  • 添加shopoperation.js文件
$(function () {
   // 获取初始url
   var initUrl = "/project2/shop/getshopinitinfo";
   var registerShopUrl = "/project2/shop/registershop";
   alert(initUrl);
   getShopInitInfo();


   function getShopInitInfo(){
      // 获取初始值
      $.getJSON(initUrl, function (data) {
          alert("SSSSSSSS");
         if (data.success) {
            var tempHtml = "";
            var tempAreaHtml = "";
            data.shopCategoryList.map(function (item, index) {
               tempHtml += "<option data-id='" + item.shopCategoryId + "'>"
                + item.shopCategoryName + "</option>";
            });
            
            data.areaList.map(function (item, index) {
                tempAreaHtml +=  "<option data-id='" + item.areaId + "'>"
                    + item.areaName + "</option>";
            });
            $("#shop-category").html(tempHtml);
            $("#area").html(tempAreaHtml);
         }
      });
   }
      // 提交
      $("#submit").click(function () {
         var shop = {};
         shop.shopName = $("#shop-name").val();
         shop.shopAddr = $("#shop-addr").val();
         shop.phone = $("#phone").val();
         shop.shopDesc = $("#shop-desc").val();
         shop.shopCategory = {
            shopCategoryId:$("#shop-category").find("option").not(function () {
                return !this.selected;
            }).data("id")
         };
         shop.area = {
            areaId: $("#area").find("option").not(function () {
               return !this.selected;
            }).data("id")
         };
         var shopImg = $("#shop-img")[0].file[0];
         var formData = new FormData();
         formData.append("shopImg", shopImg);
         formData.append("shopStr", JSON.stringify(shop));
         var verifyCodeActual = $("#j_captcha").val();
         // 判断是否为空
         if (!verifyCodeActual) {
             $.toast("请输入验证码!");
             return;
         }
         formData.append("verifyCodeActual", verifyCodeActual);
         // 提交到后台
          $.ajax({
              url: registerShopUrl,
              type: "POST",
              data: formData,
              contentType: false,
              processDate: false,
              cache: false,
              success: function (data) {
                 if (data.success){
                     $.toast("提交成功!");
                 } else {
                     $.toast("提交失败" + data.errMsg);
                 }
                 // 不管没有提交成功 都更换验证码
                 $("#captcha_img").click();
              }

          });
      });
});
  • 新建一个管理类,通过json数据
package com.imooc.o2o.web.shopadmin;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.imooc.o2o.dto.ShopExecution;
import com.imooc.o2o.enmus.ShopStateEnum;
import com.imooc.o2o.entity.Area;
import com.imooc.o2o.entity.PersonInfo;
import com.imooc.o2o.entity.Shop;
import com.imooc.o2o.entity.ShopCategory;
import com.imooc.o2o.service.AreaService;
import com.imooc.o2o.service.ShopCategoryService;
import com.imooc.o2o.service.ShopService;
import com.imooc.o2o.util.HttpServletRequestUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/shop")
public class ShopManagementController {
    @Autowired
    private ShopService shopService;

    @Autowired
    private ShopCategoryService shopCategoryService;

    @Autowired
    private AreaService areaService;

    @RequestMapping(value = "/getshopinitinfo", method = RequestMethod.GET)
    @ResponseBody
    private Map<String, Object> getShopInitInfo() {
        Map<String, Object> modelMap = new HashMap<>();
        List<ShopCategory> shopCategoryList = new ArrayList<>();
        List<Area> areaList = new ArrayList<>();
        try{
            shopCategoryList = shopCategoryService.getShopCategoryList(new ShopCategory());
            areaList = areaService.getAreaList();
            modelMap.put("shopCategoryList", shopCategoryList);
            modelMap.put("areaList", areaList);
            modelMap.put("success", true);
        } catch (Exception e) {
            modelMap.put("success", false);
            modelMap.put("errMsg", e.getMessage());
        }
        return modelMap;
    }

    @RequestMapping(value = "/registershop", method = RequestMethod.POST)
    @ResponseBody
    private Map<String, Object> registerShop(HttpServletRequest request) {
        Map<String, Object> modelMap = new HashMap<>();
        // 1. 接受并转化相应的参数, 包括店铺信息以及图片信息
        String shopstr = HttpServletRequestUtil.getString(request, "shopStr");
        ObjectMapper mapper = new ObjectMapper();
        Shop shop = null;
        try{
            shop = mapper.readValue(shopstr, Shop.class);
        } catch (Exception e) {
            modelMap.put("success", false);
            modelMap.put("errMsg", e.getMessage());
            return modelMap;
        }
        CommonsMultipartFile shopImg = null;
        CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        if (commonsMultipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
            shopImg = (CommonsMultipartFile) multipartHttpServletRequest.getFile("shopImg");
        } else {
            modelMap.put("success", false);
            modelMap.put("errMsh", "上传图片不能为空");
            return modelMap;
        }
        // 2. 注册店铺
        if (shop != null && shopImg != null) {
            PersonInfo owner = new PersonInfo();
            owner.setUserId(1L);
            shop.setOwner(owner);
            ShopExecution shopExecution = null;
            try {
                shopExecution = shopService.addShop(shop, shopImg.getInputStream(), shopImg.getOriginalFilename());
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (shopExecution.getState() == ShopStateEnum.CHECK.getState()) {
                modelMap.put("success", true);
            } else {
                modelMap.put("success", false);
            }
            return modelMap;
        } else {
            modelMap.put("success", false);
            modelMap.put("errMsh", "请输入店铺信息");
            return modelMap;
        }
        // 3. 返回结果
    }
}
  • 获取到结果


    image.png

验证码工具包

    <servlet>
        <!-- 生成图片的Servlet -->
        <servlet-name>Kaptcha</servlet-name>
        <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>

        <!-- 是否有边框 -->
        <init-param>
            <param-name>kaptcha.border</param-name>
            <param-value>no</param-value>
        </init-param>
        <!-- 字体颜色 -->
        <init-param>
            <param-name>kaptcha.textproducer.font.color</param-name>
            <param-value>red</param-value>
        </init-param>
        <!-- 图片宽度 -->
        <init-param>
            <param-name>kaptcha.image.width</param-name>
            <param-value>135</param-value>
        </init-param>
        <!-- 使用哪些字符生成验证码 -->
        <init-param>
            <param-name>kaptcha.textproducer.char.string</param-name>
            <param-value>ACDEFHKPRSTWX345679</param-value>
        </init-param>
        <!-- 图片高度 -->
        <init-param>
            <param-name>kaptcha.image.height</param-name>
            <param-value>50</param-value>
        </init-param>
        <!-- 字体大小 -->
        <init-param>
            <param-name>kaptcha.textproducer.font.size</param-name>
            <param-value>43</param-value>
        </init-param>
        <!-- 干扰线的颜色 -->
        <init-param>
            <param-name>kaptcha.noise.color</param-name>
            <param-value>black</param-value>
        </init-param>
        <!-- 字符个数 -->
        <init-param>
            <param-name>kaptcha.textproducer.char.length</param-name>
            <param-value>4</param-value>
        </init-param>
        <!-- 使用哪些字体 -->
        <init-param>
            <param-name>kaptcha.textproducer.font.names</param-name>
            <param-value>Arial</param-value>
        </init-param>
    </servlet>
    <!-- 映射的url -->
    <servlet-mapping>
        <servlet-name>Kaptcha</servlet-name>
        <url-pattern>/Kaptcha</url-pattern>
    </servlet-mapping>
<li>
    <div class="item-content">
        <div class="item-media">
            <i class="icon icon-form-email"></i>
        </div>
        <div class="item-inner">
            <label for="j_captcha" class="item-title label">验证码</label> <input
                id="j_captcha" name="j_captcha" type="text"
                class="form-control in" placeholder="验证码" />
            <div class="item-input">
                <img id="captcha_img" alt="点击更换" title="点击更换"
                    onclick="changeVerifyCode(this)" src="../Kaptcha" />
            </div>
        </div>
    </div>
</li>
function changeVerifyCode(img) {
    img.src = "../Kaptcha?" + Math.floor(Math.random() * 100);
}
  • 把验证码传入Json
         var verifyCodeActual = $("#j_captcha").val();
         // 判断是否为空
         if (!verifyCodeActual) {
             $.toast("请输入验证码!");
             return;
         }
         formData.append("verifyCodeActual", verifyCodeActual);
  • 就有了验证码


    image.png
  • 验证码util
package com.imooc.o2o.util;

import javax.servlet.http.HttpServletRequest;

public class CodeUtil {
    public static boolean checkVerifyCode(HttpServletRequest request) {
        String verifyCodeExpected = (String) request.getSession().getAttribute(
                com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
        String verifyCodeActual = HttpServletRequestUtil.getString(request,
                "verifyCodeActual");
        if (verifyCodeActual == null
                || !verifyCodeActual.equalsIgnoreCase(verifyCodeExpected)) {
            return false;
        }
        return true;
    }
}
  • 测试


    image.png

    image.png

    可以看出数据库中插入了数据

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353

推荐阅读更多精彩内容