1.   今日大纲

1、  学习Nginx的使用

2、  实现商品的管理

a)       新增商品

b)       查询商品列表

c)       编辑商品

d)       删除商品

e)       上架和下架商品


SwitchHosts!_win_x64_3.5.0(5486)

https://oldj.github.io/SwitchHosts/

使用SwitchHosts!修改本地hosts文件,实现ip地址和域名的解析。

Win10系统的hosts目录为:

C:\Windows\System32\drivers\etc

Linux下的hosts文件所在路径: /etc/hosts

# taotao2016 开发环境
127.0.0.1 www.taotao.com
127.0.0.1 manage.taotao.com
127.0.0.1 image.taotao.com

修改配置conf/nginx.conf

#user  nobody;
worker_processes ; #error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info; #pid logs/nginx.pid; events {
worker_connections ;
} http {
include mime.types;
default_type application/octet-stream; sendfile on; keepalive_timeout ; gzip on; server {
listen ;
server_name manage.taotao.com; #charset koi8-r; proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; location / {
proxy_pass http://127.0.0.1:8081;
proxy_connect_timeout ;
proxy_read_timeout ;
}
}
server {
listen ;
server_name image.taotao.com; #charset koi8-r; proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; location / {
root F:\\javaweb\\taotao-upload;
}
}
}

taotao2016.conf

使用nginx实现反向代理监听端口

Shift+鼠标右键启动Powershell
ls
F:\javaweb\nginx-1.16. #powershell启动和关闭nginx.exe服务 .\nginx -c conf\taotao2016.conf .\nginx -s stop .\nginx -s reload


Spring4.3.25版本集成使用通用Mapper,可以使用泛型注入的新特性。

package com.taotao.manage.service;

import java.util.Date;
import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.taotao.manage.pojo.BasePojo; import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.entity.Example; public abstract class BaseService<T extends BasePojo> {
/**
* 方法:
1、 queryById
2、 queryAll
3、 queryOne
4、 queryListByWhere
5、 queryPageListByWhere
6、 save
7、 update
8、 deleteById
9、 deleteByIds
10、 deleteByWhere
*/ // public abstract Mapper<T> getMapper();
// spring4.3.25支持泛型注入新特性
@Autowired
private Mapper<T> mapper; /**
* 根据id查询数据
* @param id
* @return
*/
public T queryById(Long id) {
return this.mapper.selectByPrimaryKey(id);
}
/**
* 查询所有数据
* @return
*/
public List<T> queryAll(){
return this.mapper.selectAll();
}
/**
* 根据条件查询一条数据
* 如果该条件所查询的数据为多条会抛出异常
* @param record
* @return
*/
public T queryOne(T record) {
return this.mapper.selectOne(record);
}
/**
* 根据条件查询多条数据
* @param record
* @return
*/
public List<T> queryListByWhere(T record){
return this.mapper.select(record);
}
/**
* 根据条件分页查询数据
* @param record
* @param pageNum
* @param pageSize
* @return
*/
public PageInfo<T> queryPageListByWhere(T record,Integer pageNum,Integer pageSize){
//设置分页参数
PageHelper.startPage(pageNum, pageSize);
List<T> list = this.mapper.select(record);
return new PageInfo<T>(list);
}
/**
* 新增数据,未设置的值为null
* @param t
* @return
*/
public Integer save(T t) { t.setCreated(new Date());
t.setUpdated(t.getCreated());
return this.mapper.insert(t);
}
/**
* 选择不为null的字段作为插入更新数据
* @param t
* @return
*/
public Integer saveSelective(T t) {
t.setCreated(new Date());
t.setUpdated(t.getCreated());
return this.mapper.insertSelective(t);
} /**
* 更新数据,未设置的字段值为null
* @param t
* @return
*/
public Integer update(T id) {
id.setUpdated(new Date());
return this.mapper.updateByPrimaryKey(id);
}
/**
* 更新不为null的字段作为更新的字段
* @param t
* @return
*/
public Integer updateSelective(T id) {
id.setUpdated(new Date());
id.setCreated(null); //强制设置创建时间为null,永远不会被更新
return this.mapper.updateByPrimaryKeySelective(id);
} /**
* 根据主键id删除数据(物理删除)
* @param id
* @return
*/
public Integer deleteById(Long id) {
return this.mapper.deleteByPrimaryKey(id);
}
/**
* 根据主键ids批量删除数据(物理删除)
* @param ids
* @param clazz
* @param property
* @return
*/
public Integer deleteByIds(List<Object> ids ,Class<T> clazz,String property) {
Example example = new Example(clazz);
//设置条件,andIn(数据库字段,12345)
example.createCriteria().andIn(property, ids);
return this.mapper.deleteByExample(example);
}
/**
* 根据条件删除数据
* @param record
* @return
*/
public Integer deleteByWhere(T record) {
return this.mapper.delete(record);
}
}

public abstract class BaseService

mysql数据库的bigint类型对应JAVA中的Long

item-add.jps的第115行修改restful风格的ajax请求:

        //提交到后台的RESTful
$.ajax({
type: "POST",
url: "/rest/item",
data: $("#itemAddForm").serialize(),
statusCode: {
201: function() {
$.messager.alert('提示','新增商品成功!');
},
400: function() {
$.messager.alert('提示','提交的参数不合法!');
},
500: function() {
$.messager.alert('提示','新增商品失败!');
}
}
});

通过日志查看操作Item表和ItemDesc表,由于在Service层的:同一个类、同一个方法,并且已经配置好了spring的AOP管理事务。

信息: Starting ProtocolHandler ["http-bio-8081"]
-- ::, [http-bio--exec-] [com.alibaba.druid.pool.DruidDataSource]-[INFO] {dataSource-} inited
-- ::, [http-bio--exec-] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Creating a new SqlSession
-- ::, [http-bio--exec-] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4be7a5c4]
-- ::, [http-bio--exec-] [org.mybatis.spring.transaction.SpringManagedTransaction]-[DEBUG] JDBC Connection [com.mysql.jdbc.JDBC4Connection@1e0b3b6e] will be managed by Spring
-- ::, [http-bio--exec-] [com.taotao.manage.mapper.ItemMapper.insert]-[DEBUG] ==> Preparing: INSERT INTO tb_item ( created,updated,id,title,sell_point,price,num,barcode,image,cid,status ) VALUES( ?,?,?,?,?,?,?,?,?,?,? )
-- ::, [http-bio--exec-] [com.taotao.manage.mapper.ItemMapper.insert]-[DEBUG] ==> Parameters: -- ::59.17(Timestamp), -- ::59.17(Timestamp), null, Z7(String), 970M(String), (Long), (Integer), (String), (String), (Long), (Integer)
-- ::, [http-bio--exec-] [com.taotao.manage.mapper.ItemMapper.insert]-[DEBUG] <== Updates:
-- ::, [http-bio--exec-] [com.taotao.manage.mapper.ItemMapper.insert!selectKey]-[DEBUG] ==> Executing: SELECT LAST_INSERT_ID()
-- ::, [http-bio--exec-] [com.taotao.manage.mapper.ItemMapper.insert!selectKey]-[DEBUG] <== Total:
-- ::, [http-bio--exec-] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4be7a5c4]
-- ::, [http-bio--exec-] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4be7a5c4] from current transaction
-- ::, [http-bio--exec-] [com.taotao.manage.mapper.ItemDescMapper.insert]-[DEBUG] ==> Preparing: INSERT INTO tb_item_desc ( created,updated,item_id,item_desc ) VALUES( ?,?,?,? )
-- ::, [http-bio--exec-] [com.taotao.manage.mapper.ItemDescMapper.insert]-[DEBUG] ==> Parameters: -- ::59.332(Timestamp), -- ::59.332(Timestamp), (Long), qq(String)
-- ::, [http-bio--exec-] [com.taotao.manage.mapper.ItemDescMapper.insert]-[DEBUG] <== Updates:
-- ::, [http-bio--exec-] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4be7a5c4]
-- ::, [http-bio--exec-] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4be7a5c4]
-- ::, [http-bio--exec-] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4be7a5c4]
-- ::, [http-bio--exec-] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4be7a5c4]

5.2.  上传组件的JS实现的上传参数

5.3.实现springMVC图片上传

1.导入 commons-fileupload 的依赖坐标

        <!-- 文件上传组件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>

2.配置文件上传解析器在springmvc.xml

    <!-- 定义文件上传解析器 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设定默认编码 -->
<property name="defaultEncoding" value="UTF-8"></property>
<!-- 设定文件上传的最大值5MB,5*1024*1024 -->
<property name="maxUploadSize" value="5242880"></property>
</bean>

3.PicUploadController使用了配置文件中的路径,读取配置文件用Service层spring父容器的一个“读取配置文件的类” 的 public关键字修饰的成员属性

package com.taotao.manage.controller;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Date; import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile; import com.fasterxml.jackson.databind.ObjectMapper;
import com.taotao.common.bean.PicUploadResult;
import com.taotao.manage.service.PropertieService; /**
* 图片上传
*/
@Controller
@RequestMapping("/pic")
public class PicUploadController { //创建日志对象
private static final Logger LOGGER = LoggerFactory.getLogger(PicUploadController.class); @Autowired
private PropertieService propertieService; private static final ObjectMapper mapper = new ObjectMapper(); // 允许上传的格式
private static final String[] IMAGE_TYPE = new String[] { ".bmp", ".jpg", ".jpeg", ".gif", ".png" }; @PostMapping(value = "/upload", produces = MediaType.TEXT_PLAIN_VALUE)
@ResponseBody
public String upload(@RequestParam("uploadFile") MultipartFile uploadFile , HttpServletResponse response) throws Exception { // 校验图片格式
boolean isLegal = false;
for (String type : IMAGE_TYPE) {
//忽略大小写比较字符串的末尾
if (StringUtils.endsWithIgnoreCase(uploadFile.getOriginalFilename(), type)) {
isLegal = true;
break;
}
} // 封装Result对象,并且将文件的byte数组放置到result对象中
PicUploadResult fileUploadResult = new PicUploadResult(); // 状态
fileUploadResult.setError(isLegal ? 0 : 1); // 文件新路径
String filePath = getFilePath(uploadFile.getOriginalFilename()); if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Pic file upload .[{}] to [{}] .", uploadFile.getOriginalFilename(), filePath);
} // 生成图片的绝对引用地址
String picUrl = StringUtils.replace(StringUtils.substringAfter(filePath, propertieService.REPOSITORY_PATH), "\\", "/");
fileUploadResult.setUrl(propertieService.IMAGE_BASE_URL + picUrl); File newFile = new File(filePath); // 写文件到磁盘
uploadFile.transferTo(newFile); // 校验图片是否合法
isLegal = false;
try {
BufferedImage image = ImageIO.read(newFile);
if (image != null) {
fileUploadResult.setWidth(image.getWidth() + "");
fileUploadResult.setHeight(image.getHeight() + "");
isLegal = true;
}
} catch (IOException e) {
} // 状态
fileUploadResult.setError(isLegal ? 0 : 1); if (!isLegal) {
// 不合法,将磁盘上的文件删除
newFile.delete();
} response.setContentType(MediaType.TEXT_HTML_VALUE);
//将java对象序列化成json数据
return mapper.writeValueAsString(fileUploadResult);
} private String getFilePath(String sourceFileName) {
String baseFolder = propertieService.REPOSITORY_PATH + File.separator + "images";
Date nowDate = new Date();
// yyyy/MM/dd
String fileFolder = baseFolder + File.separator + new DateTime(nowDate).toString("yyyy") + File.separator + new DateTime(nowDate).toString("MM") + File.separator
+ new DateTime(nowDate).toString("dd");
File file = new File(fileFolder);
if (!file.isDirectory()) {
// 如果目录不存在,则创建目录
file.mkdirs();
}
// 生成新的文件名
String fileName = new DateTime(nowDate).toString("yyyyMMddhhmmssSSSS") + RandomUtils.nextInt(100, 9999) + "." + StringUtils.substringAfterLast(sourceFileName, ".");
return fileFolder + File.separator + fileName;
} }

Spring容器  --  父容器

SpringMVC容器  -- 子容器

父子容器的关系:

1、  子容器能够访问父容器的资源(bean)

a)       示例:Controller可以注入Service

2、  父容器不能访问子容器的资源(bean)

package com.taotao.manage.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; @Service
public class PropertieService {
// 加载spring父容器中配置文件内容
@Value("${REPOSITORY_PATH}")
public String REPOSITORY_PATH; @Value("${IMAGE_BASE_URL}")
public String IMAGE_BASE_URL;
}

对文件做校验:

1、 类型,通过文件的后缀名

2、 大小

3、 上传文件的内容做校验

 a)   通过获取文件的宽和高来判断是否是图片

7.   日志的书写

总结:

1、  方法的入参处需要将参数打印出

2、  业务执行的状态发生变化时,需要打印

3、  异常处需要打印


6.   查询商品列表

EasyUI的datagrid的格式化输出。

默认情况下,会直接显示返回的数据,但是有些情况下不能直接显示,如:价格、日期、性别,需要指定formatter函数。

@Service
public class ItemListService extends BaseService<Item> { @Autowired
ItemMapper itemMapper; //根据商品更新时间降序排序
public EasyUIResult queryItemList(Integer page, Integer rows) {
//第三个参数:是否count查询
PageHelper.startPage(page, rows, true); //设置查询条件
Example example = new Example(Item.class);
example.setOrderByClause("updated DESC");
List<Item> list = itemMapper.selectByExample(example); PageInfo<Item> pageInfo = new PageInfo<>(list);
// 返回给视图层一个包装好的EasyUIResult对象
return new EasyUIResult(pageInfo.getTotal(), pageInfo.getList());
} }

=====================================

end

ZZJ_淘淘商城项目:day03(淘淘商城02 - 后台系统功能实现)的更多相关文章

  1. 【SSH网上商城项目实战14】商城首页UI的设计

    转自:https://blog.csdn.net/eson_15/article/details/51373403 前面我们利用EasyUI和SSH搭建好了后台的基本框架,做好了后台的基本功能,包括对 ...

  2. ZZJ_淘淘商城项目:day01(RESTful Web Service、SVN)

    淘淘商城项目是很适合初级Java程序员练习的实战项目,本次复习是另一位张老师教授的课,内容上与之前入老师版taotao商城比较有些新东西加了进来. 因此有必要记录下那些直到现在还可供参考的技术亮点分享 ...

  3. day68_淘淘商城项目_01

    原文:day68_淘淘商城项目_01 课程计划 第一天: 1.电商行业的背景介绍--电子商务 2.淘淘商城的系统架构 a) 功能介绍 b) 架构讲解 3.工程搭建--后台工程 a) 使用maven搭建 ...

  4. day68_淘淘商城项目_01_电商介绍 + 互联网术语 + SOA + 分布式 + 集群介绍 + 环境配置 + 框架搭建_匠心笔记

    课程计划 第一天: 1.电商行业的背景介绍--电子商务 2.淘淘商城的系统架构 a) 功能介绍 b) 架构讲解 3.工程搭建--后台工程 a) 使用maven搭建工程(工程大) b) 使用maven的 ...

  5. 洗礼灵魂,修炼python(82)--全栈项目实战篇(10)—— 信用卡+商城项目(模拟京东淘宝)

    本次项目相当于对python基础做总结,常用语法,数组类型,函数,文本操作等等 本项目在博客园里其他开发者也做过,我是稍作修改来的,大体没变的 项目需求: 信用卡+商城: A.信用卡(类似白条/花呗) ...

  6. 后盾网lavarel视频项目---5、淘宝镜像cnpm的原理及如何使用

    后盾网lavarel视频项目---5.淘宝镜像cnpm的原理及如何使用 一.总结 一句话总结: 原理:把npm上面的所有软件copy过来 使用:npm install -g cnpm --regist ...

  7. 商城项目实战 | 1.1 Android 仿京东商城底部布局的选择效果 —— Selector 选择器的实现

    前言 本文为菜鸟窝作者刘婷的连载."商城项目实战"系列来聊聊仿"京东淘宝的购物商城"如何实现. 京东商城的底部布局的选择效果看上去很复杂,其实很简单,这主要是要 ...

  8. 商城项目实战 | 2.1 Android 仿京东商城——自定义 Toolbar (一)

    前言 本文为菜鸟窝作者刘婷的连载."商城项目实战"系列来聊聊仿"京东淘宝的购物商城"如何实现. 现在很多的 APP 里面都有自己的自定义风格,特别是京东商城中自 ...

  9. 商城项目实战 | 2.2 Android 仿京东商城——自定义 Toolbar (二)

    本文为菜鸟窝作者刘婷的连载."商城项目实战"系列来聊聊仿"京东淘宝的购物商城"如何实现. 上一篇文章<商城项目实战 | 2.1 Android 仿京东商城 ...

随机推荐

  1. 【LeetCode】子集

    [问题]给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集).说明:解集不能包含重复的子集. 示例: 输入: nums = [,,] 输出: [ [], [], [], [,,] ...

  2. python字符串常用函数

    # 索引与切片  *** capitalize()  **首字母大写 upper() lower() *** 大写和小写函数 startswith endswith  ***    判断以‘’字母’开 ...

  3. VS 2017 没有工具栏中没有Report Viewer的解决方案

    安装 控件 Install-Package Microsoft.ReportingServices.ReportViewerControl.WinForms -Pre “工具”>“Nuget包管 ...

  4. Java8 Optional类使用小结

    Optional类的Javadoc描述如下: 这是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. of:  为非null的值创建一 ...

  5. SpringBoot学习(四)——配置文件占位符

    RandomValuePropertySource:配置文件中可以使用随机数 ${Random.value}  ${random.int}, ${random.long}, ${random.int( ...

  6. 生成私钥、公钥,配置到Git上

    ssh-keygen -t rsa -C "1032671220@qq.com" 输入完毕指令,输入密码.然后会在 /z/.ssh/文件夹下生成一个私钥rsa_id.公钥rsa_p ...

  7. (递归)Hanoi Tower

    #include<stdio.h>void move(int n,char a,char b){ printf("将第%d个盘子从%c移动到%c\n",n,a,b);  ...

  8. SpringCloud学习之手把手教你用IDEA搭建入门项目【番外篇】(一)

    之前的文章里,我曾经搭建了一个Springcloud项目,但是那个时候我对于SpringCloud架构的很多组件不甚清楚,只是通过查找资料然后动手稀里糊涂的把一个项目成功搭建起来了,其中有很多不合理和 ...

  9. C++多态性与虚函数

    派生一个类的原因并非总是为了继承或是添加新的成员,有时是为了重新定义基类的成员,使得基类成员“获得新生”.面向对象的程序设计真正的力量不仅仅是继承,而且还在于允许派生类对象像基类对象一样处理,其核心机 ...

  10. python进阶(三)~~~装饰器和闭包

    一.闭包 满足条件: 1. 函数内嵌套一个函数: 2.外层函数的返回值是内层函数的函数名: 3.内层嵌套函数对外部作用域有一个非全局变量的引用: def func(): print("=== ...