电商项目(三)

(1)搭建前台系统。

(2)完成首页导航菜单。(学习jsonp

(3)完成CMS内容管理系统。

(4)完成首页大广告位投放。(学习Httpclient


[if !supportLists]1            [endif]搭建前台系统

[if !supportLists]1.1         [endif]前台系统架构

[if !vml]

[endif]

在互联网系统开发当中,我们一般都是采用了分层的方式来架构系统,即:

(1)门户层(门户系统):网站的入口

i、渲染视图,提供用户访问的页面。

ii、不查询数据库,数据来自对远程服务(接口)的调用。

(2)服务层:基于restful,以接口的形式对外提供公共的服务。

i、连接数据库,返回json格式的数据。


[if !supportLists]1.1.1        [endif]分层架构的好处

(1)、有利于系统的维护和拓展。

(2)、有利于SOA服务治理的基础。

[if !supportLists]1.2         [endif]搭建服务层系统

[if !supportLists]1.2.1        [endif]系统简介

基于RESTful实现。以接口的形式,对外提供公共的服务。(比如购物车、导航菜单、搜索、订单等等)

RESTful是一种接口设计理念,即:

(1)不同的请求方式,对应不同的业务类型:

      GET   :查询

      POST  :添加

      PUT   :更新

      DELETE:删除

(2)返回json格式数据。


[if !supportLists]1.2.2        [endif]技术选择

核心框架:Spring+SpringMVC+Mybatis-plus

数据库:MySQL

前端框架:无


[if !supportLists]1.2.3        [endif]配置步骤

思路:(1)创建项目,导入jar依赖。

        (2)整合SSM框架。


[if !supportLists]1.2.3.1    [endif]第一步:创建maven项目(war)模型

注意:(1)项目继承ego-project。

      (2)使用maven module创建项目

[if !vml]

[endif]


[if !supportLists]1.2.3.2    [endif]第二步:导入jar依赖

导包说明:

    (1)ego-base子工程

       (2)Spring核心包

       (3)SpringMVC相关包

       (4)AOP相关包

       (5)JDBC、事物相关包

(6)Mybatis-plus及整合包

(7)JSON依赖包

导入插件:Tomcat插件(开发阶段,启动项目,对外发布接口)


"http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  4.0.0

 

    cn.gzsxt.ego

    ego-project

    1.0

 

  cn.gzsxt.ego

  ego-rest

  1.0

  war


 

   

       cn.gzsxt.ego

        ego-base

        1.0

   

   

   

   

       org.springframework

       spring-context

   

   

   

       org.springframework

       spring-jdbc

     

   

   

       org.springframework

       spring-aspects

   


   

   

       org.springframework

       spring-webmvc

   


   

   

       org.mybatis

       mybatis-spring

   


   

   

   

       mysql

       mysql-connector-java

   

   

   

       com.alibaba

       druid

   


   

       com.fasterxml.jackson.core

       jackson-databind

   

 

 

      

           

           

                 org.apache.tomcat.maven

                 tomcat7-maven-plugin

                

                     8081

                     /

                     UTF-8

                

           

        

   


[if !supportLists]1.2.3.3    [endif]第三步:创建web.xml文件

说明:可以从ego-manager工程中拷贝,修改即可。

"1.0"encoding="UTF-8"?>

"2.5"xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xml="http://www.w3.org/XML/1998/namespace"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

  http://xmlns.jcp.org/xml/ns/javaee/web-app_2_5.xsd ">


   

     

           characterEncodingFilter

           org.springframework.web.filter.CharacterEncodingFilter

          

               encoding

               utf-8

          

     

 

       characterEncodingFilter

       /*

 

   

       dispatcherServlet

       org.springframework.web.servlet.DispatcherServlet

      

           contextConfigLocation

           classpath:spring-*.xml

      

      

       1

   

   

       dispatcherServlet


      

        /rest/*

   


[if !supportLists]1.2.3.4    [endif]第四步:整合SSM框架

整合中所需要的配置文件,均可从ego-manager工程中拷贝,修改局部的配置即可。

[if !supportLists]1.2.3.4.1    [endif]Step1:Spring整合SpringMVC

创建spring-mvc.xml文件,做如下配置:

"1.0"encoding="UTF-8"?>

"http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:mvc="http://www.springframework.org/schema/mvc"

    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd

       http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans.xsd

       http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-4.1.xsd">


   

    "cn.gzsxt.rest"/>

   

   


[if !supportLists]1.2.3.4.2    [endif]Step2:mybatis-plus整合spring

在这里,我们一定要有一个概念:任何持久层框架和Spring的整合,都是为了使用Spring的事物代理。


(1)创建resource.properties文件,配置数据库连接信息如下:

#配置数据源

db.driver=com.mysql.jdbc.Driver

db.url=jdbc:mysql://localhost:3306/ego

db.username=root

db.password=gzsxt


(2)创建spring-data.xml文件,配置框架整合。

"1.0"encoding="UTF-8"?>

"http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:tx="http://www.springframework.org/schema/tx"

    xsi:schemaLocation="http://www.springframework.org/schema/beans

  http://www.springframework.org/schema/beans/spring-beans-4.3.xsd

       http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-4.3.xsd

       http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">


    "utf-8"location="classpath:resource.properties"/>


   

    "dataSource"class="com.alibaba.druid.pool.DruidDataSource">

       "driverClassName"value="${db.driver}"/>

       "url"value="${db.url}"/>

       "username"value="${db.username}"/>

       "password"value="${db.password}"/>

       "maxActive"value="20"/>

       "minIdle"value="5"/>

   


   

    "sqlSessionFactoryBean"class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">

      

       "dataSource"ref="dataSource"/>


      

       "typeAliasesPackage"value="cn.gzsxt.base.pojo"/>


      

       "plugins">

          

              

              "com.baomidou.mybatisplus.plugins.PaginationInterceptor"/>


             

              "com.baomidou.mybatisplus.plugins.PerformanceInterceptor">

                 

                  "maxTime"value="1000"/>

                  "format"value="true"/>


             

          

      


      

       "globalConfig"ref="globalConfiguration">


   


   

    "org.mybatis.spring.mapper.MapperScannerConfigurer">


       "sqlSessionFactoryBeanName"value="sqlSessionFactoryBean"/>


       "basePackage"value="cn.gzsxt.base.mapper">


   



   

   

    "globalConfiguration"class="com.baomidou.mybatisplus.entity.GlobalConfiguration">


 


  "dbColumnUnderline"value="true">


 


 


  "idType"value="0">


 


  "tablePrefix"value="tb_">

   


   

     "transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

           "dataSource"ref="dataSource">

     


   

   



[if !supportLists]1.2.3.5    [endif]第五步:整合测试

在这里我们使用静态数据(category.json),来模拟导航菜单接口的实现。


(1)拷贝category.json文件到webapp目录下。

[if !vml]

[endif]


(2)更新项目、安装到本地仓库(updata、maven clean、maven install)

(3)启动项目

[if !vml]

[endif]


查看控制台,启动成功!!!

[if !vml]

[endif]


(4)浏览器访问,地址:http://localhost:8081/category.json,整合成功!!!

[if !vml]

[endif]


[if !supportLists]1.3         [endif]搭建门户系统

[if !supportLists]1.3.1        [endif]系统简介

简单来说就是网站的入口,提供用户浏览、下单的操作页面。

门户系统不直接调用数据库,而是通过服务系统提供的接口获取数据。电商、互联网行业开发都是面向服务开发。

[if !supportLists]1.3.2        [endif]技术选择

核心框架:Spring+SpringMVC

数据库:无

前端技术:jquery、ajax、css+div、easyui等


[if !supportLists]1.3.3        [endif]配置步骤

思路:(1)创建项目

        (2)框架整合


[if !supportLists]1.3.3.1    [endif]第一步:创建maven项目(war模型)

注意:(1)继承ego-project工程

      (2)使用maven module创建子系统

[if !vml]

[endif]


[if !supportLists]1.3.3.2    [endif]第二步:导入jar依赖

在门户系统中,不直接查询数据库,所以不需要导入数据库相关的jar包。

在门户系统中,用户能够搜索、浏览商品,提交订单等,所以需要添加jsp视图相关依赖。

"http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0

  http://maven.apache.org/xsd/maven-4.0.0.xsd">

  4.0.0

 

    cn.gzsxt.ego

    ego-parent

    1.0

 

  cn.gzsxt.ego

  ego-portal

  1.0

  war


 

      

              cn.gzsxt.ego

              ego-base

              1.0

      



      

           jstl

           jstl

      

      

           javax.servlet

           servlet-api

           provided

      

      

           javax.servlet

           jsp-api

           provided

      

          

          

           org.springframework

           spring-context

      

      

      

           org.springframework

           spring-webmvc

      



      

           com.fasterxml.jackson.core

           jackson-databind

      

 

 

      

      

      

           org.apache.tomcat.maven

           tomcat7-maven-plugin

          

              8082

              /

              UTF-8

          

      

   

   


[if !supportLists]1.3.3.3    [endif]第三步:创建web.xml文件

可以从ego-rest工程拷贝,修改配置

"1.0"encoding="UTF-8"?>

"2.5"xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xml="http://www.w3.org/XML/1998/namespace"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_2_5.xsd

  ">

   

       index.html

   


   

     

           characterEncodingFilter

           org.springframework.web.filter.CharacterEncodingFilter


          

               encoding

               utf-8

          


     


 

       characterEncodingFilter

       /*

 


   

       dispatcherServlet

       org.springframework.web.servlet.DispatcherServlet


      

           contextConfigLocation

           classpath:spring-*.xml

      

      

       1

   


   

       dispatcherServlet


      

       *.html

   


[if !supportLists]1.3.3.4    [endif]第四步:导入jsp页面、静态资源

说明:(1)静态资源放在/webapp目录

        (2)jsp放到/WEB-INF/JSP目录下

[if !vml]

[endif]


[if !supportLists]1.3.3.5    [endif]第五步:Spring整合SpringMVC

从ego-rest工程拷贝,修改部分配置即可。

"1.0"encoding="UTF-8"?>

"http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:mvc="http://www.springframework.org/schema/mvc"

    xsi:schemaLocation="http://www.springframework.org/schema/mvc

  http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd

       http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans.xsd

       http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-4.1.xsd">


   

    "cn.gzsxt.portal"/>

   

   


   

    "org.springframework.web.servlet.view.InternalResourceViewResolver">

       "prefix"value="/WEB-INF/jsp/">

       "suffix"value=".jsp">

   



[if !supportLists]1.3.3.6    [endif]第六步:整合测试

需求:访问门户系统首页。


(1)创建PageController类

package cn.gzsxt.portal.controller;


import org.springframework.stereotype.Controller;

import  org.springframework.web.bind.annotation.RequestMapping;


@Controller

public class PageController {


    @RequestMapping("/index")

    public String showIndex(){


       return "index";

    }

}


(2)更新项目、安装到本地仓库。(update、clean、install)

(3)启动项目

[if !vml]

[endif]


(4)访问首页,地址:http://localhost:8082

[if !vml]

[endif]


前台系统搭建成功!!!


[if !supportLists]2            [endif]首页导航菜单实现

说明:首页导航菜单,是通过异步加载实现的。

好处:只有当展开导航菜单时,才会发送请求,从而节约cpu资源。


[if !supportLists]2.1         [endif]实现流程

[if !vml]

[endif]


需要解决的问题:

(1)在rest系统中发布接口,封装导航菜单成json格式数据。

(2)在portal系统中,远程请求接口(跨域请求)。


[if !supportLists]2.2         [endif]跨越请求

[if !supportLists]2.2.1        [endif]什么是跨域(两个不同系统之间的访问、调用)

(1)域名不同,即两个不同的应用。

[if !vml]

[endif]


(2)域名相同,但是端口不同,即同一个应用中的不同子系统。

[if !vml]

[endif]


[if !supportLists]2.2.2        [endif]Ajax跨域请求的缺陷

在ego-rest系统使用静态数据,模拟Ajax的跨域问题。


[if !supportLists]2.2.2.1    [endif]第一步:在ego-rest中添加category.json文件。(已实现)

[if !supportLists]2.2.2.2    [endif]第二步:在ego-portal中发送ajax请求

(1)创建testJsonp.jsp页面

<%@pagelanguage="java"contentType="text/html;

  charset=UTF-8"

    pageEncoding="UTF-8"%>

  HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">

"Content-Type"content="text/html; charset=UTF-8">

"text/javascript"src="/js/jquery-1.6.4.js">

Insert title here

"text"style="width: 1200px; height: 200px;">

"button"value="测试异步跨越"onclick="testajax()"  />

"text/javascript">

    function testajax(){

       $.ajax({

           url:"http://localhost:8081/category.json",

           type:"GET",

           success:function (data) {

              $("#text").val(JSON.stringify(data));

           }

       });

    }


(2)修改PageController,新增访问非首页的方法。

@RequestMapping("/{page}")

public String showPage(@PathVariable("page")String page){


    return page;

}


[if !supportLists]2.2.2.3    [endif]第三步:测试Ajax跨越

(1)重启启动ego-portal系统,访问testJsonp.jsp

[if !vml]

[endif]

(2)点击按钮,发送异步请求

[if !vml]

[endif]


测试发现,Ajax跨越请求失败了。


[if !supportLists]2.2.3        [endif]解决方案:jsonp跨域

在前面的测试中,我们发现Ajax跨越请求时,json数据被浏览器禁用了。

原因:浏览器禁止远程加载Json数据。(浏览器安全机制)


如何解决呢?

答:使用Jsonp方式。


[if !supportLists]2.2.3.1    [endif]Jsonp原理

Jsonp实现的前提:

浏览器允许跨越加载同源数据。

即在JavaScript脚本中发送请求,就可以远程加载js格式数据。


请求原理:

(1)异步请求的时候,加上一个名为callback的回调函数

(2)在接口中,将返回的json格式数据,伪装成js脚本格式。

(3)得到js格式数据后,提取里面的json数据。

[if !vml]

[endif]


[if !supportLists]2.2.3.2    [endif]测试Jsonp

(1)修改testJsonp.jsp,指定异步请求为jsonp方式。

"text/javascript">

    function testajax(){

       $.ajax({

           url:"http://localhost:8081/category.json",

           type:"GET",

           dataType:"jsonp",  

  //jsonp请求

           jsonp:"callbackFunction", 

  //请求参数名

           jsonpCallback:"showData", 

  //回调函数名称

           success:function (data) {

              $("#text").val(JSON.stringify(data));

           }

       });

    }


(2)在ego-rest工程中,修改category.json文件,将返回数据包装成js脚本。

[if !vml]

[endif]


(3)再次发送ajax异步请求,使用jsonp方式

[if !vml]

[endif]


结论:(1)jsonp是ajax技术中的一种异步请求方式。

     (2)jsonp能实现跨越请求。

     (3)jsonp跨越时,需要指定一个回调函数,并使用该函数将返回的数据伪装成js脚本。

     (4)获取返回的js脚本后,jsonp自动提取其中的json数据。


[if !supportLists]2.3         [endif]首页导航菜单实现

思路:

(1)在rest工程中,开发接口,返回js格式数据。(参考category.json)

(2)在portal工程中,修改jsonp请求路径。请求rest接口。


[if !supportLists]2.3.1        [endif]第一部分:在rest工程中开发导航菜单接口

[if !supportLists]2.3.1.1    [endif]第一步:定义导航菜单POJO

导航菜单结构分析。(使用JsonViewer工具查看category.json)

[if !vml]

[endif]


结论:(1)需要定义两个POJO:菜单POJO、父目录节点POJO

     (2)导航菜单的数据,是一次加载出来的。


创建菜单Menu类。(ego-base中创建)

package cn.gzsxt.base.pojo;


import java.util.List;


/**

 *自定义导航菜单

 *@authorccnulyq

 *

 */

public class Menu {


    private List data;  //目录节点


    public List getData() {

       return data;

    }


    public void setData(List data) {

       this.data = data;

    }


    public Menu() {

       super();

    }

}


创建父目录节点MenuNode类

package cn.gzsxt.base.pojo;


import java.util.List;


/**

 *自定义目录节点结构

 *@authorccnulyq

 *

 */

public class MenuNode {


    private String u;    //目录的链接


    private String n;    //目录的名称


    private List i;   //当请目录的子目录


    public MenuNode() {

       super();

    }

//

  补全getset方法

}

 

(3)重新编译ego-base工程,安装到本地仓库。(maven clean、maven install


[if !supportLists]2.3.1.2    [endif]第二步:创建ItemCatService接口及其实现类

package cn.gzsxt.rest.service.impl;


import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import cn.gzsxt.base.mapper.ItemCatMapper;

import cn.gzsxt.base.pojo.ItemCat;

import cn.gzsxt.base.vo.Menu;

import cn.gzsxt.base.vo.MenuNode;

import cn.gzsxt.rest.service.ItemCatService;


@Service

public class ItemCatServiceImpl implements ItemCatService{


    @Autowired

    private ItemCatMapper itemCatMapper;


    @Override

    public Menu initMenu() {


       Menumenu = new Menu();


       //从返回值Menu的形式上来看,就是把一级目录查询出来即可。因此定义一个查询方法,通过parent_id=0查询一级目录

       Listnodes = getNodesByParantId(0L);

       menu.setData(nodes);


       return menu;

    }


    //根据父目录的id,查询子目录

    private List getNodesByParantId(long parentId) {


       Mapparams = new HashMap<>();

       params.put("parent_id", parentId);


       ListselectByMap = itemCatMapper.selectByMap(params);


       Listnodes = new ArrayList<>();


       MenuNodenode = null;

       for (ItemCat itemCat : selectByMap) {

           if(1==itemCat.getIsParent()){

              node = new MenuNode();


              node.setU("/products/"+itemCat.getId()+".html");    

  //u :

  "/products/1.html"

              node.setN(""+itemCat.getName()+"");     //n : "图书、音像、电子书刊"

              node.setI(getNodesByParantId(itemCat.getId())); 


              nodes.add(node);


           }else{

               nodes.add("/products/"+itemCat.getId()+".html|"+itemCat.getName());     //[3] : "/products/6.html|多媒体图书"

           }

       }


       return nodes;

    }

}


[if !supportLists]2.3.1.3    [endif]第三步:创建ItemCatController类

说明:需要将返回值,包装成js脚本数据。


(1)方式一:手动封装

package cn.gzsxt.rest.controller;


import  org.springframework.beans.factory.annotation.Autowired;

import org.springframework.http.MediaType;

import org.springframework.stereotype.Controller;

import  org.springframework.web.bind.annotation.RequestMapping;

import  org.springframework.web.bind.annotation.ResponseBody;

import cn.gzsxt.base.utils.JsonUtils;

import cn.gzsxt.base.vo.Menu;

import cn.gzsxt.rest.service.ItemCatService;


@Controller

public class ItemCatController {


    @Autowired

    private ItemCatService catService;


    /*

     *jsonp方法下,返回值,要使用回调函数来伪装js脚本

     * @return

     */

    @RequestMapping(value="/item/all",produces=MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8")

    @ResponseBody

    public String getMenu(String callback){

       Menumenu = catService.initMenu();

       StringjsonMenu= JsonUtils.objectToJson(menu);

       StringjsMenu = callback+"("+jsonMenu+")";


       return jsMenu;

    }

}


(2)方式二:使用MappingJacksonValue对象封装

//使用MappingJacksonValue对象包装返回结果,并设置jsonp的回调方法

    @RequestMapping("/item/all")

    @ResponseBody

    public MappingJacksonValue

  queryAll(String callback) {

       //查询分类列表

       Menumenu = catService.getMenu();

       //包装jsonp

       MappingJacksonValuejacksonValue = new MappingJacksonValue(menu);

       //设置包装的回调方法名

       jacksonValue.setJsonpFunction(callback);

       return jacksonValue;

    }


[if !supportLists]2.3.1.4    [endif]第四步:测试接口

在浏览器访问。

地址:http://localhost:8081/rest/item/all?callback=category.getDataService

[if !vml]

[endif]


[if !supportLists]2.3.2        [endif]第二部分:在portal工程中调用导航菜单接口

[if !supportLists]2.3.2.1    [endif]第一步:指定请求方式为jsonp

(1)修改lib-v1.js文件,指定导航菜单接口地址。

[if !vml]

[endif]


(2)修改lib-v1.js文件,指定请求方式为jsonp。

[if !vml]

[endif]


[if !supportLists]2.3.2.2    [endif]第二步:测试导航菜单

(1)重启portal工程

(2)访问首页,请求导航菜单

[if !vml]

[endif]

导航菜单开发成功!!!

你可能感兴趣的:(电商项目(三))