框架 day78 涛涛商城项目-CMS内容管理,httpclient使用,首页ad展示

淘淘商城第六天

                              讲师:入云龙

 

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


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

 

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

1、有一张图片

2、有一个连接

3、有一个标题

4、有链接的提示

5、价格

 

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

 

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

 

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

 

2  Cms系统


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

 

2.1    内容分类管理

2.1.1  内容分类初始化

2.1.1.1 需求分析


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


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

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

 

2.1.1.2 Dao层

需要一张表存储内容数据:字段:标题、url、子标题、image、内容分类id等等

需要一张表存储内容的分类信息,树形结构的表。

 

表结构:

内容分类表


内容表


Sql语句:

根据parentid查询节点列表

SELECT * FROM `tb_content_category` WHEREparent_id = 30;

 

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

 

2.1.1.3 Service层

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

参数:id

返回值:List<EUTreeNode>

 

@Service

public class ContentCategoryServiceImpl implements ContentCategoryService {

 

     @Autowired

     private TbContentCategoryMappercontentCategoryMapper;

     @Override

     public List<EUTreeNode> getCategoryList(longparentId) {

          //根据parentid查询节点列表

          TbContentCategoryExample example =new TbContentCategoryExample();

          Criteria criteria = example.createCriteria();

          criteria.andParentIdEqualTo(parentId);

          //执行查询

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

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

          for (TbContentCategorytbContentCategory : list) {

               //创建一个节点

               EUTreeNode node =new EUTreeNode();

               node.setId(tbContentCategory.getId());

               node.setText(tbContentCategory.getName());

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

              

               resultList.add(node);

          }

          returnresultList;

     }

 

}

 

2.1.1.4 Controller

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

@Controller

@RequestMapping("/content/category")

public class ContentCategoryController {

 

    @Autowired

    private ContentCategoryServicecontentCategoryService;

   

    @RequestMapping("/list")

     @ResponseBody

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

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

         returnlist;

    }

}

 

 

2.1.2  内容分类添加

2.1.2.1 需求分析

请求的url:/content/category/create

参数:

1、parentId父节点id

2、name:当前节点的名称

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

 

2.1.2.2 Dao层

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

 

2.1.2.3 Service层

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

 

需要返回主键信息:

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

方式一:


方式二:

  <insert id="insert" parameterType="com.taotao.pojo.TbContentCategory" useGeneratedKeys="true"keyProperty="id">

    insert into tb_content_category (id, parent_id, name,

      status, sort_order, is_parent,

      created, updated)

    values (#{id,jdbcType=BIGINT}, #{parentId,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR},

      #{status,jdbcType=INTEGER}, #{sortOrder,jdbcType=INTEGER}, #{isParent,jdbcType=BIT},

      #{created,jdbcType=TIMESTAMP}, #{updated,jdbcType=TIMESTAMP})

  </insert>

 

@Override

     public TaotaoResult insertContentCategory(longparentId, 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);

     }

2.1.2.4 Controller层

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

@RequestMapping("/create")

     @ResponseBody

     public TaotaoResult createContentCategory(LongparentId, String name) {

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

          returnresult;

     }

 

2.1.3  内容分类删除

需求分析:

请求的url:

/content/category/delete/

参数:

1、parentId

2、Id

返回值:TaotaoResult

 

业务逻辑:

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

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


 

2.1.4  重命名节点

1、


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


请求的url:/content/category/update

参数:id、name

返回值:返回TaotaoResult。Json格式

 

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

 

2.2    内容管理

内容管理表:


2.2.1  内容列表

需求分析

请求url:/content/query/list


参数:page、rows、categoryId


返回值:EUDataGridResult

Total、rows:内容pojo列表。

 

业务逻辑:

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

 

2.2.2  内容添加

需求分析:


图片上传初始化:


内容表单提交:


请求的url:/content/save

请求的方法:post

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

返回的结果:TaotaoResult。

 

2.2.3  Dao层

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

 

2.2.4  Service层

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

返回TaotaoResult。

@Service

public class ContentServiceImpl implements ContentService {

 

     @Autowired

     private TbContentMapper contentMapper;

    

     @Override

     public TaotaoResult insertContent(TbContentcontent) {

          //补全pojo内容

          content.setCreated(new Date());

          content.setUpdated(new Date());

          contentMapper.insert(content);

         

          return TaotaoResult.ok();

     }

 

}

 

2.2.5  Controller层

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

@Controller

@RequestMapping("/content")

public class ContentController {

 

     @Autowired

     private ContentServicecontentService;

    

     @RequestMapping("/save")

     @ResponseBody

     public TaotaoResult insertContent(TbContent content) {

          TaotaoResult result =contentService.insertContent(content);

          returnresult;

     }

}

 

3  展示商城首页大广告位

3.1    首页大广告方案

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

 

3.1.1  方案1

jsonp跨域请求

 

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

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

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

 

 

 

3.1.2  第二种方案:


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

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

 

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

 

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

3.2    展示流程


3.3    内容服务发布

3.3.1  需求分析

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

 

3.3.2  Dao层

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

 

3.3.3  Service层

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

参数:分类id

返回值:pojo列表

 

@Service

public class ContentServiceImpl implements ContentService {

 

     @Autowired

     private TbContentMappercontentMapper;

     @Override

     public List<TbContent> getContentList(longcontentCid) {

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

          TbContentExample example =new TbContentExample();

          Criteria criteria = example.createCriteria();

          criteria.andCategoryIdEqualTo(contentCid);

          //执行查询

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

         

          returnlist;

     }

 

}

 

3.3.4  Controller层

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

/rest/content/list/{contentCategoryId}

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

@Controller

@RequestMapping("/content")

public class ContentController {

 

     @Autowired

     private ContentServicecontentService;

    

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

     @ResponseBody

     public TaotaoResult getContentList(@PathVariable LongcontentCategoryId) {

          try {

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

               return TaotaoResult.ok(list);

          } catch (Exceptione) {

               e.printStackTrace();

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

          }

     }

}

 

3.4    Httpclient的使用

3.4.1  什么是httpclient

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


HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
下载地址:

http://hc.apache.org/


以下列出的是 HttpClient 提供的主要的功能,要知道更多详细的功能可以参见 HttpClient 的主页。

(1)实现了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)

(2)支持自动转向

(3)支持 HTTPS 协议

(4)支持代理服务器等


 

3.4.2  添加依赖

 

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

 

3.4.3  使用方法

3.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);

          //取响应的结果

          intstatusCode = 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();

     }

 

3.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);

          //取响应的结果

          intstatusCode = 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();

     }

 

3.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();

           

      }

 

3.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();

     }

 

3.4.4  Httpclient封装成工具类

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

 

 

public class HttpClientUtil {

 

         public static String doGet(String url, Map<String, String> param) {

 

                  // 创建Httpclient对象

                  CloseableHttpClient httpclient = HttpClients.createDefault();

 

                  String resultString = "";

                  CloseableHttpResponse response = null;

                  try {

                          // 创建uri

                          URIBuilder builder = new URIBuilder(url);

                          if (param != null) {

                                   for (String key : param.keySet()) {

                                            builder.addParameter(key, param.get(key));

                                   }

                          }

                          URI uri = builder.build();

 

                          // 创建http GET请求

                          HttpGet httpGet = new HttpGet(uri);

 

                          // 执行请求

                          response = httpclient.execute(httpGet);

                          // 判断返回状态是否为200

                          if (response.getStatusLine().getStatusCode() == 200) {

                                   resultString = EntityUtils.toString(response.getEntity(), "UTF-8");

                          }

                  } catch (Exception e) {

                          e.printStackTrace();

                  } finally {

                          try {

                                   if (response != null) {

                                            response.close();

                                   }

                                   httpclient.close();

                          } catch (IOException e) {

                                   e.printStackTrace();

                          }

                  }

                  return resultString;

         }

 

         public static String doGet(String url) {

                  return doGet(url, null);

         }

 

         public static String doPost(String url, Map<String, String> param) {

                  // 创建Httpclient对象

                  CloseableHttpClient httpClient = HttpClients.createDefault();

                  CloseableHttpResponse response = null;

                  String resultString = "";

                  try {

                          // 创建Http Post请求

                          HttpPost httpPost = new HttpPost(url);

                          // 创建参数列表

                          if (param != null) {

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

                                   for (String key : param.keySet()) {

                                            paramList.add(new BasicNameValuePair(key, param.get(key)));

                                   }

                                   // 模拟表单

                                   UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);

                                   httpPost.setEntity(entity);

                          }

                          // 执行http请求

                          response = httpClient.execute(httpPost);

                          resultString = EntityUtils.toString(response.getEntity(), "utf-8");

                  } catch (Exception e) {

                          e.printStackTrace();

                  } finally {

                          try {

                                   response.close();

                          } catch (IOException e) {

                                   // TODO Auto-generated catch block

                                   e.printStackTrace();

                          }

                  }

 

                  return resultString;

         }

 

         public static String doPost(String url) {

                  return doPost(url, null);

         }

        

         public static String doPostJson(String url, String json) {

                  // 创建Httpclient对象

                  CloseableHttpClient httpClient = HttpClients.createDefault();

                  CloseableHttpResponse response = null;

                  String resultString = "";

                  try {

                          // 创建Http Post请求

                          HttpPost httpPost = new HttpPost(url);

                          // 创建请求内容

                          StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);

                          httpPost.setEntity(entity);

                          // 执行http请求

                          response = httpClient.execute(httpPost);

                          resultString = EntityUtils.toString(response.getEntity(), "utf-8");

                  } catch (Exception e) {

                          e.printStackTrace();

                  } finally {

                          try {

                                   response.close();

                          } catch (IOException e) {

                                   // TODO Auto-generated catch block

                                   e.printStackTrace();

                          }

                  }

 

                  return resultString;

         }

}

 

4  大广告位展示

4.1    需求分析




需要创建一个json字符串传递给jsp:使用EL表达式${ad1} 接收

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

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

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

 

4.2    Dao层

没有

 

4.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 StringREST_BASE_URL;

     @Value("${REST_INDEX_AD_URL}")

     private StringREST_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 (TbContenttbContent : 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 (Exceptione) {

               e.printStackTrace();

          }

         

          returnnull;

     }

 

}

 

4.4    Controller

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

@RequestMapping("/index")

     public String showIndex(Modelmodel) {

          String adJson = contentService.getContentList();

          model.addAttribute("ad1", adJson);

         

          return"index";

     }


效果


 

`jbundle-util-osgi-wrapped-httpclient` 是一个用于在 OSGi(开放服务网关倡议)环境中使用 Apache HttpClient 的工具库。它提供了将 Apache HttpClient 封装为 OSGi 插件的功能,使得在 OSGi 容器中可以方便地使用 HttpClient 进行 HTTP 请求和处理。 Apache HttpClient 是一个功能强大的 HTTP 客户端库,用于在 Java 应用程序中进行 HTTP 通信。它提供了丰富的功能和灵活的配置选项,包括支持各种 HTTP 方法、处理认证和代理、处理 Cookie、支持连接池等。 使用 `jbundle-util-osgi-wrapped-httpclient` 可以进行以下操作: 1. 封装 Apache HttpClient:`jbundle-util-osgi-wrapped-httpclient` 将 Apache HttpClient 封装为 OSGi 插件,使得它可以在 OSGi 容器中进行动态加载和管理。这样你就可以通过 OSGi 的方式来使用 HttpClient,而无需手动处理其依赖和生命周期管理。 2. OSGi 配置和服务:工具库提供了一些实用方法和类,用于在 OSGi 环境中配置和使用 HttpClient。它提供了 OSGi 配置管理器和服务注册的支持,使得你可以方便地配置和获取 HttpClient 实例。 3. HTTP 请求和响应处理:`jbundle-util-osgi-wrapped-httpclient` 提供了一些工具类和方法,用于发送 HTTP 请求和处理响应。你可以使用这些工具来构建和发送 HTTP 请求,并处理服务器返回的响应数据。 需要注意的是,`jbundle-util-osgi-wrapped-httpclient` 是一个针对 OSGi 环境的工具库,主要用于在 OSGi 容器中使用 Apache HttpClient。如果你不使用 OSGi,可以直接使用 Apache HttpClient 的原生库。 希望这个解释对你有帮助!如果你有任何其他问题,请随时提问。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值