淘淘商城第六天


 

1   课程计划

1、前台系统搭建

a)        Taotao-rest:服务层没有jsp页面

b)       Taotao-portal:门户,表现层。

2、首页分类列表展示

a)        使用ajax调用服务层的服务。

b)       跨域问题。使用jsonp解决。

 

今天内容

首页大广告位的实现。

1、cms系统的实现

2、发布服务

3、调用服务展示内容

 

2   首页大广告位的实现分析

首页的内容需要动态管理,需要后台管理功能。

 

抽取首页展示内容的共性:

1、有一张图片

2、有一个连接

3、有一个标题

4、有链接的提示

5、价格

 

需要把内容进行分类,分类应该是一个树形结构。

 

在展示首页时,可以根据分类取内容信息,把内容展示到页面。

 

在后台管理内容及内容分类的系统就叫做cms系统。

 

3   Cms系统

先实现内容的分类管理再实现内容管理。

 

3.1  内容分类管理

3.1.1   内容分类初始化

3.1.1.1        需求分析

 

初始化树形视图的url:/content/category/list

参数是id,当前节点id属性,应该根据此id查询子节点列表。

返回值:包含id、text、state三个属性的json数据列表

 

3.1.1.2        Dao层

表结构:

Sql语句:

根据parentid查询节点列表

SELECT * FROM `tb_content_category` WHEREparent_id = 30;

 

单表查询可以实现逆向工程生成的代码。

 

3.1.1.3        Service层

功能:接收parentid。根据parentid查询节点列表,返回返回一个EasyUI异步Tree要求的节点列表。每个节点包含三个属性id、text、state三个属性。可以使用EUTreeNode。

参数:id

返回值:List<EUTreeNode>

 

@Service

public class ContentCategoryServiceImpl implements ContentCategoryService {

 

     @Autowired

     private TbContentCategoryMapper contentCategoryMapper;

     @Override

     public List<EUTreeNode> getCategoryList(long parentId) {

         //根据parentid查询节点列表

         TbContentCategoryExample example = new TbContentCategoryExample();

         Criteria criteria = example.createCriteria();

         criteria.andParentIdEqualTo(parentId);

         //执行查询

         List<TbContentCategory> list = contentCategoryMapper.selectByExample(example);

         List<EUTreeNode> resultList = new ArrayList<>();

         for (TbContentCategory tbContentCategory : list) {

              //创建一个节点

              EUTreeNode node = new EUTreeNode();

              node.setId(tbContentCategory.getId());

              node.setText(tbContentCategory.getName());

              node.setState(tbContentCategory.getIsParent()?"closed":"open");

             

              resultList.add(node);

         }

         returnresultList;

     }

 

}

 

3.1.1.4        Controller

接收页面传递过来的parentid,根据parentid查询节点列表。返回List<EUTreeNode>。需要响应json数据。

@Controller

@RequestMapping("/content/category")

public class ContentCategoryController {

 

    @Autowired

    private ContentCategoryService contentCategoryService;

   

    @RequestMapping("/list")

     @ResponseBody

    public List<EUTreeNode> getContentCatList(@RequestParam(value="id", defaultValue="0")Long parentId) {

        List<EUTreeNode> list = contentCategoryService.getCategoryList(parentId);

        returnlist;

    }

}

 

 

3.1.2   内容分类添加

3.1.2.1        需求分析

请求的url:/content/category/create

参数:

1、parentId父节点id

2、name:当前节点的名称

返回值:TaotaoResult。其中包含节点pojo对象。

 

3.1.2.2        Dao层

可以使用逆向工程生成的代码

 

3.1.2.3        Service层

功能:接收两个参数parentId父节点id、name:当前节点的名称。向tb_content_category表中添加一条记录。返回TaoTaoResult包含记录的pojo对象。

 

需要返回主键信息:

需要修改mapper文件,返回主键信息。

@Override

     public TaotaoResult insertContentCategory(long parentId, String name) {

        

         //创建一个pojo

         TbContentCategory contentCategory = new TbContentCategory();

         contentCategory.setName(name);

         contentCategory.setIsParent(false);

         //'状态。可选值:1(正常),2(删除)',

         contentCategory.setStatus(1);

         contentCategory.setParentId(parentId);

         contentCategory.setSortOrder(1);

         contentCategory.setCreated(new Date());

         contentCategory.setUpdated(new Date());

         //添加记录

         contentCategoryMapper.insert(contentCategory);

         //查看父节点的isParent列是否为true,如果不是true改成true

         TbContentCategory parentCat = contentCategoryMapper.selectByPrimaryKey(parentId);

         //判断是否为true

         if(!parentCat.getIsParent()) {

              parentCat.setIsParent(true);

              //更新父节点

              contentCategoryMapper.updateByPrimaryKey(parentCat);

         }

         //返回结果

         return TaotaoResult.ok(contentCategory);

     }

3.1.2.4        Controller层

接收两个参数parentid、name。调用Service添加记录。返回TaotaoResult。应该返回json数据。

@RequestMapping("/create")

     @ResponseBody

     public TaotaoResult createContentCategory(Long parentId, String name) {

         TaotaoResult result = contentCategoryService.insertContentCategory(parentId, name);

         return result;

     }

 

3.1.3   内容分类删除

需求分析:

请求的url:

/content/category/delete/

参数:

1、parentId

2、Id

返回值:TaotaoResult

 

业务逻辑:

接收parentid、id两个参数。删除id对应的记录。需要判断parentid对应的记录下是否有子节点。如果没有子节点。需要把parentid对应的记录的isparent改成false。

注意:删除直接是物理删除。

 

3.1.4   重命名节点

1、

2、当编辑完成后会触发onAfterEdit事件。

请求的url:/content/category/update

参数:id、name

返回值:返回TaotaoResult。Json格式

 

业务逻辑:根据id更新记录的name列即可。

 

3.2  内容管理

内容管理表:

3.2.1   内容列表

需求分析

请求url:/content/query/list

参数:page、rows、categoryId

返回值:EUDataGridResult

Total、rows:内容pojo列表。

 

业务逻辑:

根据内容分类id查询内容列表。需要实现分页。返回EUDataGridResult

 

3.2.2   内容添加

需求分析:

图片上传初始化:

内容表单提交:

请求的url:/content/save

请求的方法:post

请求内容:表单中的内容。

返回的结果:TaotaoResult。

 

3.2.3   Dao层

向tb_content表中插入数据。可以使用逆向工程生成的代码。

 

3.2.4   Service层

接收表tb_content对应的pojo对象。把pojo对象插入到tb_content表中。

返回TaotaoResult。

@Service

public class ContentServiceImpl implements ContentService {

 

     @Autowired

     private TbContentMapper  contentMapper;

    

     @Override

     public TaotaoResult insertContent(TbContent content) {

         //补全pojo内容

         content.setCreated(new Date());

         content.setUpdated(new Date());

         contentMapper.insert(content);

        

         return TaotaoResult.ok();

     }

 

}

 

3.2.5   Controller层

接收表单中的内容,使用pojo接收。要求pojo的属性要和表单中的name一致。调用Service插入内容信息。返回TaotaoResult。Json格式的数据。

@Controller

@RequestMapping("/content")

public class ContentController {

 

     @Autowired

     private ContentService contentService;

    

     @RequestMapping("/save")

     @ResponseBody

     public TaotaoResult insertContent(TbContent content) {

         TaotaoResult result = contentService.insertContent(content);

         returnresult;

     }

}

 

4   展示商城首页大广告位

4.1  首页大广告方案

前端系统获取后端系统提供的接口,如何获取?

 

4.1.1   方案1

jsonp跨域请求

 

需要当首页加载完毕后,大广告位就应该显示。没有触发事件。不是太合适。

优点:不需要二次请求,页面直接加载内容数据。减少门户系统的压力。

缺点:需要延迟加载。不利于seo优化。

 

 

 

4.1.2   第二种方案:

优点:有利于seo优化。可以在taotao-portal中对数据进行加工。

缺点:系统直接需要调用服务查询内容信息。多了一次http请求。

 

系统直接服务的调用,需要使用httpclient来实现。Taotao-portal和taotao-rest是在同一个局域网内部。速度非常快,调用时间可以忽略不计。

 

展示首页内容功能,使用方案二实现。

4.2  展示流程

4.3  内容服务发布

4.3.1   需求分析

根据内容的分类id查询内容列表,从tb_content表中查询。服务是一个restFul形式的服务。使用http协议传递json格式的数据。

 

4.3.2   Dao层

从tb_content表中查询,根据内容分类id查询。是单表查询。可以使用逆向工程生成的代码。

 

4.3.3   Service层

接收内容分类id,根据分类id查询分类列表。返回一个内容pojo列表。

参数:分类id

返回值:pojo列表

 

@Service

public class ContentServiceImpl implements ContentService {

 

     @Autowired

     private TbContentMapper contentMapper;

     @Override

     public List<TbContent> getContentList(long contentCid) {

         //根据内容分类id查询内容列表

         TbContentExample example = new TbContentExample();

         Criteria criteria = example.createCriteria();

         criteria.andCategoryIdEqualTo(contentCid);

         //执行查询

         List<TbContent> list = contentMapper.selectByExample(example);

        

         return list;

     }

 

}

 

4.3.4   Controller层

发布服务。接收查询参数。Restful风格内容分类id应该从url中取。

/rest/content/list/{contentCategoryId}

从url中取内容分类id,调用Service查询内容列表。返回内容列表。返回一个json格式的数据。可以使用TaotaoResult包装此列表。

@Controller

@RequestMapping("/content")

public class ContentController {

 

     @Autowired

     private ContentService contentService;

    

     @RequestMapping("/list/{contentCategoryId}")

     @ResponseBody

     public TaotaoResult getContentList(@PathVariable Long contentCategoryId) {

         try {

              List<TbContent> list = contentService.getContentList(contentCategoryId);

              return TaotaoResult.ok(list);

         } catch (Exception e) {

              e.printStackTrace();

              return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));

         }

     }

}

 

4.4  Httpclient的使用

4.4.1   什么是httpclient

HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
下载地址:

http://hc.apache.org/

 

4.4.2   添加依赖

 

需要把httpclient的jar包添加到工程中。只需要在工程中添加httpclient的依赖。

 

4.4.3   使用方法

4.4.3.1        使用httpclient执行get请求

@Test

     public void doGet() throws Exception {

         //创建一个httpclient对象

         CloseableHttpClient httpClient = HttpClients.createDefault();

         //创建一个GET对象

         HttpGet get = new HttpGet("http://www.sogou.com");

         //执行请求

         CloseableHttpResponse response = httpClient.execute(get);

         //取响应的结果

         int statusCode = response.getStatusLine().getStatusCode();

         System.out.println(statusCode);

         HttpEntity entity = response.getEntity();

         String string = EntityUtils.toString(entity, "utf-8");

         System.out.println(string);

         //关闭httpclient

         response.close();

         httpClient.close();

     }

 

4.4.3.2        执行get请求带参数

@Test

     public void doGetWithParam() throws Exception{

         //创建一个httpclient对象

         CloseableHttpClient httpClient = HttpClients.createDefault();

         //创建一个uri对象

         URIBuilder uriBuilder = new URIBuilder("http://www.sogou.com/web");

         uriBuilder.addParameter("query", "花千骨");

         HttpGet get = new HttpGet(uriBuilder.build());

         //执行请求

         CloseableHttpResponse response = httpClient.execute(get);

         //取响应的结果

         int statusCode = response.getStatusLine().getStatusCode();

         System.out.println(statusCode);

         HttpEntity entity = response.getEntity();

         String string = EntityUtils.toString(entity, "utf-8");

         System.out.println(string);

         //关闭httpclient

         response.close();

         httpClient.close();

     }

 

4.4.3.3        使用httpclient执行post请求

@Test

      public void doPost() throws Exception {

           CloseableHttpClient httpClient = HttpClients.createDefault();

     

           //创建一个post对象

           HttpPost post = new HttpPost("http://localhost:8082/httpclient/post.html");

           //执行post请求

           CloseableHttpResponse response = httpClient.execute(post);

           String string = EntityUtils.toString(response.getEntity());

           System.out.println(string);

           response.close();

           httpClient.close();

          

      }

 

4.4.3.4        带参数post请求

 

     @Test

     public void doPostWithParam() throws Exception{

         CloseableHttpClient httpClient = HttpClients.createDefault();

        

         //创建一个post对象

         HttpPost post = new HttpPost("http://localhost:8082/httpclient/post.html");

         //创建一个Entity。模拟一个表单

         List<NameValuePair> kvList = new ArrayList<>();

         kvList.add(new BasicNameValuePair("username", "zhangsan"));

         kvList.add(new BasicNameValuePair("password", "123"));

        

         //包装成一个Entity对象

         StringEntity entity = new UrlEncodedFormEntity(kvList, "utf-8");

         //设置请求的内容

         post.setEntity(entity);

        

         //执行post请求

         CloseableHttpResponse response = httpClient.execute(post);

         String string = EntityUtils.toString(response.getEntity());

         System.out.println(string);

         response.close();

         httpClient.close();

     }

 

4.4.4   Httpclient封装成工具类

其他项目也可能会用到httpclient,所以把工具类放到taotao-common中。

5   大广告位展示

5.1  需求分析

需要创建一个json字符串传递给jsp:

Json字符串如何传递给jsp:使用modelAndView对象把json字符串传递给jsp。

如何获得json字符串:获得一个广告位对应的内容列表,需要调用taotao-rest的服务。把列表转换成json数据格式要求的pojo对象列表。

需要使用httpclient调用taotao-rest的服务。

 

5.2  Dao层

没有

 

5.3  Service层

根据内容分类id查询分类的内容列表,需要使用httpclient调用taotao-rest的服务。得到一个json字符串。需要把字符串转换成java对象taotaoResult对象。从taotaoResult对象中取data属性,得到内容列表。把内容列表转换成jsp页面要求的json格式。返回一个json字符串。

参数:没有参数

返回值:json字符串。

@Service

public class ContentServiceImpl implements ContentService {

 

     @Value("${REST_BASE_URL}")

     private String REST_BASE_URL;

     @Value("${REST_INDEX_AD_URL}")

     private String REST_INDEX_AD_URL;

    

     @Override

     public String getContentList() {

         //调用服务层的服务

         String result = HttpClientUtil.doGet(REST_BASE_URL + REST_INDEX_AD_URL);

         //把字符串转换成TaotaoResult

         try {

              TaotaoResult taotaoResult = TaotaoResult.formatToList(result, TbContent.class);

              //取内容列表

              List<TbContent> list = (List<TbContent>) taotaoResult.getData();

              List<Map> resultList = new ArrayList<>();

              //创建一个jsp页码要求的pojo列表

              for (TbContent tbContent : list) {

                   Map map = new HashMap<>();

                   map.put("src", tbContent.getPic());

                   map.put("height", 240);

                   map.put("width", 670);

                   map.put("srcB", tbContent.getPic2());

                   map.put("widthB", 550);

                   map.put("heightB", 240);

                   map.put("href", tbContent.getUrl());

                   map.put("alt", tbContent.getSubTitle());

                   resultList.add(map);

              }

              return JsonUtils.objectToJson(resultList);

         } catch (Exception e) {

              e.printStackTrace();

         }

        

         returnnull;

     }

 

}

 

5.4  Controller

展示首页返回一个逻辑视图,需要把首页大广告位的json数据传递给jsp。

@RequestMapping("/index")

     public String showIndex(Model model) {

         String adJson = contentService.getContentList();

         model.addAttribute("ad1", adJson);

        

         return "index";

     }

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值