上一篇我们讲到了首页左侧栏的商品分类类目的展示,效果如下:
以上这种是基于同一个项目中,ajax直接请求获得json数据的,不涉及不同项目(url、ip、域名、或者端口有一个不同就是跨域)之间的服务请求调用,属于本项目中的静态调用,如果想动态发布rest服务,并在其他项目中进行js调用,则必须使用jquery的GetJSONP方法跨域进行数据的请求
一、我们在rest项目中,根据category.json数据的格式,创建两个pojo(类)如下:
ItemCatResult.java
package com.taotao.rest.pojo;
import java.util.List;
public class ItemCatResult {
private List data ;
public List getData() {
return data;
}
public void setData(List data) {
this.data = data;
}
}
CatNode.java
package com.taotao.rest.pojo;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
public class CatNode {
//JsonProperty注解作用于属性 -- 把属性名称序列化另外一个名称
@JsonProperty("u")
private String url ;
@JsonProperty("n")
private String name ;
@JsonProperty("i")
private List items;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List getItems() {
return items;
}
public void setItems(List items) {
this.items = items;
}
}
二、创建Service,基于tb_item_cat的单表查询,返回一个ItemCatResult对象(mybatis逆向工程+方法递归调用)
ItemCatService.java(接口)
package com.taotao.rest.service;
import com.taotao.rest.pojo.ItemCatResult;
public interface ItemCatService {
ItemCatResult getItemCatList();
}
ItemCatServiceImpl.java(接口实现)
package com.taotao.rest.service.impl;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.taotao.mapper.TbItemCatMapper;
import com.taotao.pojo.TbItemCat;
import com.taotao.pojo.TbItemCatExample;
import com.taotao.pojo.TbItemCatExample.Criteria;
import com.taotao.rest.pojo.CatNode;
import com.taotao.rest.pojo.ItemCatResult;
import com.taotao.rest.service.ItemCatService;
/**
* Title: ItemCatServiceImpl.java
* Description:商品类目JSON数据封装,递归调用实现
* Blog: http://blog.csdn.net/appleyk
* @author Appleyk
* @date 2017年11月6日 下午5:18:16
* @version 1.0
*/
@Service
public class ItemCatServiceImpl implements ItemCatService {
@Autowired
TbItemCatMapper itemcatMapper;
@Override
public ItemCatResult getItemCatList() {
ItemCatResult result = new ItemCatResult();
result.setData(getItemCatList(0l));//参数是bigint类型,对应Long
return result;
}
//方法的递归调用,根据是否是一级根节点(parent_id = 0)封装数据,最终返回一个list
//是否是叶子节点,也要判断一下,is_parent == true ?
public List getItemCatList(long parentID){
TbItemCatExample example = new TbItemCatExample();
Criteria criteria = example.createCriteria();
//根据父节点ID进行递归查询,从0开始
criteria.andParentIdEqualTo(parentID);
List list = itemcatMapper.selectByExample(example);
List resultList = new ArrayList<>();//这个是要返回的结果
int count = 0;//这里我们控制只显示14个商品分类,多的pass
//遍历list
for (TbItemCat item : list) {
if(count>=14){
break;
}
//1.如果当前的商品是根(父)节点的话
if(item.getIsParent()){
CatNode node = new CatNode();
//拼接商品URL
node.setUrl("/products/"+item.getId()+".html");
//如果当前节点的parent_id=0的话,说明它是一级根节点,一级节点封装如下
if(item.getParentId() ==0){
count++;//这里一级根节点++
node.setName(""+item.getName()+"");
}
else{//如果不等于0的说,证明此节点是二级节点,二级节点封装如下
//二级节点的话,直接拿到name字段
node.setName(item.getName());
}
//递归调用,把当前的id(主键)作为查询条件,去匹配其子节点
node.setItems(getItemCatList(item.getId()));//这里递归调用
//把node添加到列表
resultList.add(node);
}
else{//如果当前是叶子节点的话(is_parent == 0 false)
//拼接字符串,i == items,
/**
"i": [
"/products/66.html|艺术/设计/收藏" ,
"/products/67.html|经济管理" ,
"/products/68.html|文化/学术" ,
"/products/69.html|少儿文学/国学"
]
i
0 "/products/90.html|电风扇"
1 "/products/91.html|冷风扇"
2 "/products/92.html|净化器"
3 "/products/93.html|饮水机"
*/
String i = "/products/"+item.getId()+".html|"+item.getName();
resultList.add(i);//这个单独(另外加)
}
}
//遍历over后,返回最终的数据集
return resultList;
}
}
三、创建Controller,发布服务并测试
(1):直接返回一个result,不考虑callback回调参数方法名
ItemCatController.java
package com.taotao.rest.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.taotao.rest.pojo.ItemCatResult;
import com.taotao.rest.service.ItemCatService;
/**
* 商品分类查询 Controller
* Title: ItemCatController.java
* Description:
* Blog: http://blog.csdn.net/appleyk
* @author Appleyk
* @date 2017年11月6日 下午6:40:59
* @version 1.0
*/
@Controller
@RequestMapping("/item/cat")
public class ItemCatController {
@Autowired
private ItemCatService itemCatService;
//1.不考虑callback参数
@RequestMapping("/list")
@ResponseBody //没有callback参数,不用考虑JSONP调用
private ItemCatResult getItemCatList(){
ItemCatResult result = itemCatService.getItemCatList();
return result;
}
}
服务测试:http:localhost:8081/rest/item/cat/list?callback=func_name
(2):考虑请求的url中是否带有callback参数
A.利用JsonUtils工具类转化对象为JSON字符串,并返回
ItemCatController.java
package com.taotao.rest.controller;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.taotao.common.utils.JsonUtils;
import com.taotao.rest.pojo.ItemCatResult;
import com.taotao.rest.service.ItemCatService;
/**
* 商品分类查询 Controller
* Title: ItemCatController.java
* Description:
* Blog: http://blog.csdn.net/appleyk
* @author Appleyk
* @date 2017年11月6日 下午6:40:59
* @version 1.0
*/
@Controller
@RequestMapping("/item/cat")
public class ItemCatController {
@Autowired
private ItemCatService itemCatService;
//1.不考虑callback参数
// @RequestMapping("/list")
// @ResponseBody //没有callback参数,不用考虑JSONP调用
// private ItemCatResult getItemCatList(){
// ItemCatResult result = itemCatService.getItemCatList();
// return result;
// }
//2.直接返回String类型的json串,利用JsonUtils工具类转化对象为JSON字符串
@RequestMapping("/list")
@ResponseBody //有callback参数,考虑是否JSONP调用
private String getItemCatList(String callback){
ItemCatResult result = itemCatService.getItemCatList();
//如果这个callback等于空的话,直接返回json串
if(StringUtils.isBlank(callback)){
String json = JsonUtils.objectToJson(result);
return json;
}
//否则的话,拼接一下这个callback,返回一个回调js片段,里面包含json数据
//供js跨域调用----jsonp
String json = JsonUtils.objectToJson(result);
return callback+"("+json+");";
}
}
出现这种情况,需要指定一下响应数据的类型以及字符集的编码
无callback参数的服务请求:http://localhost:8081/rest/item/cat/list
有callback参数的服务请求:http://localhost:8081/rest/item/cat/list?callback=func_calltest
首:
尾:
B.使用MappingJacksonValue类
ItemCatController.java
package com.taotao.rest.controller;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.converter.json.MappingJacksonValue;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.taotao.rest.pojo.ItemCatResult;
import com.taotao.rest.service.ItemCatService;
/**
* 商品分类查询 Controller
* Title: ItemCatController.java
* Description:
* Blog: http://blog.csdn.net/appleyk
* @author Appleyk
* @date 2017年11月6日 下午6:40:59
* @version 1.0
*/
@Controller
@RequestMapping("/item/cat")
public class ItemCatController {
@Autowired
private ItemCatService itemCatService;
//1.不考虑callback参数
// @RequestMapping("/list")
// @ResponseBody //没有callback参数,不用考虑JSONP调用
// private ItemCatResult getItemCatList(){
// ItemCatResult result = itemCatService.getItemCatList();
// return result;
// }
//2.直接返回String类型的json串,利用JsonUtils工具类转化对象为JSON字符串
// @RequestMapping(value="/list",produces=MediaType.APPLICATION_JSON_VALUE+";charset=utf-8")
// @ResponseBody //有callback参数,考虑是否JSONP调用
// private String getItemCatList(String callback){
// ItemCatResult result = itemCatService.getItemCatList();
// //如果这个callback等于空的话,直接返回json串
// if(StringUtils.isBlank(callback)){
// String json = JsonUtils.objectToJson(result);
// return json;
// }
// //否则的话,拼接一下这个callback,返回一个回调js片段,里面包含json数据
// //供js跨域调用----jsonp
//
// String json = JsonUtils.objectToJson(result);
// return callback+"("+json+");";
// }
//3. 使用MappingJacksonValue类封装一个pojo,供js跨域调用----jsonp形式
@RequestMapping("/list")
@ResponseBody //有callback参数,考虑是否JSONP调用
private Object getItemCatList(String callback){
ItemCatResult result = itemCatService.getItemCatList();
//如果这个callback等于空的话,直接返回result,交给@ResponseBody注解处理成JSON对象
if(StringUtils.isBlank(callback)){
return result;
}
//支持jsonp调用,需要Spring版本4.1+
MappingJacksonValue mjkVal = new MappingJacksonValue(result);
mjkVal.setJsonpFunction(callback);
return mjkVal;
}
}
效果和第二种方式一样,这里放出一个无callback参数的服务调用,看一下,是否是只展示了14个商品分类节点
在Mysql数据库中查询一下,测试一下,数据节点是不是对号入座
查询语句:
use taotao;
SELECT @row_no:=@row_no+1 as row_id,name FROM tb_item_cat ,(select @row_no:=0) t
where parent_id = 0
四、门户模块potal,商城首页-->商品分类展示--->js跨域数据请求的实现
保存后,运行taotao-portal(端口:8082)
测试:http://localhost:8082/