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

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

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

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


    
    
        Kaptcha
        com.google.code.kaptcha.servlet.KaptchaServlet

        
        
            kaptcha.border
            no
        
        
        
            kaptcha.textproducer.font.color
            red
        
        
        
            kaptcha.image.width
            135
        
        
        
            kaptcha.textproducer.char.string
            ACDEFHKPRSTWX345679
        
        
        
            kaptcha.image.height
            50
        
        
        
            kaptcha.textproducer.font.size
            43
        
        
        
            kaptcha.noise.color
            black
        
        
        
            kaptcha.textproducer.char.length
            4
        
        
        
            kaptcha.textproducer.font.names
            Arial
        
    
    
    
        Kaptcha
        /Kaptcha
    

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

然后是前端的设计;

html中加入验证码选项:

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

    common.js

    SSM项目之商铺系统-店铺注册之引入kaptcha(十二)_第1张图片

     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中的验证码,我们可以通过前台传来的验证码进行比较,判断是否为相同值。

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

    SSM项目之商铺系统-店铺注册之引入kaptcha(十二)_第2张图片

    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 registerShop(HttpServletRequest request){
            Map  modelMap=new HashMap();
            //先判断验证码是否正确
            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

    SSM项目之商铺系统-店铺注册之引入kaptcha(十二)_第3张图片

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

        
        
            
            
            
            
            
            
        

    问题解决

    你可能感兴趣的:(SSM项目之商铺系统-店铺注册之引入kaptcha(十二))