4.前端框架搭建
[taotao]-前端框架搭建
1.前台系统搭建
【1】系统架构分析
前台系统可以查询商品信息(PC端、移动端)、下单,通过将公共的业务逻辑提取出来,以发布服务的形式供pc、移动端调用
优点
1.提高代码复用度
2.可以灵活的进行分布式部署
3.系统之间耦合度低
4.团队之间开发不冲突
缺点
1.需要发布Webservice,系统之间需要远程调用
2.工作量增加
3.需要系统之间协作才能完成整个业务流程,系统之间调用变的复杂
系统构成
服务层:taotao-rest:没有表现层,只有业务逻辑(需要发布服务)
表现层:taotao-portal:只有表现层,没有业务逻辑,不需要连接数据库。
表现层和服务层通信,使用Webservice进行通信。Restful形式的Webservice。http+json数据
【2】工程创建
taotao-rest服务层
(1)基本概念
项目属性
使用maven管理工程:War包
使用技术
Mybatis
Spring
发布服务:cxf、springmvc
(2)工程创建
步骤1:工程初始化
步骤2:整合ssm框架(可以参考taotao-manager工程)
Spring默认配置了视图解析器,如果springmvc.xml中没有配置,默认也可以使用jsp
在对应springmvc的依赖jar中查看相关的信息:org\springframework\spring-webmvc\4.1.3.RELEASE\spring-webmvc-4.1.3.RELEASE.jar-->org.springframework.web.servlet包下有DispatcherServlet.properties,默认配置了视图解析器
- Web.xml文件复制:修改两个内容--项目名称、拦截路径、控制器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="taotao" version="2.5">
<display-name>taotao-rest</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 加载spring容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 解决post乱码 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- springmvc的前端控制器 -->
<servlet>
<servlet-name>taotao-rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- contextConfigLocation不是必须的, 如果不配置contextConfigLocation, springmvc的配置文件默认在:WEB-INF/servlet的name+"-servlet.xml" -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
<!-- load-on-startup元素标记容器是否应该在web应用程序启动的时候就加载这个servlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 配置拦截url的请求:/表示拦截所有的请求(包括静态资源) -->
<servlet-mapping>
<servlet-name>taotao-rest</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
步骤3:配置pom文件
添加对taotao-manager-dao的依赖、添加spring的依赖、配置tomcat插件
<project xmlns="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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.taotao</groupId>
<artifactId>taotao-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.taotao</groupId>
<artifactId>taotao-rest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.taotao</groupId>
<artifactId>taotao-manager-mapper</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- Redis客户端 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!-- solr客户端 -->
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
</dependency>
</dependencies>
<!-- 添加tomcat插件 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<port>8081</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
taotao-portal表现层
(1)基本概念
使用技术
Spring
Springmvc
(2)工程创建
步骤1:初始化工程
步骤2:pom.xml配置
引入taotao-manager-pojo、Spring相关依赖、配置Tomcat插件
<project xmlns="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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.taotao</groupId>
<artifactId>taotao-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.taotao</groupId>
<artifactId>taotao-portal</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.taotao</groupId>
<artifactId>taotao-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.taotao</groupId>
<artifactId>taotao-manager-pojo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<!-- JSP相关 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- 添加tomcat插件 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<port>8082</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
步骤3:配置web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="taotao" version="2.5">
<display-name>taotao-portal</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 加载spring容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 解决post乱码 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- springmvc的前端控制器 -->
<servlet>
<servlet-name>taotao-portal</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- contextConfigLocation不是必须的, 如果不配置contextConfigLocation, springmvc的配置文件默认在:WEB-INF/servlet的name+"-servlet.xml" -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
<!-- load-on-startup元素标记容器是否应该在web应用程序启动的时候就加载这个servlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 配置拦截url的请求:/表示拦截所有的请求(包括静态资源) -->
<servlet-mapping>
<servlet-name>taotao-portal</servlet-name>
<!-- 伪静态化 -->
<url-pattern>*.html</url-pattern>
</servlet-mapping>
</web-app>
步骤4:框架整合
运行过程中可能会报错,要先将相应的工程导入仓库(taotao-manager-pojo、taotao-manager),Maven安装工程到本地仓库,跳过测试:mvn clean install -DskipTests
【3】首页访问
将相关的静态文件导入到相应的webapp文件夹下
创建一个Controller,当访问http://localhost:8082/跳转到首页;请求的url:/index
@Controller
public class IndexController {
@RequestMapping("/index")
public String showIndex() {
return "index";
}
}
启动tomcat测试:clean tomcat7:run,请求路径:http://localhost:8082/index.html、http://localhost:8082/
http://localhost:8082/index无法访问(拦截器)
2.首页商品类目展示
【1】基本概念
需求分析
类目展示需要异步加载
商品类目从数据库中获得,调用taotao-rest发布的服务获得数据
可以在首页中使用js直接调用taotao-rest发布的服务获得数据
json数据格式
在webapp下创建category.json,复制相关内容,可通过json编辑器或者浏览器发布访问到该文件数据
js请求过程分析
请求数据的js位置:index.jsp-->header.jsp-->lib-vl.js
将category.json放到taotao-rest的webapp文件夹下,重启taotao-rest服务器访问localhost:8081/category.json
数据可以正常访问,此时修改lib-vl.js的内容让其实现由taotao-portal访问taotao-rest的category.json进行测试,会出现js跨域问题
⚡JS跨域问题
❓什么是跨域?
Js为了安全有一个限制,不允许跨域访问。
如果两个url的域名不同
url相同,端口不同也是跨域
ip不同也是跨域
因此在taotao-portal中不能使用ajax直接调用taotao-rest的服务(两个服务发布端口不同)
跨域问题解决(参考:使用jsonp解决跨域)
在js中不能跨域请求数据,js可以跨域请求js片段
可以把数据包装成js片段。可以把数据使用js方法来包装,形成一条方法的调用语句
可以使用ajax请求js片段,当js判断到达浏览器会被立即执行
在浏览器端,先创建好回调方法,在回调方法中通过参数可以获得请求的数据
参考实现
3.发布商品列表查询服务
【1】功能实现
基本概念
首页的商品列表查询功能需要调用taotao-rest提供的接口,因此在测试的时候需要先将taotao-rest服务启动,随后再将taotao-portal启动进行测试
商品列表数据是一个分类列表数据,从tb_item_cat数据表中取数据,可以在taotao-rest(com.taotao.rest.pojo)中创建一个pojo(CatNode)用于描述树形列表节点,对应内容如下
package com.taotao.rest.pojo;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
public class CatNode {
@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;
}
}
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;
}
}
dao层
从tb_item_cat表中取数据,单表查询,可以使用逆向工程生成的代码
service层
返回结果:ItemCatResult
参数:没有
业务逻辑:根据parentid查询子节点列表,并递归调用
public interface ItemCatService {
// 获取分类列表
public ItemCatResult getItemCatList();
}
@Service
public class ItemCatServiceImpl implements ItemCatService {
@Autowired
private TbItemCatMapper itemCatMapper;
@Override
public ItemCatResult getItemCatList() {
//调用递归方法查询商品分类列表
List catList = getItemCatList(0l);
//返回结果
ItemCatResult result = new ItemCatResult();
result.setData(catList);
return result;
}
private List getItemCatList(Long parentId) {
//根据parentId查询列表
TbItemCatExample example = new TbItemCatExample();
Criteria criteria = example.createCriteria();
criteria.andParentIdEqualTo(parentId);
//执行查询
List<TbItemCat> list = itemCatMapper.selectByExample(example);
List resultList = new ArrayList<>();
for (TbItemCat tbItemCat : list) {
//如果是父节点
if (tbItemCat.getIsParent()) {
CatNode node = new CatNode();
node.setUrl("/products/"+tbItemCat.getId()+".html");
//如果当前节点为第一级节点
if (tbItemCat.getParentId() == 0) {
node.setName("<a href='/products/"+tbItemCat.getId()+".html'>"+tbItemCat.getName()+"</a>");
} else {
node.setName(tbItemCat.getName());
}
node.setItems(getItemCatList(tbItemCat.getId()));
//把node添加到列表
resultList.add(node);
} else {
//如果是叶子节点
String item = "/products/"+tbItemCat.getId()+".html|" + tbItemCat.getName();
resultList.add(item);
}
}
return resultList;
}
}
controller层
响应一个json数据。判断callback参数是否为空,如果为空正常返回json数据,如果不为空,支持jsonp调用。
@Controller
@RequestMapping("/item/cat")
public class ItemCatController {
@Autowired
private ItemCatService itemCatService;
@RequestMapping(value="/list")
@ResponseBody
public ItemCatResult testGetItemCatList() {
return itemCatService.getItemCatList();
}
}
访问测试:http://localhost:8081/rest/item/cat/list
portal层中js处理
可进一步限制节点个数,不然会默认将所有的分类节点查找出来:在taotao-rest服务端进行处理
【2】扩展内容
支持jsonp的两种方式
(1)方式1:直接响应字符串(注意乱码问题处理)
@RequestMapping(value="/list",produces=MediaType.APPLICATION_JSON_VALUE+";charset=utf-8")
@ResponseBody
public String getItemCatList(String callback) {
ItemCatResult result = itemCatService.getItemCatList();
if (StringUtils.isBlank(callback)) {
//需要把result转换成字符串
String json = JsonUtils.objectToJson(result);
return json;
}
//如果字符串不为空,需要支持jsonp调用
//需要把result转换成字符串
String json = JsonUtils.objectToJson(result);
return callback + "(" + json + ");";
}
(2)方式2:MappingJacksonValue(要求springmvc必须是4.1以上的版本)
@RequestMapping(value="/list")
@ResponseBody
public Object getItemCatList(String callback) {
ItemCatResult result = itemCatService.getItemCatList();
if (StringUtils.isBlank(callback)) {
//需要把result转换成字符串
return result;
}
//如果字符串不为空,需要支持jsonp调用
MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(result);
mappingJacksonValue.setJsonpFunction(callback);
return mappingJacksonValue;
}
访问测试:
http://localhost:8081/rest/item/cat/list?callback=function1
http://localhost:8081/rest/item/cat/list?callback=functionn