2006-京淘Day07

1. 商品后台管理

1.1 商品修改操作

1.1.1 页面URL分析

1.1.2 参数分析

1.1.3 返回值结果确定

1.1.4 编辑ItemController

/**
     * 商品修改操作
     * 1.url地址: http://localhost:8091/item/update
     * 2.参数:      form表单提交
     * 3.返回值:  SysResult对象
     */
    @RequestMapping("/update")
    public SysResult updateItem(Item item){

        itemService.updateItem(item);
        return SysResult.success();
    }
 

1.1.5 编辑ItemService

@Override
    public void updateItem(Item item) {

        //更新时间由程序自动填充....
        itemMapper.updateById(item);
    }
 

1.2 商品删除

1.2.1 url请求地址说明

1.2.2 请求参数

1.2.3 返回值类型

1.2.4 编辑ItemController

/**
     * 业务: 商品删除
     * url地址: http://localhost:8091/item/delete
     * 参数:    ids: 1474391993,1474391997,1474391996
     * 返回值:  系统返回值VO
     * List 可以赋值 name="list[0]" value=100
     *                 name="list[1]" value=200
     */
    @RequestMapping("/delete")
    public SysResult deleteItems(Long[] ids){

        itemService.deleteItems(ids);
        return SysResult.success();
    }
 

1.2.4 编辑ItemService

@Override
    public void deleteItems(Long[] ids) {
        //1.将数组转化为集合
        List<Long> longList = Arrays.asList(ids);
        itemMapper.deleteBatchIds(longList);
    }
 

1.3 商品上架/下架操作

1.3.1 业务说明

说明:当用户点击上架/下架的按钮时,需要修改item数据表中的status信息.同时修改时间…

1.3.2 页面分析

1.3.3 参数分析

1.3.4返回值结果分析

1.3.5 修改页面url地址

1.3.6 编辑ItemController

/**
     * 实现商品的下架
     * url地址: http://localhost:8091/item/updateStatus/2    status=2
     *             http://localhost:8091/item/updateStatus/1   status=1
     * 利用RestFul风格实现通用的操作.
     * 参数:   ids: 1474391997,1474391996,1474391995
     * 返回值:  VO对象
     */
    @RequestMapping("/updateStatus/{status}")
    public SysResult updateStatus(@PathVariable Integer status,Long[] ids){

        itemService.updateStatus(status,ids);
        return SysResult.success();
    }
 

1.3.7 编辑ItemService

/**
     * sql: update tb_item set status = #{status},updated={date}
     *         where id in (id1,id2,id3)
     *     MP机制实现
     * @param status
     * @param ids
     */
    @Override
    public void updateStatus(Integer status, Long[] ids) {

        Item item = new Item();    //封装修改的值
        item.setStatus(status);
        UpdateWrapper<Item> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("id", Arrays.asList(ids));
        itemMapper.update(item,updateWrapper);
    }
 

 

2. 富文本编辑器

2.1 富文本编辑器介绍

KindEditor是一套开源的HTML可视化编辑器,主要用于让用户在网站上获得所见即所得编辑效果,兼容IE、Firefox、Chrome、Safari、Opera等主流浏览器。

2.2 入门案例

<script type="text/javascript">
    $(function(){
        KindEditor.ready(function(){
            //在指定的位置创建富文本.
            KindEditor.create("#editor")
        })
    })
</script>
</head>
<body>
<h1>富文本编辑器</h1>
<textarea style="width:700px;height:350px" id="editor"></textarea>
</body>

2.3 关于商品模块的表设计

表业务说明: 商品表中的id与商品详情表中的ID是一致的.

2.4 编辑ItemDesc POJO对象

@TableName("tb_item_desc")
@Data
@Accessors(chain = true)
public class ItemDesc extends BasePojo{

    //item中的id与ItemDesc中的Id应该保持一致...
    @TableId    //只标识主键  不能自增.
    private Long itemId;
    private String itemDesc;
}
 

2.5 重构商品新增

2.5.1 编辑ItemController

@RequestMapping("/save")
    public SysResult saveItem(Item item, ItemDesc itemDesc){

        itemService.saveItem(item,itemDesc);
        return SysResult.success();
    
    }
 

2.5.2 编辑ItemService

@Override
    @Transactional    //控制事务
    public void saveItem(Item item, ItemDesc itemDesc) {
        //思考:如果每次编辑数据库 每次都需要操作公共的属性...
        //完成自动的填充功能
        //Date date = new Date();
        //item.setStatus(1).setCreated(date).setUpdated(date);
        item.setStatus(1);
        //如果完成入库操作,时应该动态回显主键信息.
        //MP的方式实现数据入库操作,MP会自动的实现主键信息的回显..
        itemMapper.insert(item);

        //itemDesc属性有值
        itemDesc.setItemId(item.getId());
        itemDescMapper.insert(itemDesc);
    }
 

2.6 商品详情回显

2.6.1 页面url分析

2.6.2 页面JS

2.6.3 编辑ItemController

/**
     * 业务:动态获取商品详情信息
     * url地址: http://localhost:8091/item/query/item/desc/1474391999
     * 参数:   itemId restFul方式获取
     * 返回值: 系统VO对象
     */
    @RequestMapping("/query/item/desc/{itemId}")
    public SysResult findItemDescById(@PathVariable Long itemId){

        ItemDesc itemDesc = itemService.findItemDescById(itemId);
        return SysResult.success(itemDesc);
    }
 

2.6.4 编辑ItemService

 

@Override
    public ItemDesc findItemDescById(Long itemId) {

        return itemDescMapper.selectById(itemId);
    }
 

2.6.5 页面效果展现

2.7 重构商品修改

2.7.1 编辑ItemDescController

@RequestMapping("/update")
    public SysResult updateItem(Item item,ItemDesc itemDesc){

        itemService.updateItem(item,itemDesc);
        return SysResult.success();
    }
 

2.7.2 编辑ItemDescService

@Transactional
    @Override
    public void updateItem(Item item, ItemDesc itemDesc) {

        //更新时间由程序自动填充....
        itemMapper.updateById(item);

        itemDesc.setItemId(item.getId());
        itemDescMapper.updateById(itemDesc);
    }
 

2.8 重构商品删除

@Transactional
    @Override
    public void deleteItems(Long[] ids) {
        //1.将数组转化为集合
        List<Long> longList = Arrays.asList(ids);
        itemMapper.deleteBatchIds(longList);
        //2.删除商品详情信息
        itemDescMapper.deleteBatchIds(longList);
    }
 

3. 文件上传

3.1 文件上传入门案例

3.1.1 页面分析

<form action="http://localhost:8091/file" method="post" 
    enctype="multipart/form-data">
        <input name="fileImage" type="file" />
        <input type="submit" value="提交"/>
    </form>
 

3.1.2 编辑FileController

package com.jt.controller;

import org.springframework.http.codec.multipart.FormFieldPart;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

@RestController
public class FileController {

    /**
     * 文件上传的入门案例
     * url:http://localhost:8091/file
     * 参数: fileImage 名称
     * 返回值:  文件上传成功!!!
     * SpringMVC 提供了工具API 专门操作流文件.
     *
     * 文件上传的具体步骤:
     *  1.准备文件目录
     *  2.准备文件的全名   xxxx.jpg
     *  3.准备文件上传的路径  D:/JT-SOFT/images/xxxx.jpg
     *  4.将字节信息输出即可.
     *  大小不要超过1M
     */
    @RequestMapping("/file")
    public String file(MultipartFile fileImage) throws IOException {

        String dirPath = "D:/JT-SOFT/images";
        File dirFile = new File(dirPath);
        if(!dirFile.exists()){
            dirFile.mkdirs();   //一劳永逸的写法
        }
        //获取文件的名称
        String fileName = fileImage.getOriginalFilename();
        //获取文件全路径
        String filePath = dirPath + "/" + fileName;
        File file = new File(filePath);
        fileImage.transferTo(file); //将字节信息输出到指定的位置中

        return "文件上传成功!!!!";
    }


}

 

3.2 商品文件上传实现

3.2.1 页面分析

 

3.2.2 准备ImageVO对象

package com.jt.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class ImageVO {

    //{"error":0,"url":"图片的保存路径","width":图片的宽度,"height":图片的高度}
    private Integer error;  //错误信息   0程序运行正常    1.文件上传有误.
    private String url;     //图片访问的虚拟路径
    private Integer width;  // >0
    private Integer height; // >0

    //设定上传失败的方法
    public static ImageVO fail(){

        return new ImageVO(1,null,null,null);
    }

    public static ImageVO success(String url,Integer width,Integer height){

        return new ImageVO(0,url,width,height);
    }
}

 

3.2.3 编辑FileController

 /**
     * 实现文件上传
     * url地址: http://localhost:8091/pic/upload?dir=image
     * 参数:    uploadFile: 文件的字节信息.
     * 返回值:  {"error":0,"url":"图片的保存路径","width":图片的宽度,"height":图片的高度}
     *          ImageVO对象...
     */
    @RequestMapping("/pic/upload")
    public ImageVO upload(MultipartFile uploadFile){

        return fileService.upload(uploadFile);
    }
 

3.2.4 编辑FileService

package com.jt.service;

import com.jt.vo.ImageVO;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

@Service
public class FileServiceImpl implements FileService{

    private String rootDirPath = "D:/JT-SOFT/images";

    //1.2 准备图片的集合  包含了所有的图片类型.
    private static Set<String> imageTypeSet;
    static {
        imageTypeSet = new HashSet<>();
        imageTypeSet.add(".jpg");
        imageTypeSet.add(".png");
        imageTypeSet.add(".gif");
    }


    /**
     * 完善的校验的过程
     * 1. 校验是否为图片
     * 2. 校验是否为恶意程序
     * 3. 防止文件数量太多,分目录存储.
     * 4. 防止文件重名
     * 5. 实现文件上传.
     * @param uploadFile
     * @return
     */
    @Override
    public ImageVO upload(MultipartFile uploadFile) {
        //1.校验图片类型  jpg|png|gif..JPG|PNG....
        //1.1 获取当前图片的名称 之后截取其中的类型.   abc.jpg
        String fileName = uploadFile.getOriginalFilename();
        int index = fileName.lastIndexOf(".");
        String fileType = fileName.substring(index);
        //将数据转化为小写
        fileType = fileType.toLowerCase();
        //1.3 判断图片类型是否正确.
        if(!imageTypeSet.contains(fileType)){
            //图片类型不匹配
            return ImageVO.fail();
        }

        //2.校验是否为恶意程序 根据宽度/高度进行判断
        try {
            //2.1 利用工具API对象 读取字节信息.获取图片对象类型
            BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
            //2.2 校验是否有宽度和高度
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            if(width==0 || height==0){
                return ImageVO.fail();
            }

            //3.分目录存储  yyyy/MM/dd 分隔
            //3.1 将时间按照指定的格式要求 转化为字符串.
            String dateDir = new SimpleDateFormat("/yyyy/MM/dd/")
                             .format(new Date());
            //3.2 拼接文件存储的目录对象
            String fileDirPath = rootDirPath + dateDir;
            File dirFile = new File(fileDirPath);
            //3.3 动态创建目录
            if(!dirFile.exists()){
                dirFile.mkdirs();
            }

            //4.防止文件重名  uuid.jpg 动态拼接
            //4.1 动态生成uuid  实现文件名称拼接  名.后缀
            String uuid =
                    UUID.randomUUID().toString().replace("-", "");
            String realFileName = uuid + fileType;

            //5 实现文件上传
            //5.1 拼接文件真实路径 dir/文件名称.
            String realFilePath = fileDirPath + realFileName;
            //5.2 封装对象  实现上传
            File realFile = new File(realFilePath);
            uploadFile.transferTo(realFile);

            //实现文件上传成功!!!!
            String url = "https://img14.360buyimg.com/n0/jfs/t1/45882/22/7027/53284/5d49358aE9c25c1bd/fb7365463f6a1a7b.jpg";
            return ImageVO.success(url,width,height);
        } catch (IOException e) {
            e.printStackTrace();
            return ImageVO.fail();
        }
    }
}

 

3.2.5 页面效果展现

 

 

 

<?xml version="1.0" encoding="UTF-8"?>
<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>

    <groupId>com.jt</groupId>
    <artifactId>jt</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--当前父级工程打包类型,如果修改了项目的名称记得修改modules标签
    -->
    <modules>
        <module>jt-common</module>
        <module>jt-manage</module>
        <module>jt-web</module>
        <module>jt-sso</module>
        <module>jt-cart</module>
        <module>jt-order</module>
    </modules>

    <!--定义父级工程打包类型-->
    <packaging>pom</packaging>

    <!--1.引入springboot的父级项目
    -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <!--2.引入属性的配置-->
    <properties>
        <java.version>1.8</java.version>
        <!--跳过测试类打包-->
        <skipTests>true</skipTests>
    </properties>

<!--    在父级项目中添加jar包文件-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--引入插件lombok 自动的set/get/构造方法插件  -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!--引入数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--springBoot数据库连接  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <!--spring整合mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>

        <!--springBoot整合JSP添加依赖  -->
        <!--servlet依赖 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </dependency>

        <!--jstl依赖 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>

        <!--使jsp页面生效 -->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>

        <!--支持热部署 -->
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-devtools</artifactId>-->
<!--        </dependency>-->

        <!--添加httpClient jar包 -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>

        <!--引入dubbo配置-->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>

        <!--添加Quartz的支持 -->
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-quartz</artifactId>-->
<!--        </dependency>-->

        <!-- 引入aop支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <!--spring整合redis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
        </dependency>

    </dependencies>

    <!--
        父级工程只是项目的管理者不会在其中编辑代码,所以不需要添加build
    -->

</project>

 

server:
  port: 8092    
spring:     #定义springmvc视图解析器
  mvc:
    view:
      prefix: /WEB-INF/views/
      suffix: .jsp

dubbo:
  scan:
    basePackages: com.jt
  application:
    name: consumer-web   #定义消费者名称
  registry:               #注册中心地址
    address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183


  
#最大连接数
http.maxTotal = 1000
#并发数
http.defaultMaxPerRoute = 20
#创建连接的最长时间
http.connectTimeout=5000
#从连接池中获取到连接的最长时间
http.connectionRequestTimeout=500
#数据传输的最长时间
http.socketTimeout=5000
#提交请求前测试连接是否可用
http.staleConnectionCheckEnabled=true

 

package com.jt;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

@SpringBootApplication(exclude=DataSourceAutoConfiguration.class)
//springboot启动时排除数据源
public class SpringBootRun {
   
   public static void main(String[] args) {
      
      SpringApplication.run(SpringBootRun.class,args);
   }
}

 

package com.jt.config;

import com.jt.interceptor.UserInterceptor;
import com.jt.util.CookieUtil;
import org.apache.catalina.connector.Request;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MvcConfigurer implements WebMvcConfigurer{//web.xml配置文件
   
   //开启匹配后缀型配置
   @Override
   public void configurePathMatch(PathMatchConfigurer configurer) {
      //开启后缀类型的匹配  xxxx.html
      configurer.setUseSuffixPatternMatch(true);
   }


   @Autowired
   private UserInterceptor userInterceptor;
   /**
    * 添加拦截器功能
    */

   @Override
   public void addInterceptors(InterceptorRegistry registry) {


      registry.addInterceptor(userInterceptor)
            .addPathPatterns("/cart/**","/order/**");
   }
}

 

package com.jt.interceptor;

import com.jt.pojo.User;
import com.jt.thread.UserThreadLocal;
import com.jt.util.CookieUtil;
import com.jt.util.ObjectMapperUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import redis.clients.jedis.JedisCluster;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component//spring容器管理对象
public class UserInterceptor implements HandlerInterceptor {

    @Autowired
    private JedisCluster jedisCluster;

    /**
     * spring版本升级 4 必须实现所有的方法 spring 5 只需要重写指定的方法即可
     *
     * 需求:拦截/cart开头的所有的请求进行拦截,并且校验用户是否登录.....
     * 拦截器选择:preHander
     * 如何判断用户是否登录:
     *1.检查cookie信息
     * 2.检查Redis中是否有记录
     * true:请求应该放行
     * false:请求应该拦截 则配合重定向的语法实现页面跳转到登录页面 使得程序流转起来
     *
     */

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //1.判断用户是否登录 检查cookie是否有值
        String ticket=CookieUtil.getCookieValue(request,"JT_TICKET");

        //2.校验ticket
        if (!StringUtils.isEmpty(ticket)){

            //3.判断redis中是否有值
            if (jedisCluster.exists(ticket)){
                //4.动态获取json信息
                String userJSON=jedisCluster.get(ticket);
                User user= ObjectMapperUtil.toObj(userJSON, User.class);
                request.setAttribute("JT_USER", user);
                UserThreadLocal.set(user);
                return true;
            }

        }
        response.sendRedirect("/user/login.html");
        return false;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //销毁数据
        request.removeAttribute("JT_USER");
        UserThreadLocal.remove();
    }
}

 

package com.jt.thread;

import com.jt.pojo.User;

public class UserThreadLocal {

    //static不会影响线程 threadLocal创建时跟随线程
    private static ThreadLocal<User> threadLocal=new ThreadLocal<>();
    public static  void set(User user){
        threadLocal.set(user);
    }

    public static User get(){
        return threadLocal.get();
    }

    public static void remove(){
        threadLocal.remove();
    }
}

 

package com.jt.service;

import com.jt.pojo.Item;

import java.util.List;

public interface HttpClientService {
    List<Item> getItems();
}

 

package com.jt.service;

import com.jt.pojo.Item;
import com.jt.util.ObjectMapperUtil;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class HttpClientServiceImpl implements HttpClientService{

    @Override
    public List<Item> getItems() {
        List<Item> itemList=new ArrayList<>();
        //1.定义远程访问网址
        String url="http://manage.jt.com/getItems";
        HttpClient httpClient =HttpClients.createDefault();
        HttpGet httpGet=new HttpGet(url);
        try {
            HttpResponse httpResponse =httpClient.execute(httpGet);
            if (httpResponse.getStatusLine().getStatusCode()==200){
                String result=
                        EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
            //result是jt-manage为jt-web返回的List<Item>的JSON串
                if (!StringUtils.isEmpty(result)){
                    itemList=ObjectMapperUtil.toObj(result, itemList.getClass());
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return itemList;
    }
}

 

package com.jt.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.pojo.Cart;
import com.jt.pojo.User;
import com.jt.service.DubboCartService;
import com.jt.thread.UserThreadLocal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@Controller
@RequestMapping("/cart")
public class CartController {

    @Reference(timeout = 3000,check = false)
    private DubboCartService cartService;

    /**
     * 业务需求:根据userId查询购物车数据
     * url地址:http://www.jt.com/cart/show.html
     * 请求参数:动态获取userId
     * 返回值结果:cart.jsp页面
     * 页面取值方式:${cartList}
     */

    @RequestMapping("/show")
    public String findCartListByUserId(Model model,HttpServletRequest request){

//        User user = (User) request.getAttribute("JT_USER");
//        Long userId=user.getId();
        Long userId= UserThreadLocal.get().getId();
        List<Cart> cartList=cartService.findCartListByUserId(userId);
        model.addAttribute("cartList", cartList);
        return "cart";
    }

    /**
     * 业务:实现购物车数量的更新
     * url: http://www.jt.com/cart/update/num/562379/8
     * 参数:itemId/num
     * 返回值:void
     *
     */


    @RequestMapping("/update/num/{itemId}/{num}")
    @ResponseBody//1.返回值转化为json 2.ajax结束标识
    public void updateCartNum(Cart cart, HttpServletRequest request){//key的名称必须和属性的名称一致

        //User user = (User) request.getAttribute("JT_USER");
        //Long userId=user.getId();
        Long userId= UserThreadLocal.get().getId();
        cart.setUserId(userId);
        cartService.updateCartNum(cart);

    }


    /**
     * 完成购物车新增
     * url:http://www.jt.com/cart/add/562379.html
     * 参数:form表单提交 对象接收
     * 返回值: 重定向到购物车列表页面中
     *
     */
    @RequestMapping("/add/{itemId}")
    public String saveCart(Cart cart,HttpServletRequest request){

        //User user = (User) request.getAttribute("JT_USER");
      //  Long userId=user.getId();
        Long userId= UserThreadLocal.get().getId();
        cart.setUserId(userId);
        cartService.saveCart(cart);
        return "redirect:/cart/show.html";
    }

    /**
     * 购物车删除操作
     * url地址:http://www.jt.com/cart/delete/562379.html
     * 参数:获取itemId
     * 返回值:重定向到购物车的展现页面
     *
     */

    @RequestMapping("/delete/{itemId}")
    public String deleteCarts(@PathVariable Long itemId,HttpServletRequest request){

        //User user = (User) request.getAttribute("JT_USER");
        //Long userId=user.getId();
        Long userId= UserThreadLocal.get().getId();
        cartService.deleteCarts(userId,itemId);
        return "redirect:/cart/show.html";
    }

}

 

package com.jt.controller;

import com.jt.pojo.Item;
import com.jt.service.HttpClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class HttpClientController {

    @Autowired
    private HttpClientService httpClientService;

    /**
     * 获取后端manage中商品数据信息
     */
    @RequestMapping("/getItems")
    public List<Item> getItems(){

        return httpClientService.getItems();
    }
}

 

package com.jt.controller;

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

@Controller//跳转页面
public class IndexController {

    //用户通过/index请求实现页面的跳转
    @RequestMapping("/index")
    public String index(){

        return "index";
    }
}

 

package com.jt.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.pojo.Item;
import com.jt.pojo.ItemDesc;
import com.jt.service.DubboItemService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/items")
public class ItemController {

    @Reference(timeout = 3000,check = false)//消费者启动时不会校验是否有提供者
    private DubboItemService itemService;

    /**
     * 实现商品详情页面跳转
     * url:http://www.jt.com/items/562379.html
     * 参数:562379 itemId
     * 返回值: item.jsp页面
     *${item.title } item对象
     *     ${itemDesc.itemDesc } itemDesc对象
     *
     * 思路:
     * 1.重构jt-manage项目
     * 2.创建中立接口DubboItemService
     * 3.实现业务调用获取item/itemDesc对象
     */

    @RequestMapping("/{itemId}")
    public String findItemById(@PathVariable Long itemId, Model model){

        Item item=itemService.findItemById(itemId);
        ItemDesc itemDesc=itemService.findItemDescById(itemId);
        //问题:商品对象从哪里获取???
        //将数据保存到request域中
        model.addAttribute("item",item);
        model.addAttribute("itemDesc", itemDesc);
        return "item";
    }
}

 

package com.jt.controller;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.pojo.Cart;
import com.jt.pojo.Order;
import com.jt.service.DubboCartService;
import com.jt.service.DubboOrderService;
import com.jt.thread.UserThreadLocal;
import com.jt.vo.SysResult;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
@RequestMapping("/order")
public class OrderController {

    @Reference(timeout = 3000,check = false)
    private DubboOrderService orderService;
    @Reference(timeout = 3000,check = false)
    private DubboCartService cartService;

    /**
     * 订单页面跳转
     * url: http://www.jt.com/order/create.html
     * 页面取值: ${carts}
     */
    @RequestMapping("/create")
    public String create(Model model){

        //1.根据userId查询购物车信息
        Long userId = UserThreadLocal.get().getId();
        List<Cart> cartList = cartService.findCartListByUserId(userId);
        model.addAttribute("carts",cartList);
        return "order-cart";
    }

    /**
     * 订单提交
     * url: http://www.jt.com/order/submit
     * 参数: 整个form表单
     * 返回值: SysResult对象   携带返回值orderId
     * 业务说明:
     *   当订单入库之后,需要返回orderId.让用户查询.
     */
    @RequestMapping("/submit")
    @ResponseBody
    public SysResult saveOrder(Order order){
        Long userId = UserThreadLocal.get().getId();
        order.setUserId(userId);
        String orderId = orderService.saveOrder(order);
        if(StringUtils.isEmpty(orderId))
            return SysResult.fail();
        else
            return SysResult.success(orderId);

    }

    /**
     * 实现商品查询
     * 1.url地址: http://www.jt.com/order/success.html?id=71603356409924
     * 2.参数说明: id 订单编号
     * 3.返回值类型: success.html
     * 4.页面取值方式: ${order.orderId}
     */
    @RequestMapping("/success")
    public String findOrderById(String id,Model model){
        Order order = orderService.findOrderById(id);
        model.addAttribute("order",order);
        return "success";
    }









}

 

package com.jt.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.pojo.User;
import com.jt.service.DubboUserService;
import com.jt.util.CookieUtil;
import com.jt.vo.SysResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import redis.clients.jedis.JedisCluster;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller//需要进行页面跳转
@RequestMapping("/user")
public class UserController {

    @Reference(timeout = 3000,check = false)
    private DubboUserService userService;

    @Autowired
    private JedisCluster jedisCluster;

    /**
     * 实现用户模块页面跳转
     * url:http://www.jt.com/user/login.html 页面:login.jsp
     * url:http://www.jt.com/user/register.html 页面:register.jsp
     *要求:实现通用的页面跳转
     * restFul方式:
     * 1.动态获取url中的参数,之后实现通用的跳转
     *
     *
     */


    @RequestMapping("/{moduleName}")
    public String module(@PathVariable String moduleName){

        return moduleName;
    }

    /**
     * 需求:实现用户信息注册
     * 1.url请求地址:http://www.jt.com/user/doRegister
     * 2.请求参数: {password:_password,username:_username,phone:_phone},
     * 3.返回值结果:SysResult对象
     */


    @RequestMapping("/doRegister")
    @ResponseBody //将数据转化为JSON
    public SysResult saveUser(User user){
        //消费者给予dubbo协议将user对象进行远程网络数据传输
        userService.saveUser(user);
        return SysResult.success();
    }


    /**
     * 完成用户登陆操作
     * 1.url地址:http://www.jt.com/user/doLogin?r=0.9768995384445416
     * 2。参数:{username:_username,password:_password}
     * 3.返回值:SysResult对象
     *
     * 4.cookie的使用:
     * 4.1 setPath("/") path表示如果需要获取cookie中的数据,则url地址所在路径
     * url:http://www.jt.com/person/findAll
     * cookie.setPath("/");一般都是/
     * cookie.setPath("/person");
     * 4.2 setDemain("xxxxx")  设定cookie共享的域名地址
     */

    @RequestMapping("/doLogin")
    @ResponseBody
    public SysResult doLogin(User user, HttpServletResponse response){

        String ticket= userService.doLogin(user);
        if (StringUtils.isEmpty(ticket)){

            //说明用户名或者密码错误
            return SysResult.fail();
        }else {
            //1.创建Cookie
//            Cookie cookie=new Cookie("JT_TICKET",ticket);
//            cookie.setMaxAge(7*24*60*60);//设定cookie存活的最大值
//            cookie.setPath("/");//设定cookie有效范围
//            cookie.setDomain("jt.com");//设定cookie共享的域名 是实现单点登陆必备要素
//            response.addCookie(cookie);
            CookieUtil.addCookie(response, "JT_TICKET", ticket, 7*24*60*60, "jt.com");
            return SysResult.success();//表示用户登陆成功
        }
    }

    /**
     * 实现用户的退出操作,重定向到系统的首页
     * url:http://www.jt.com/user/logout.html
     *  1.删除Redis中的数据 key
     *  2.删除Cookie记录
     */

    @RequestMapping("logout")
    public String logout(HttpServletRequest request,HttpServletResponse response){

        //1.根据JT_TICKET获取指定的ticket
        String ticket=CookieUtil.getCookieValue(request,"JT_TICKET");
        //2.判断ticket是否为null
        if (!StringUtils.isEmpty(ticket)){
            jedisCluster.del(ticket);
            CookieUtil.deleteCookie(response, "JT_TICKET", "jt.com");
        }


        return "redirect:/";
    }





}

 

package com.jt;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.junit.jupiter.api.Test;

import java.io.IOException;

public class HttpClientTest {

    /**
     * 要求:在java代码内部,获取百度的页面
     * 实现步骤:
     * 1.确定目标地址:https://www.baidu.com
     * 2.创建httpClient客户端对象
     * 3.创建请求类型
     * 4.发起http请求,并且获取响应的结果。
     * 之后判断状态码是否为200,如果等于200则请求正确
     * 5.如果请求正确则动态获取响应值信息,之后进行数据的再次加工.....
     */
    @Test
    public void testGet() throws IOException {

        String url="https://www.baidu.com";
        HttpClient httpClient =HttpClients.createDefault();
        HttpGet httpGet=new HttpGet(url);
        HttpResponse httpResponse =httpClient.execute(httpGet);
        if (httpResponse.getStatusLine().getStatusCode()==200){
            //表示用户请求正确
            //获取返回值数据
            HttpEntity httpEntity =httpResponse.getEntity();
            String result=EntityUtils.toString(httpEntity,"UTF-8");
            System.out.println(result);
        }
    }
}

 

<html>

<h1>hello</h1>
</html>

 

<html>
<body>
<h2>Hello World!</h2>
</body>
</html>

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JSONP测试</title>
<script type="text/javascript" src="http://manage.jt.com/js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript">
   $(function(){
      alert("测试访问开始!!!!!")
      $.ajax({
         url:"http://manage.jt.com/web/testJSONP",
         type:"get",             //jsonp只能支持get请求
         dataType:"jsonp",       //dataType表示返回值类型
         jsonp: "callback",    //指定参数名称
         jsonpCallback: "hello",  //指定回调函数名称
         success:function (data){   //data经过jQuery封装返回就是json串
            alert(data.id);
            alert(data.name);
            //转化为字符串使用
            //var obj = eval("("+data+")");
            //alert(obj.name);
         }  
      });    
   })
</script>
</head>
<body>
   <h1>JSON跨域请求测试</h1>
</body>
</html>

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试JSON跨域问题</title>
   <!--js引入函数类库-->
<script type="text/javascript" src="http://manage.jt.com/js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript">
   /*$(){}结构必然是jQuery函数类库导入后才能正确执行*/
   $(function(){
      alert("我执行了AJAX");
      //利用jQuery发起AJAX请求
      $.get("http://manage.jt.com/test2.json",function(data){
         //alert(data.name);
         console.log(data);
      })
   })
</script>
</head>
<body>
   <h1>JSON跨域请求测试</h1>
</body>
</html>

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试JSON跨域问题</title>  
   <script type="text/javascript">
      /*JS是解释执行的语言  */
      /*定义回调函数  */
      function hello(data){
         alert(data.name);
      }
   </script>
   <!--该json一直保存到浏览器中等待调用,但是没有函数名称无法调用  -->
   <script type="text/javascript" src="http://manage.jt.com/test.json"></script>
   <script type="text/javascript" src="http://manage.jt.com/js/jquery-easyui-1.4.1/jquery.min.js"></script>
</head>
<body>
   <h1>JS跨域问题</h1>
   

</body>


</html>

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值