SSM项目之商铺系统-店铺注册之引入kaptcha(十二)

我们来实现添加店铺并且引入验证码的步骤

我们使用kaptcha库,首先在maven中加入这个api的包

首先在web.xml文件中配置:kaptcha的验证码。


    <!-- 生成图片的Servlet,Kaptcha验证码 -->
    <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>

配置他的显示格式和映射文件。

然后是前端的设计;

html中加入验证码选项:

      <!-- 验证码  kapa-->
                        <li>
                            <div class="item-content">
                                <div class="item-inner">
                                    <div class="item-title label">验证码</div>
                                    <input type="text" id="j_kaptcha" placeholder="验证码">
                                    <div class="item-input">
                                        <img id="kaptcha_img" alt="点击更换" title="点击更换"
                                            onclick="changeVerifyCode(this)" src="../Kaptcha"> <!-- src是找到web.xml中 对应的servlet的名字 -->
                                    </div>
                                </div>
                            </div>
                        </li>

由于别的模块也会使用到验证码功能,我们将验证码的js存放在common文件夹下:这里存放公用的js

common.js

 shopoperation.js:

  // 验证码
            var verifyCodeActual =$('#j_kaptcha').val();
            if(!verifyCodeActual){
                $.toast('请输入验证码');
                return;
            }

            // 接收数据
            var formData = new FormData();
            // 和后端约定好,利用shopImg和 shopStr接收 shop图片信息和shop信息
            formData.append('shopImg',shopImg);
            // 转成JSON格式,后端收到后将JSON转为实体类
            formData.append('shopStr',JSON.stringify(shop));

            // 将数据封装到formData发送到后台
            formData.append('verifyCodeActual',verifyCodeActual);


            // 利用ajax提交
            $.ajax({
                // 动态判断 url
                url:registerShopUrl,
                type:'POST',
                data:formData,
                contentType:false,
                processData:false,
                cache:false,
                success:function(data){
                    if(data.success){
                        $.toast('提示信息:'+data.errMsg);
                    }else{
                        $.toast('提示信息:' + data.errMsg);
                    }
                    // 点击提交后 不管成功失败都更换验证码,防止重复提交
                    $('#kaptcha_img').click();
                }
            });

        });

 最后是后台的实现:

思路:在提交的controller提交前,我们先判断验证码是否正确我们可以调用kaptcha的功能来获取当前session中的验证码,我们可以通过前台传来的验证码进行比较,判断是否为相同值。

先写一个工具类用于判断验证码是否相同。

package storepro.util;

import com.google.code.kaptcha.Constants;

import javax.servlet.http.HttpServletRequest;

public class CodeUtil  {//判断验证码是否相同
    public static boolean checkVerifyCode(HttpServletRequest request)
    {
        String verifyCodeExpect= (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
        String verifyCodeActual=HttpServletRequestUtil.getString(request,"verifyCodeActual");
        if (verifyCodeActual==null&&!verifyCodeActual.equals(verifyCodeExpect))//当实际值为空或者实际值和期望值不同
            return  false;//返回错误
        return true;
    }



}

通过之前写的HttpServletRequest里的方法获取相应的key值,从中取出相应的数据,,判断是否相同

加入:

private Map<String,Object> registerShop(HttpServletRequest request){
        Map<String,Object>  modelMap=new HashMap<String,Object>();
        //先判断验证码是否正确
        if (!CodeUtil.checkVerifyCode(request)){//当验证码错误时
            modelMap.put("success",false);
            modelMap.put("errMsg","输入了错误的验证码");
            return modelMap;
        }
         //1.接受转换相应的参数,包括店铺信息和店铺图片信息
        String shopStr = HttpServletRequestUtil.getString(request,"shopStr");//通过转换工具类将前端传来的数据转为字符串
        ObjectMapper mapper=new ObjectMapper();//获取处理json的对象
        Shop shop=null;
        try{
            shop=mapper.readValue(shopStr,Shop.class);//将传入的jsonshopStr转为Shop对象并完成赋值
        }catch (Exception e){//出错后输出错误信息
            modelMap.put("success",false);
            modelMap.put("errMsg",e.getMessage());
            return modelMap;
        }
        /*
        * 操作添加图片
        * */
        CommonsMultipartFile shopImg=null;//spring自带
        CommonsMultipartResolver commonsMultipartResolver=new CommonsMultipartResolver(
                request.getSession().getServletContext()
        );//解析request传来的文件的,通过本次会话的上下文获取相关文件上传的内容
        if (commonsMultipartResolver.isMultipart((request))) {//如果有上传的文件流
            MultipartHttpServletRequest multipartHttpServletRequest= (MultipartHttpServletRequest) request;//这样就能提取出request中的文件流了
            shopImg=(CommonsMultipartFile)multipartHttpServletRequest.getFile("shopImg");//(这个字符串"shopImg"是前端传来的),得到文件
        }else {//如果不具备图片
            modelMap.put("success",false);
            modelMap.put("errMsg","上传图片不能为空");
            return modelMap;
        }
        // 2.注册店铺
        if (shop!=null&&shopImg!=null) {//如果接受完相应的参数
            PersonInfo owner=new PersonInfo();//owner的信息可以通过session获取
            owner.setUserId(1L);//先手动设置,后期更改
            shop.setOwner(owner);
            ShopExecution shopExecution= null;//不能直接传文件,因为CommonsMultipartFile和File不能直接转换
            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);
                modelMap.put("errMsg",shopExecution.getState());
                return modelMap;
            }
            return modelMap;
        }else{
            modelMap.put("success",false);
            modelMap.put("errMsg","请输入店铺信息");
            return modelMap;
        }
        //3.返回结果

    }
}

判断验证码部分,如果相同接着进行,如果不同任务结束。这个方法在的url在js中:

   /**
         * submit按钮触发的操作
         * 验证表单输入,省略。。。。
         */
        $('#submit').click(function() {
            // 获取页面的值
            var shop = {};
            // 注意: 这个地方的变量名称要和Shop实体类中的属性保持一致,因为后台接收到shopStr后,会将Json转换为实体类,如果不一致会抛出异常
            // com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException

            // 如果是编辑,需要传入shopId

            shop.shopName = $('#shop-name').val();
            shop.shopAddr = $('#shop-addr').val();
            shop.phone = $('#shop-phone').val();
            shop.shopDesc = $('#shop-desc').val();
            // 选择id,双重否定=肯定
            shop.shopCategory = {
                // 这里定义的变量要和ShopCategory.shopCategoryId保持一致,否则使用databind转换会抛出异常
                shopCategoryId:$('#shop-category').find('option').not(function(){
                    return !this.selected;
                }).data('id')
            };
            shop.area = {
                // 这里定义的变量要和Area.areaId属性名称保持一致,否则使用databind转换会抛出异常
                areaId:$('#shop-area').find('option').not(function(){
                    return !this.selected;
                }).data('id')
            };


            // 图片
            var shopImg = $('#shop-img')[0].files[0];

            // 验证码
            var verifyCodeActual =$('#j_kaptcha').val();
            if(!verifyCodeActual){
                $.toast('请输入验证码');
                return;
            }

            // 接收数据
            var formData = new FormData();
            // 和后端约定好,利用shopImg和 shopStr接收 shop图片信息和shop信息
            formData.append('shopImg',shopImg);
            // 转成JSON格式,后端收到后将JSON转为实体类
            formData.append('shopStr',JSON.stringify(shop));

            // 将数据封装到formData发送到后台
            formData.append('verifyCodeActual',verifyCodeActual);


            // 利用ajax提交
            $.ajax({
                // 动态判断 url
                url:registerShopUrl,
                type:'POST',
                data:formData,
                contentType:false,
                processData:false,
                cache:false,
                success:function(data){
                    if(data.success){
                        $.toast('提示信息:'+data.errMsg);
                    }else{
                        $.toast('提示信息:' + data.errMsg);
                    }
                    // 点击提交后 不管成功失败都更换验证码,防止重复提交
                    $('#kaptcha_img').click();
                }
            });

        });
    });

注意前台通过formDate.append("key","value)方法传送数据,后台通过requset.getParamet("key")获得内容

这样整个店铺注册就实现了。可是进行了测试debug测试后,我发现前台传来的数据为空

解决:

因为我们的注册店铺页面有文件类型上传,所以必须配置文件上传解析器,才能正确接受request中的key值,就算我们一开始没有用到文件,spring看到有文件上传类型发现没有文件上传解析器,还是没办法识别key

加上文件上传解析器 在spring——web中

    <!--配置文件上传解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--默认字符集编码-->
        <property name="defaultEncoding" value="utf-8"></property>
        <!-- 设置上传文件最大尺寸,1024*1024*20-->
        <property name="maxUploadSize" value="20971520" />
        <!--最大内存-->
        <property name="maxInMemorySize" value="20971520"></property>
    </bean>

问题解决

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值