淘淘商城_day02_課堂筆記


  1. 今日大綱

  1. 學習Nginx的使用
  2. 實現商品的管理
    1. 新增商品
    2. 查詢商品列表
    3. 編輯商品
    4. 刪除商品
    5. 上架和下架商品
    1. 學習nginx

      1. 開發階段中的環境

開發環境:自己的電腦

測試環境:提供給測試人員使用的環境

生產環境:項目最終發布上線的環境

 

預發布環境:數據是和生成環境的數據一致,運行最新的項目代碼進去測試

 

每個環境的訪問地址是不同的,可能因為訪問地址不同導致一些問題的產生,所以,為了避免該類問題的產生,可以使不同的環境訪問地址完全一致,通過域名訪問即可實現。

  1. 需求:需要通過域名訪問后台系統?

現在:http://127.0.0.1/rest/page/index

 

需要通過manage.taoao.com訪問。

 

http://manage.taotao.com /rest/page/index

 

  1. Hosts

用戶訪問淘寶:

 

用戶 è www.taobao.com è 本機的hosts文件中查找域名映射,如果查找到就返回 è瀏覽器通過域名到DNS查找服務器ip地址 è 執行訪問

 

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

  1. 實現

  1. 修改本地的hosts,將manage.taotao.com映射到127.0.0.1

 

效果:

 

 

 

但是,如果后台系統占用80端口,其他系統就無法占用80,也就是無法通過域名直接訪問,必須通過域名:端口訪問http://www.taotao.com:8081/

問題是:導致,生產環境和開發環境的訪問路徑是不同的。

 

如何解決以上問題? -- 通過nginx來解決。

 

  1. 修改后台管理系統的端口為8081

 

 

  1. Nginx簡介

目前電商和互聯網系統都會采用nginx + 應用服務器(tomcat).

 

Web服務器分2類:

  1. web服務器
    1. Apache 服務器
    2. Nginx
    3. IIS
  2. web應用服務器
    1. tomcat
    2. resin
    3. jetty

 

區分:web服務器不能解析jsp等頁面,只能處理js、css、html等靜態資源。

並發:web服務器的並發能力遠高於web應用服務器。

 

 

淘寶:

 

京東:(也是nginx,將服務名稱改為JDWS)

 

  1. 簡介

 

Nginx是使用C語言開發。

  1. 使用

解壓得到:

 

三個命令:(在 CMD 中執行)

啟動:start nginx.exe

停止:nginx.exe -s stop

重新加載:nginx.exe -s reload

 

 

只有2個進程nginx才算是真正的啟動成功:

 

  1. Nginx的配置

 

 

  1. 測試

 

現在的請求:

 

用戶 è Nginx è tomcat

  1. 啟動nginx的注意事項

  1. 其他服務占用80端口,會導致nginx啟動失敗,檢查的方法是 cmd è nginx.exe
  2. Nginx的路徑不能包含中文
    1. 代理

      1. 正向代理

用戶 è 代理 è google

 

  1. 反向代理

用戶 è nginx è tomcat

 

解釋:

Tomcat根本不知道請求的來源,只知道所有的請求都是來源於Nginx,不知道真正的來源。

  1. 封裝BaseService

方法:

  1. queryById
  2. queryAll
  3. queryOne
  4. queryListByWhere
  5. queryPageListByWhere
  6. save
  7. update
  8. deleteById
  9. deleteByIds
  10. deleteByWhere

 

  1. 實現

package com.taotao.manage.service;

 

import java.util.Date;

import java.util.List;

 

import com.github.abel533.entity.Example;

import com.github.abel533.mapper.Mapper;

import com.github.pagehelper.PageHelper;

import com.github.pagehelper.PageInfo;

import com.taotao.manage.pojo.BasePojo;

 

public abstract class BaseService<T extends BasePojo> {

 

public abstract Mapper<T> getMapper();

 

/**

* 根據id查詢數據

*

* @param id

* @return

*/

public T queryById(Long id) {

return getMapper().selectByPrimaryKey(id);

}

 

/**

* 查詢所有數據

*

* @return

*/

public List<T> queryAll() {

return this.getMapper().select(null);

}

 

/**

* 根據條件查詢一條數據

*

* @param record

* @return

*/

public T queryOne(T record) {

return this.getMapper().selectOne(record);

}

 

/**

* 根據條件查詢數據列表

*

* @param record

* @return

*/

public List<T> queryListByWhere(T record) {

return this.getMapper().select(record);

}

 

/**

* 根據條件分頁查詢數據列表

*

* @param record

* @param page

* @param rows

* @return

*/

public PageInfo<T> queryPageListByWhere(T record, Integer page, Integer rows) {

// 設置分頁條件

PageHelper.startPage(page, rows);

 

List<T> list = this.getMapper().select(record);

 

// 獲取分頁數據

return new PageInfo<T>(list);

}

 

/**

* 保存數據

*

* @param record

* @return

*/

public Integer save(T record) {

record.setCreated(new Date());

record.setUpdated(record.getCreated());

return this.getMapper().insert(record);

}

 

/**

* 有選擇性的保存數據(選擇不為null的字段做保存)

*

* @param record

* @return

*/

public Integer saveSelective(T record) {

record.setCreated(new Date());

record.setUpdated(record.getCreated());

return this.getMapper().insertSelective(record);

}

 

/**

* 更新數據

*

* @param record

* @return

*/

public Integer update(T record) {

record.setUpdated(new Date());

return this.getMapper().updateByPrimaryKey(record);

}

 

/**

* 有選擇性的更新數據(選擇不為null的字段做更新)

*

* @param record

* @return

*/

public Integer updateSelective(T record) {

record.setCreated(null);

record.setUpdated(new Date());

return this.getMapper().updateByPrimaryKeySelective(record);

}

 

public Integer deleteById(Long id) {

return this.getMapper().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);

example.createCriteria().andIn(property, ids);

return this.getMapper().deleteByExample(example);

}

 

/**

* 根據條件刪除數據

*

* @param record

* @return

*/

public Integer deleteByWhere(T record){

return this.getMapper().delete(record);

}

}

 

  1. 使用BaseService改造ItemCatService

 

在Controller:

  1. 測試

測試結果:和原來的實現完全一致。

  1. Spring4的泛型注入

  1. BaseService的優化

 

測試:運行時注入具體的通用Mapper的子接口的實現類:

 

  1. 問題

ItemCatMapper在編碼時沒有使用到,是否將其刪除? -- 不能。

 

原因:在Spring運行時會使用該對象,將其注入到BaseService中。

 

  1. 新增商品

    1. 商品數據結構

需求文檔:

 

 

表結構:

 

問題1:為什么價格要以最小單位分存儲? -- 為了避免小數計算帶來的問題。

 

 

商品描述表:

 

問題2:為什么要將商品描述和商品的基本數據分離?

  1. 商品描述的數據量大,會導致數據文件變大,影響查詢速度。
  2. 后期會對商品描述數據的存儲做改造,所以需要將描述數據分離
    1. 點擊商品類目的葉子節點的事件

 

在item-add.jsp中定義:

  1. 新增頁面中價格

  1. KindEditor的使用

效果:

 

  1. 導入js文件
  2. 定義多行文本
  3. 通過JS創建出富文本編輯器

    Common.js:

    1. 提交事件

    function submitForm(){

        if(!$('#itemAddForm').form('validate')){

            $.messager.alert('提示','表單還未填寫完成!');

            return ;

        }

        //處理商品的價格的單位,將元轉化為分

        $("#itemAddForm [name=price]").val(eval($("#itemAddForm [name=priceView]").val()) * 100);

        //將編輯器中的內容同步到隱藏多行文本中

        itemAddEditor.sync();

        

        //輸入的規格參數數據保存為json

        var paramJson = [];

        $("#itemAddForm .params li").each(function(i,e){

            var trs = $(e).find("tr");

            var group = trs.eq(0).text();

            var ps = [];

            for(var i = 1;i<trs.length;i++){

                var tr = trs.eq(i);

                ps.push({

                    "k" : $.trim(tr.find("td").eq(0).find("span").text()),

                    "v" : $.trim(tr.find("input").val())

                });

            }

            paramJson.push({

                "group" : group,

                "params": ps

            });

        });

        paramJson = JSON.stringify(paramJson);

        

        $("#itemAddForm [name=itemParams]").val(paramJson);

        

        /*

        $.post("/rest/item/save",$("#itemAddForm").serialize(), function(data){

            if(data.status == 200){

                $.messager.alert('提示','新增商品成功!');

            }

        });

        */

        

        //提交到后台的RESTful

        $.ajax({

         type: "POST",

         url: "/rest/item",

         data: $("#itemAddForm").serialize(), //表單序列化,將所有的輸入內容轉化成K/V數據格式

         statusCode : {

             201 : function(){

                 $.messager.alert('提示','新增商品成功!');

             },

                400 : function(){

                 $.messager.alert('提示','提交的參數不合法!');

             },

             500 : function(){

                 $.messager.alert('提示','新增商品失敗!');

             }

         }

        });

    }

  1. 商品描述表中業務id

  1. 實現

    1. Controller

 

效果

數據:

 

 

描述數據:

  1. 事務問題

 

解決:

將2次保存放到同一個Service的同一個方法中即可:

 

Controller:

 

 

日志:

2016-12-02 15:26:39,723 [http-bio-8081-exec-1] [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] DispatcherServlet with name 'taotao-manage' processing POST request for [/rest/item]

2016-12-02 15:26:39,725 [http-bio-8081-exec-1] [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping]-[DEBUG] Looking up handler method for path /item

2016-12-02 15:26:39,727 [http-bio-8081-exec-1] [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping]-[DEBUG] Returning handler method [public org.springframework.http.ResponseEntity<java.lang.Void> com.taotao.manage.controller.ItemController.saveItem(com.taotao.manage.pojo.Item,java.lang.String)]

2016-12-02 15:26:39,727 [http-bio-8081-exec-1] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'itemController'

2016-12-02 15:26:39,797 [http-bio-8081-exec-1] [org.springframework.jdbc.datasource.DataSourceTransactionManager]-[DEBUG] Creating new transaction with name [com.taotao.manage.service.ItemService.saveItem]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT

2016-12-02 15:26:39,819 [http-bio-8081-exec-1] [com.jolbox.bonecp.BoneCPDataSource]-[DEBUG] JDBC URL = jdbc:mysql://127.0.0.1:3306/taotao?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true, Username = root, partitions = 1, max (per partition) = 100, min (per partition) = 5, idle max age = 30 min, idle test period = 60 min, strategy = DEFAULT

2016-12-02 15:26:40,113 [http-bio-8081-exec-1] [org.springframework.jdbc.datasource.DataSourceTransactionManager]-[DEBUG] Acquired Connection [ConnectionHandle{url=jdbc:mysql://127.0.0.1:3306/taotao?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true, user=root, debugHandle=null, lastResetAgoInSec=0, lastUsedAgoInSec=0, creationTimeAgoInSec=0}] for JDBC transaction

2016-12-02 15:26:40,117 [http-bio-8081-exec-1] [org.springframework.jdbc.datasource.DataSourceTransactionManager]-[DEBUG] Switching JDBC Connection [ConnectionHandle{url=jdbc:mysql://127.0.0.1:3306/taotao?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true, user=root, debugHandle=null, lastResetAgoInSec=0, lastUsedAgoInSec=0, creationTimeAgoInSec=0}] to manual commit

2016-12-02 15:26:40,154 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Creating a new SqlSession

2016-12-02 15:26:40,175 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@77c39180]

2016-12-02 15:26:40,281 [http-bio-8081-exec-1] [org.mybatis.spring.transaction.SpringManagedTransaction]-[DEBUG] JDBC Connection [ConnectionHandle{url=jdbc:mysql://127.0.0.1:3306/taotao?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true, user=root, debugHandle=null, lastResetAgoInSec=0, lastUsedAgoInSec=0, creationTimeAgoInSec=0}] will be managed by Spring

2016-12-02 15:26:40,292 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemMapper.insert]-[DEBUG] ==> Preparing: INSERT INTO tb_item (PRICE,UPDATED,STATUS,CREATED,SELL_POINT,ID,CID,IMAGE,TITLE,BARCODE,NUM) VALUES ( ?,?,?,?,?,?,?,?,?,?,? )

2016-12-02 15:26:40,325 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemMapper.insert]-[DEBUG] ==> Parameters: 519900(Long), 2016-12-02 15:26:40.148(Timestamp), 1(Integer), 2016-12-02 15:26:40.148(Timestamp), 推薦選擇下方的移動、聯通、電信優惠購,套餐有優惠,還有話費返還。(String), null, 560(Long), (String), Apple iPhone 7 (A1660) 32G 銀色移動聯通電信4G手機(String), (String), 999999(Integer)

2016-12-02 15:26:40,326 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemMapper.insert]-[DEBUG] <== Updates: 1

2016-12-02 15:26:40,332 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemMapper.insert!selectKey]-[DEBUG] ==> Executing: SELECT LAST_INSERT_ID()

2016-12-02 15:26:40,357 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemMapper.insert!selectKey]-[DEBUG] <== Total: 1

2016-12-02 15:26:40,358 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@77c39180]

2016-12-02 15:26:40,358 [http-bio-8081-exec-1] [org.springframework.jdbc.datasource.DataSourceTransactionManager]-[DEBUG] Participating in existing transaction

2016-12-02 15:26:40,388 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Fetched SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@77c39180] from current transaction

2016-12-02 15:26:40,397 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemDescMapper.insert]-[DEBUG] ==> Preparing: INSERT INTO tb_item_desc (ITEM_DESC,UPDATED,CREATED,ITEM_ID) VALUES ( ?,?,?,? )

2016-12-02 15:26:40,398 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemDescMapper.insert]-[DEBUG] ==> Parameters: <div id="activity_header" style="margin:0px;padding:0px;color:#666666;font-family:Arial, Verdana, 宋體;background-color:#FFFFFF;">

    <div style="margin:0px;padding:0px;text-align:center;">

        ……

<br />

</div>

<div id="activity_footer" style="margin:0px;padding:0px;color:#666666;font-family:Arial, Verdana, 宋體;background-color:#FFFFFF;">

    <div style="margin:0px;padding:0px;text-align:center;">

        <img alt="" class="" src="https://img30.360buyimg.com/jgsq-productsoa/jfs/t3577/344/1077770157/80811/316f9e36/581c7263N82a0e9fc.jpg" />

    </div>

</div>(String), 2016-12-02 15:26:40.388(Timestamp), 2016-12-02 15:26:40.388(Timestamp), 41(Long)

2016-12-02 15:26:40,399 [http-bio-8081-exec-1] [com.taotao.manage.mapper.ItemDescMapper.insert]-[DEBUG] <== Updates: 1

2016-12-02 15:26:40,400 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@77c39180]

2016-12-02 15:26:40,401 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@77c39180]

2016-12-02 15:26:40,401 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@77c39180]

2016-12-02 15:26:40,401 [http-bio-8081-exec-1] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@77c39180]

2016-12-02 15:26:40,401 [http-bio-8081-exec-1] [org.springframework.jdbc.datasource.DataSourceTransactionManager]-[DEBUG] Initiating transaction commit

2016-12-02 15:26:40,401 [http-bio-8081-exec-1] [org.springframework.jdbc.datasource.DataSourceTransactionManager]-[DEBUG] Committing JDBC transaction on Connection [ConnectionHandle{url=jdbc:mysql://127.0.0.1:3306/taotao?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true, user=root, debugHandle=null, lastResetAgoInSec=0, lastUsedAgoInSec=0, creationTimeAgoInSec=0}]

2016-12-02 15:26:40,403 [http-bio-8081-exec-1] [org.springframework.jdbc.datasource.DataSourceTransactionManager]-[DEBUG] Releasing JDBC Connection [ConnectionHandle{url=jdbc:mysql://127.0.0.1:3306/taotao?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true, user=root, debugHandle=null, lastResetAgoInSec=0, lastUsedAgoInSec=0, creationTimeAgoInSec=0}] after transaction

2016-12-02 15:26:40,404 [http-bio-8081-exec-1] [org.springframework.jdbc.datasource.DataSourceUtils]-[DEBUG] Returning JDBC Connection to DataSource

2016-12-02 15:26:40,422 [http-bio-8081-exec-1] [org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdviceChain]-[DEBUG] Invoking ResponseBodyAdvice chain for body=null

2016-12-02 15:26:40,422 [http-bio-8081-exec-1] [org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdviceChain]-[DEBUG] After ResponseBodyAdvice chain body=null

2016-12-02 15:26:40,422 [http-bio-8081-exec-1] [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] Null ModelAndView returned to DispatcherServlet with name 'taotao-manage': assuming HandlerAdapter completed request handling

2016-12-02 15:26:40,423 [http-bio-8081-exec-1] [org.springframework.web.servlet.DispatcherServlet]-[DEBUG] Successfully completed request

2016-12-02 15:26:40,423 [http-bio-8081-exec-1] [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[DEBUG] Returning cached instance of singleton bean 'org.mybatis.spring.SqlSessionFactoryBean#0'

 

  1. 圖片上傳

    1. 上傳組件

使用KindEditor的上傳組件:

 

  1. 上傳組件的JS實現

    1. 上傳參數

  1. 官方示例代碼

workspace/taotao-manage/taotao-manage-web/src/main/webapp/js/kindeditor-4.1.10/examples/multi-image-dialog.html

 

  1. 我們的實現

 

  1. 實現圖片上傳

在SpringMVC中實現圖片上傳:

  1. 導入依賴 commons-fileupload
  2. 配置文件上傳解析器
  3. 編寫具體的上傳邏輯(Controller)

 

對文件做校驗:

  1. 類型,通過文件的后綴名
  2. 大小
  3. 上傳文件的內容做校驗
    1. 通過獲取文件的寬和高來判斷是否是圖片
    1. 上傳組件

需求:上傳文件返回的數據是:文本類型的json數據。

 

響應類型:

 

文本類型:

 

歷史遺留問題。

 

解決:

 

 

安裝taotao-common到本地倉庫時出錯:

 

測試:

 

 

  1. 完整的代碼

 

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.http.MediaType;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

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.manage.bean.PicUploadResult;

 

/**

* 圖片上傳

*/

@Controller

@RequestMapping("/pic")

public class PicUploadController {

 

private static final Logger LOGGER = LoggerFactory.getLogger(PicUploadController.class);

 

private static final ObjectMapper mapper = new ObjectMapper();

 

// 允許上傳的格式

private static final String[] IMAGE_TYPE = new String[] { ".bmp", ".jpg", ".jpeg", ".gif", ".png" };

 

/**

*

* @param uploadFile

* @param response

* @return返回文本類型的json數據

* @throws Exception

*/

@RequestMapping(value = "/upload", method = RequestMethod.POST, 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, "E:\\0114\\taotao-upload"),

"\\", "/");

fileUploadResult.setUrl("http://image.taotao.com" + 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();

}

 

//java對象序列化為json字符串

return mapper.writeValueAsString(fileUploadResult);

}

 

//E:\\1110\\taotao-upload\\images\\2015\\11\\13\\20151113111111111.jpg

private String getFilePath(String sourceFileName) {

String baseFolder = "E:\\0114\\taotao-upload" + 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;

}

 

}

  1. 測試

  1. 解決顯示圖片的問題

之前的上傳后,通過tomcat訪問圖片。

 

沒有真實的項目是通過tomcat訪問靜態資源。 為什么?

 

Tomcat是應用服務器,作用:處理動態請求。

 

Nginx、Apache是web服務器,作用:處理靜態資源、反向代理功能。

 

Web服務器的並發能力遠高於應用服務器。

 

  1. 配置nginx訪問圖片

  1. 配置hosts

  1. 測試

  1. 圖片存儲路徑硬編碼到java代碼中

解決方案:需要將路徑配置到外部的配置文件中。

 

  1. @value

@Value作用:獲取配置文件的值。

 

注入值:在Spring容器初始化(所有的bean)之后,在當前的所在容器中獲取值,然后注入。

 

  1. Spring父子容器

Spring容器 -- 父容器

SpringMVC容器 -- 子容器

 

父子容器的關系:

  1. 子容器能夠訪問父容器的資源(bean)
    1. 示例:Controller可以注入Service
  2. 父容器不能訪問子容器的資源(bean)

 

  1. 實現

  1. 定義ProperttiesService:
  2. 在Controller中注入Service:
  3. 測試

 

  1. 查詢商品列表

    1. JS

  1. EasyUI的datagrid的格式化輸出

默認情況下,會直接顯示返回的數據,但是有些情況下不能直接顯示,如:價格、日期、性別,需要指定formatter函數。

 

 

 

 

效果:

  1. 后台實現

Controller:

 

擴展BaseService中的排序查詢方法:

 

  1. 日志的書寫

 

總結:

  1. 方法的入參處需要將參數打印出
  2. 業務執行的狀態發生變化時,需要打印
  3. 異常處需要打印

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM