品优购项目学习总结

品优购项目总结

  • 之前在学习java的时候自己做过一个商城项目,采用的是SSH框架做的,当时也是为了学习SSH框架,属于那种OA系统,很单一。后来看资料发现了传智播客的品优购项目,找到了资料学习。从开始到结束,差不多用了一个月的时间,期间没有用提供的虚拟机,自己在阿里云上部署了一个服务器,也算把所有内容自己尝试了一下,包括安装FastDFS这些。
  • 做的过程中遇到了很多的问题。开这个帖子的目的呢,一个是做一下学习笔记,一个是我在做的过程问题的一些汇总。

一、工程搭建问题

  • 工程搭建的时候我使用的工具的IDEA来操作的,在建立的过程当中,也会区分jar包与war包的区别,这个需要在建立的时候自己选择一下。


    创建工程
  • 使用IDEA搭建好工程以后需要手动去建立一些文件,在main目录下面创建resourcesjava,一定注意要写对,我当时建立的时候写成了resource,就少了一个S,spring的配置文件一个也读取不到,访问Controller一直是404,找错误找了好久。然后打开Project Structure,给这个目录作为Resources也Sources。
    Project Structure
  • 这里注意一个问题,可能你在建立web工程的时候速度特别慢,这里可以修改一下本地仓库,引用一下阿里巴巴的一个仓库,在setting.xml文件中加入一句话。
       
        
      nexus  
      *   
      http://maven.aliyun.com/nexus/content/groups/public/  
      
      
        
      nexus-public-snapshots  
      public-snapshots   
      http://maven.aliyun.com/nexus/content/repositories/snapshots/  
     
  
  • 这样的话在新建web工程的时候速度就很快了。

二、商户修改密码阶段问题

  • 这个阶段视频当中没有说过,我是后面再完善的时候看到了这个模块,主要这里涉及一个问题,就是在使用Security框架的时候,当时注册时候,密码被加密了,在修改密码的时候,会和原来的密码进行比较,因为和MD5加密不一样,每次的值都不同。查了资料才发现,提供了一个加密比较方法。
BCryptPasswordEncoder passwordEncoder =new BCryptPasswordEncoder();
boolean matches = passwordEncoder.matches(oldpass, seller.getPassword());
  • 这样就能可以比较两次的密码值。

三、AngularJS跨域提交的过程中文乱码问题

  • 在做跨域访问的时候,传对象、数字都是正常的,就是传输中文的时候会导致乱码的问题。一直也没找到问题。编译器编码也改了,但还是有问题,传输之前打印一个alert,正常。到了控制层打印就出现了乱码。
  • 在传输的过程中,涉及到传输中文的话,我都会以对象的形式传,有问题的朋友可以尝试一下。
    $scope.maps={};
    $scope.findOne=function(ids){
        $scope.maps.sellerId=ids;
        sellerService.findOne($scope.maps).success(
            function(response){
                $scope.entity= response;
            }
        );
    }

四、Solr搜索服务问题

  1. 在第十天、第十一天的内容里面都是在做Solr的搜索,当时在做的过程中,测试的时候发现了一个小bug,就是我点击最后一页,比如是19页,当我在搜索一个内容的时候,没有19页就会出现什么内容也没有。(后面的时候老师有讲这个过程)可以在搜索的时候每次将页面拉回去。
    $scope.searchMap.pageNo=1;

这句话只要是涉及到更改搜索内容的时候都需要放上,不然都会出现没有数据的情况。

  1. 第二个小问题就是在更新solr库的时候,感觉需求分析稍微有点问题,个人感觉,商品上传以后运营商会进行审核,但是在审核的过程当中由于 没有修改后端代码,运用商更新的只是tb_goods表当中的audit_status字段,但是在导入solr库的时候,导入的是tb_item这个表里面的信息,而且看的也是这个表中status字段,所以在存储的过程中,永远不会添加到solr库。
  • 然后我自己修改了一下需求,也就是在商户点击商家商品的时候,导入solr库,将内容放入消息中间件当中,获取。需要修改Shop-web下面的GoodsController。
@RequestMapping("/updateStatue")
    public void updateStatue(final Long id, String status){

        goodsService.UpdateMarkStatus(id,status);

        //更新Solr
        if (status.equals("1")) {
             List item = goodsService.findItemListByGoodsIdListAndStatus(id, status);
//          //导入solr
//          itemSearchService.importList(item);

            final String jsonString = JSON.toJSONString(item);
            //发消息 传输对象必须是实现了序列化接口
            jmsTemplate.send(queueSolrDestination, new MessageCreator() {
                @Override
                public Message createMessage(Session session) throws JMSException {
                    return session.createTextMessage(jsonString);
                }
            });
            System.out.println("消息发送完毕------");


            //创建页面
//          itemPageService.genItemHtml(id);
            jmsTemplate.send(topicGoodsDestination, new MessageCreator() {
                @Override
                public Message createMessage(Session session) throws JMSException {

                    return session.createTextMessage(id+"");
                }
            });
        }else{
            //下架以后再创建
//          itemPageService.genItemHtml(id);
            jmsTemplate.send(topicGoodsDestination, new MessageCreator() {
                @Override
                public Message createMessage(Session session) throws JMSException {

                    return session.createTextMessage(id+"");
                }
            });
        }
  • 代码写的不是很好....凑活看看

五、Redis缓存问题

  • 在做缓存的时候,当时需要把品牌列表与规格列表全部放入Redis当中,当时老师在写的时候,直接改成了一个死的,也就是每次项目运行的时候,在点击的过程中,都会有一个很长时间的导入过程,造成超时,就算把时间改成很长,但是也得过很久才会显示,这样的体验很差。
  • 个人的解决办法:导入一次以后记得将之前的代码注释一下,之后在增加修改删除的时候,只执行一次。在TypeTemplateServiceImpl文件中,重新写了一个方法,每次增删改查的时候执行这个方法即可。
private void saveToRedisOne(TbTypeTemplate typeTemplate){
        List brandList = JSON.parseArray(typeTemplate.getBrandIds(), Map.class);
        List specList = findSpecList(typeTemplate.getId());
        redisTemplate.boundHashOps("brandList").put(typeTemplate.getId(), brandList);
        redisTemplate.boundHashOps("specList").put(typeTemplate.getId(), specList);
        System.out.println("品牌..规格...列表放入缓存");
    }
  • 水平有限...各位如果有好的方法可以一起交流一下。

六、支付

  • 视频里面使用的是微信扫码付款方式,但是没有签名所以很多时候做到这一步基本就放弃了,由于没有营业执照什么的,微信支付自己又没办法申请,这里别着急,可以使用支付宝的,支付宝的可以个人免费申请一个,然后使用沙盒测试就ok。
  1. 首先去 https://docs.open.alipay.com/ 开发者中心注册这些自己就可以完成。之后进入开发中心 ----> 网页移动应用 。
    在这里插入图片描述
  2. 然后选择一下支付接入,自己接入一下。这个地方其实可以随便写一下,因为app上线的话这个就很重要,我们的目的是学习,所以这个地方自己有兴趣看看,加密那块的设置。然后就是打开沙箱测试。 https://openhome.alipay.com/platform/appDaily.htm?tab=info
    在这里插入图片描述
  3. 这里有几个参数一会要用到的,appid 支付宝网关 支付宝公钥。公钥怎么设置这里不做过多的赘述,鼠标放上去之后下载一个支付宝提供的加密软件,生成 复制 粘贴就ok了。说明一下这里的支付宝网关,这里一定记得用这个沙盒测试地址。正式的地址由于没有上线,appid不合法的。需要用安卓手机下载一个沙盒测试app网站里面就有。 https://docs.open.alipay.com/291/106103/ 密钥的开发文档
  4. 生成好密钥以后,保存一下自己的密钥和支付宝公钥。然后就开始写代码测试。如果要学习可以看看 https://docs.open.alipay.com/270/106291/ 开发文档,我用的是电脑扫码付款这个,有兴趣自己下载一下Demo看看。
  5. 引入阿里巴巴的sdk依赖。
        
            com.alipay.sdk
            alipay-sdk-java
            3.4.49.ALL
        
  1. 创建一个类,用来完成支付。这里也需要的JSON格式的数据,但是每个都得写太麻烦了,直接就封装到Map里面然后JSON.toJSONString转换了一下字符串就可以了。这里记得要看着开发文档去做啊。我把一些文件都写到了properties文件里面了,详细可以参考一下视频里面的做法。
@Service
public class ZhiFuBaoPayServiceImpl implements ZhiFuBaoPayService {

    @Value("${app_id}")
    private String appid;

    @Value("${merchant_private_key}")
    private String merchant_private_key;

    @Value("${alipay_public_key}")
    private String alipay_public_key;

    @Value("${notify_url}")
    private String notify_url;

    @Value("${return_url}")
    private String return_url;

    @Value("${sign_type}")
    private String sign_type;

    @Value("${charset}")
    private String charset;

    @Value("${gatewayUrl}")
    private String gatewayUrl;

    @Autowired
    private HttpServletRequest req;
    @Autowired
    private HttpServletResponse response;

    @Override
    public String createNative(String out_trade_no, String total_fee,String subject) {
        AlipayClient alipayClient=new DefaultAlipayClient(gatewayUrl,appid,merchant_private_key,"json",charset,alipay_public_key,sign_type);
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setReturnUrl(return_url);
        request.setNotifyUrl(notify_url);

        //添加商品信息
        Map map=new HashMap();
        map.put("out_trade_no",out_trade_no);
        map.put("total_amount",total_fee);
        map.put("subject",subject);
        map.put("body","你好,测试商品");
        map.put("product_code","FAST_INSTANT_TRADE_PAY");

        String parm=JSON.toJSONString(map);

        request.setBizContent(parm);
//        System.out.println("===这是parm:"+parm);

        String result="";
        try {
            result = alipayClient.pageExecute(request).getBody();


        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return result;
    }
}

  • 这里注意两个地址notify_urlreturn_ur,这两个地址。return_url指的是用户的付款以后跳转的一个页面,这个页面尽量做一个静态页面就行,给用户展示用的。notify_url 这个页面是异步调用的,也就是说用户和我们都没办法看到这个页面,它是用来做数据的处理的,比如更改订单状态。

    1. notify_url这个地址需要公网ip能访问的,因为阿里巴巴的说法是这个页面需要他们返回执行,通知率据说可以达到99.999%,这个连接里面主要做的就是修改数据库字段,但是没有公网ip所以就写一个任意地址。
    1. return_url这个地址由于网络问题可能会通知不到,页面不跳转,建议就是不在这个地址上做任何事,放一个静态地址就可以。但是测试的时候只能用这个地址来做。
  • gatewayUrl 这个就是沙盒测试地址,也就是之前的说的支付宝网关。

  1. 创建Controller来完成支付。
@RequestMapping("/pay")
public class ZhiFuBaoController {

    @Reference
    private ZhiFuBaoPayService zhiFuBaoPayService;

    @Reference
    private OrderService orderService;


    @RequestMapping("/ZhiFuBao")
    public void createNativeZhiFuBao(HttpServletResponse response) throws IOException {

        String name = SecurityContextHolder.getContext().getAuthentication().getName();
        TbPayLog tbPayLog = orderService.searchPayLogFromRedis(name);
        String result="";
        if (tbPayLog!=null){
            result = zhiFuBaoPayService.createNative(tbPayLog.getOutTradeNo(),tbPayLog.getTotalFee()+"","黑蚂蚁商城家的商品");
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write(result);//直接将完整的表单html输出到页面
            response.getWriter().flush();
            response.getWriter().close();
        }else{
            return;
        }
    }


    @RequestMapping("/success")
    public void success(HttpServletRequest request, HttpServletResponse response){
        Map parem=new HashMap();
        Map map=request.getParameterMap();
        for (Iterator iterator=map.keySet().iterator();iterator.hasNext();){
            String name= (String) iterator.next();
            String[] values= (String[]) map.get(name);
            String vlaue="";
            for (int i = 0; i < values.length; i++) {
                vlaue = (i == values.length - 1) ? vlaue + values[i]
                        : vlaue + values[i] + ",";
            }
            parem.put(name,vlaue);
        }

        String outId=parem.get("out_trade_no");
        String trade_no=parem.get("trade_no");
        orderService.updateOrderStatus(outId,trade_no);
        System.out.println("支付宝流水号:"+trade_no);
        try {
            response.sendRedirect("../paysuccess.html");
        } catch (IOException e) {
            e.printStackTrace();
        }


    }


}

  1. 我这边测试的时候就把return_url 改成了这个Controller的success.do这个地址。更改数据库字段在跳转成功界面。

总结

整个品优购项目的完成,熟悉了很多的技术。如SpringSecurity、Dubbox,Solr等。在学习过程,遇到了很多的问题,也翻阅了很多的资料。整个品优购项目中,让我体会到一个大型项目的“魅力”。整个项目中,让我感觉到最麻烦最难的一点就是单点登录,每次看单点登录的跳转,看的头大。但是分布式应用有不可避免....自己的技术还有待提高,如果文章当中有问题,或者有什么好的意见,大家可以指出来,一起学习。

你可能感兴趣的:(品优购项目学习总结)