精华内容
下载资源
问答
  • 在设计Web项目的目录结构时,一般吧JSP 和 HTML文件放在( )下。 文档根目录或其子文件下 在Web项目的目录结构中,web.xml文件位于( )中。 WEB-INF目录 下面对于B/S架构与C/S架构的描述错误的是

    JAVA WEB

    第1章.JAVA WEB介绍

    • 单选题

      1. 当多个用户请求同一个JSP页面时,Tomcat服务器为每个客户启动一个() 线程
      2. 下列说法哪一项是正确的( ) Tomcat用于JSP技术所开发网站的服务器
      3. Tomcat服务器的默认端口号是:( ) 8080
      4. 在设计Web项目的目录结构时,一般吧JSP 和 HTML文件放在( )下。 文档根目录或其子文件下
      5. 在Web项目的目录结构中,web.xml文件位于( )中。 WEB-INF目录
      6. 下面对于B/S架构与C/S架构的描述错误的是( )。 B/S架构解决了C/S架构的弊端,因而在程序开发中将会逐步取代C/S架构
      7. 在web.xml中使用_____标签配置过滤器。 <filter><filter-mapping>
      8. 不是JSP运行必须的是( )。 数据库
      9. Tomcat的端口号可以在_____文件中修改。 server.xml
    • 判断题

      1. Tomcat和JDK都不是开源的。() ×
      2. 动态网页和静态网页的根本区别在于服务器端返回的HTML文件是事先存储好的还是由动态网页程序生成的() √
    展开全文
  • 目前市场业务中产品以及其他项目的认证和检测方面存在诸多不便,用户需要实地考察并频繁与检测单位沟通,填写繁琐的纸质检测报告、当面送递样品,对于检测环节中存在的问题难以及时交互并处理。市场上相应的检测...
  • 整个blog进行开发之前,要确定出整个项目的整体架构,包括系统的选型、运行环境的确定及系统结构设计。下面对这进行详细介绍。 进行软件系统开发的最初环节,一般都需要进行系统的选型,即根据系统功能的实际...
  • 概要设计阶段,大家来看看我们是怎么做。导演,灯光,给大叔一个特写…..   项目背景说明 系统背景:这是一个数据量大,用户数少,外部接口数据多,批处理时间长、子系统多企业业务管理系统。 技术背景:...

    在概要设计阶段,大家来看看我们是怎么做的。导演,灯光,给大叔一个特写…..

     

    项目背景说明

    系统背景:这是一个数据量大,用户数少,外部接口数据多,批处理时间长、子系统多的企业业务管理系统。

    技术背景:使用客户端(Browser)+ Web + EJB + 数据源 的四层应用结构

    项目人员:20人左右

    说明:很古老的技术,只用于参考

    目标:理解做概要设计的基本步骤和思考要点

    参考时间点:准备做概要设计的时候做参考,没做的时候只要知道都有什么内容即可。

     

    摘要

    分六步走,依次为总体设计、接口设计、界面总体设计、数据库设计、系统安全设计、系统部署。其中:

    总体设计是在选择架构及其各类约定

    接口设计是内部、外部接口的协议和约定

    界面总体设计是界面的样式、色调的约定

    数据库设计是选择数据库、命名、分布、设计原则的约定

    系统安全设计是对系统的安全使用的协议和约定

    系统部署是如何部署到客户环境下的约定

     

    关键词

    约定

     

    前提条件

       已经确定使用的框架

    已经确定框架的风险

    已经做过可行性分析

    ……

    没有这些条件,大家会很失望的发现后续的内容全部都是在谈约定

     

    开始踏步走

    第一步:总体设计

    1、设计目标

       分为2部分

       第一部分:需要实现的亮点,按亮点一句话搞定

    例如:

    满足《需求规格说明书-总论》中项目涵盖范围要求;

    实现对大数据量历史数据的管理;

    提供良好的架构组织,保证扩展能力,减少功能模块的扩展对核心架构的影响;

    提供良好的用户界面;

    等等。

     

    第二部分:实现的范围限制,有就写,无略过

     

    2、运行环境

    2.1 软件环境。如操作系统、数据库、WEB服务器、应用服务器等等。

    2.2 硬件环境。如按客户的规模给出最低配置、推荐配置。

    2.3 网络结购。画出系统的网络拓扑结构,然后做简单的说明。

    2.4 逻辑结构。画出系统的逻辑结构图,然后做简单的说明。

    2.5 总体架构

    以下目录按需要写,使用例子采用的基本架构是J2EE

     

    2.5.1 J2EE整体架构

    客户端(Browser)+ Struts + EJB + 数据源 的四层应用结构,自己画或者用GOOGLE找个类似的图,然后对所列的架构做简单的描述,最后描述文字描述完整的系统调用过程。

         重点就是简单的吹一吹选择的框架合理性

     

    2.5.2 客户端和WEB层实现

    2.5.2.1 概述

    客户端:系统的实现方式,如DHTML+javascript+XML+ActiveX

    WEB端:采用STRUTS的框架

     

    2.5.2.2 STRUTS架构

       画个图表达STRUTS是怎么和业务层、数据层交互;

       文字描述一下在STRUTS框架下一个完整的系统调用过程。



     

     

     

    2.5.2.3 WEB工程组织结构

    WEB部署包的目录结构;

    如果有使用自定的标签简单的列出。

     

    2.5.3 EJB层实现

    (重要的是要约定输入输出和工程文件的组织结构)

    概述

    DAO设计模式

    系统DAO类结构

    公共输入输出对象

    (约定输入输出的样式,如果不是公共输入输出,说明组成原则)

    DAO实现举例

    EJB接口设计

    EJB工程组织结构

    (这个约定很重要,可以用图来表达)

     

     

     

     

    2.5.4 数据层实现

    (就写选择的数据库是什么?本例中使用的是ORACLE

     

    2.6 非功能性需求的实现

    2.6.1 JDBC连接管理

    (是不是有使用连接池,有的话在这里申明)

     

    2.6.2 系统参数配置

    (申明系统参数配置约定)

     

    2.6.3 统一认证中心和权限控制

    (如果包含了很多子系统,就会用到,有的话只要说明一下检验的位置)

     

    2.6.4 日志管理

    (列出日志类型、记录内容、记录点、记录介质、调用方法、管理方式。另外配置说明)

     

    2.6.5 系统出错信息与异常处理

    (异常处理的约定)

     

    2.6.6  JAVA公共库

    (调用自己的公共类简单说明)

     

    2.6.7 JAVA单元测试支持

    (单元测试约定)

     

    2.6.8 公共系统平台框架

    (在公共系统平台下各个子系统部署和命名的约定)

     

    2.6.9 前端功能实现

    浏览器端打印

    (控件名称和开发工具约定)

    文件上传

    (控件名称和开发工具约定)

    客户端报表

    (报表使用的技术约定)

     

    2.6.10 其它功能实现说明

    数据查询

    (查询的数据分页约定)

    工作流系统

    (是否使用工作流,如果使用,则使用工作流机制约定)

     

    2.7 开发工具与环境

           (开发工具/软件/组件的版本预定,及其对应的编码规范文件名)

     

    第二步:接口设计

    1 内部接口

    (内部各层之间的调用约定)

    2 外部接口

    (与外部系统之间调用的协议和约定)

     

    第三步:界面总体设计

    1 总体界面布局

    (界面布局约定,一般就是一个主界面图+简单说明)

    2 风格设计

    (色调约定)

    3 用户界面实现

    (用户界面使用方法的约定,如JSP

     

    第四步:数据库设计

    1 系统数据库设计原则

    (对数据库设计要求的原则约定)

     

    2 数据库环境说明

    (使用的数据库名称/版本的约定,如ORACLE 10g

     

    3 逻辑结构

    (建模工具的约定)

    (数据库命名,所起的作用、分布方式的约定)

     

    4 物理存储

    (数据量测量)

    (存储方式、每日数据占用磁盘空间(M)、保存方式、说明)

    (数据占用空间说明)

     

    5 数据备份和恢复

    (备份和恢复约定)

     

    第五步:系统安全设计

    1 数据传输安全性设计

    (如果有,则说明数据传输安全性采用方式和约定)

     

    2 应用系统安全性设计

    (如果有,则说明应用系统安全性采用方式和约定)

     

    3 数据存储安全性设计

    (如果有,则说明数据存储安全性采用方式和约定)

     

    第六步:系统部署

    (说明系统是如何给用户部署的)

     

     

    附录

    1 系统配置文件XML格式说明

    (系统配置参数的配置约定,可以使用例子来表达)

     

    2 报表接口规范及报表模板设计

           (如果使用了专用的报表控件,确定其接口约定,可以使用例子来表达)

     

    等等其它需要具体说的约定附录

     

     

    Ps:实在不知道该如何做的有趣点,只好按目录做填空题了

    展开全文
  • 首先我们需要设计一个良好的目录结构,如下: - web 目录放置<em>.html页面 - style 目录放置</em>.css文件,另外此目录中放置了less源文件 - src 目录放置了我们的所有*.js文件 - mock 内置的...
  • 文章目录一、设计Restful接口1、前端交互流程设计2、学习Restful接口二、SpringMVC整合spring1、SpringMVC理论2、整合配置SpringMVC框架三、实现秒杀相关Restfu接口四、基于bootstrap开发页面结构五、交互逻辑编程...

    如果完全跟着老师走,在编写seckill.js时会出现一些小问题,自己搜索改正了,可以正常运行。


    一、设计Restful接口

    前端交互设计—Restful—SpringMVC—bootstrap+jquery

    1、前端交互流程设计

    前端页面流程:列表页–>详情页–>登录–>写入cookie–>展示逻辑
    详情页流程逻辑:获取标准系统时间–>时间判断,开始时间,结束时间–>秒杀结束/倒计时/秒杀地址–>执行秒杀–>结果

    2、学习Restful接口

    一种优雅的URI表达方式,是资源的状态和转改转移。
    Restful规范:GET查询操作、POST添加/修改操作、PUT修改操作、DELETE删除操作。
    URL设计:/模块/资源/{标识}/集合1/…
    秒杀API的URL设计:

    • GET /seckill/list 秒杀列表
    • GET /seckill/{id}/detail 详情页
    • GET /seckill/time/now 系统时间
    • POST /seckill/{id}/exposer 暴露秒杀
    • POST /seckill/{id}/{md5}/execution 执行秒杀

    二、SpringMVC整合spring

    1、SpringMVC理论

    在这里插入图片描述

    • HTTP请求地址映射原理:
      HTTP请求–>Servlet容器(SpringMVC HandlerMapping–>Handler处理方法)
    • 注解映射技巧:
      @RequestMapping注解:支持标准的URL;Ant风格URL(即?和**等字符);带{xxx}占位符的URL。
    • 请求方法细节处理:
      请求参数绑定、请求方式限制、请求转发和重定向、数据模型赋值、返回json数据、cookie访问。

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    2、整合配置SpringMVC框架

    在web.xml中配置DispatcherServlet:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
    
        <!--maven创建的项目中的Servlet版本不合适,需要修改-->
        <!--配置DispatcherServlet-->
        <servlet>
            <servlet-name>seckill-dispatcher</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!--配置SpringMVC需要加载的配置文件
                spring-dao.xml,spring-service.xml,spring-web.xml
                Mybatis -> spring -> springmvc
                -->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:spring/spring-*.xml</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>seckill-dispatcher</servlet-name>
            <!--默认匹配所有的请求-->
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>
    

    新增spring-web.xml配置SpringMVC:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
        <!--配置SpringMVC-->
        <!--1:开启SpringMVC注解模式-->
        <!--简化配置:
            (1)自动注册DefaultAnnotationHandlerMapping,AnnotationMethodHandlerAdapter
            (2)提供一系列:数据绑定,数字和日期的format @NumberFormat,@DataTimeFormat
                 xml,json默认读写支持。
        -->
        <mvc:annotation-driven/>
        <!--2:servlet-mapping 映射路径:"/"-->
        <!--静态资源默认servlet配置
            (1)加入对静态资源的处理:js,gif,png
            (2)允许使用"/"做整体映射
        -->
        <mvc:default-servlet-handler/>
        
        <!--3:配置jsp 显示ViewResolver-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
        
        <!--4:扫描web相关的bean-->
        <context:component-scan base-package="org.luyangsiyi.seckill.web"/>
    </beans>
    

    三、实现秒杀相关的Restfu接口

    web/SeckillController.java

    package org.luyangsiyi.seckill.web;
    
    import org.luyangsiyi.seckill.dto.Exposer;
    import org.luyangsiyi.seckill.dto.SeckillExecution;
    import org.luyangsiyi.seckill.dto.SeckillResult;
    import org.luyangsiyi.seckill.entity.Seckill;
    import org.luyangsiyi.seckill.enums.SeckillStatEnum;
    import org.luyangsiyi.seckill.exception.RepeatKillException;
    import org.luyangsiyi.seckill.exception.SeckillClosedException;
    import org.luyangsiyi.seckill.exception.SeckillException;
    import org.luyangsiyi.seckill.service.SeckillService;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.Date;
    import java.util.List;
    
    /**
     * Created by luyangsiyi on 2020/2/23
     */
    @Controller
    @RequestMapping("/seckill") //url:/模块/资源/{id}/细分
    public class SeckillController {
        private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
        @Autowired
        private SeckillService seckillService;
    
        @RequestMapping(value = "/list", method = RequestMethod.GET)
        public String list(Model model){
            //获取列表页
            List<Seckill> seckills = seckillService.getSeckillList();
            model.addAttribute("list",seckills);
            //list.jsp + model = ModelAndView
            return "list";///WEB-INF/jsp/list.jsp
        }
    
        @RequestMapping(value = "/{seckillId}/detail",method = RequestMethod.GET)
        public String detail(@PathVariable("seckillId") Long seckillId, Model model){
            if(seckillId== null){
                return "redirect:/seckill/list";
            }
            Seckill seckill = seckillService.getById(seckillId);
            if(seckill == null){
                return "forward:/seckill/list";
            }
            model.addAttribute("seckill",seckill);
            return "detail";
        }
    
        //ajax json
        @RequestMapping(value = "/{seckillId}/exposer",
                method = RequestMethod.POST,
                produces = {"application/json;charset=UTF-8"})
        @ResponseBody //告知返回类型的json
        public SeckillResult<Exposer> exposer(@PathVariable("seckillId") Long seckillId){
            SeckillResult<Exposer> result;
            try{
                Exposer exposer = seckillService.exportSeckillUrl(seckillId);
                result = new SeckillResult<Exposer>(true,exposer);
            } catch (Exception e){
                logger.error(e.getMessage(),e);
                result = new SeckillResult<Exposer>(false,e.getMessage());
            }
            return result;
        }
    
        @RequestMapping(value = "/{seckillId}/{md5}/execution",
                    method = RequestMethod.POST,
                produces = {"application/json;charset=UTF-8"})
        @ResponseBody
        public SeckillResult<SeckillExecution> execute(@PathVariable("seckillId") Long seckillId,
                                                        @PathVariable("md5") String md5,
                                                        @CookieValue(value = "killPhone",required = false) Long phone){
            if(phone == null){
                return new SeckillResult<SeckillExecution>(false,"未注册");
            }
            SeckillResult<SeckillExecution> result;
            try{
                SeckillExecution execution = seckillService.executeSeckill(seckillId,phone,md5);
                return new SeckillResult<SeckillExecution>(true,execution);
            } catch(RepeatKillException e1){
                SeckillExecution seckillExecution = new SeckillExecution(seckillId, SeckillStatEnum.REPEAT_KILL);
                return new SeckillResult<SeckillExecution>(true,seckillExecution);
            } catch (SeckillClosedException e2) {
                SeckillExecution seckillExecution = new SeckillExecution(seckillId, SeckillStatEnum.END);
                return new SeckillResult<SeckillExecution>(true,seckillExecution);
            } catch (Exception e){
                logger.error(e.getMessage(),e);
                SeckillExecution seckillExecution = new SeckillExecution(seckillId, SeckillStatEnum.INNER_ERROR);
                return new SeckillResult<SeckillExecution>(true,seckillExecution);
            }
        }
    
        @RequestMapping(value = "/time/now", method = RequestMethod.GET)
        @ResponseBody
        public SeckillResult<Long> time(){
            Date now = new Date();
            return new SeckillResult<Long>(true,now.getTime());
        }
    }
    

    需要用到的dto/SeckillResult.java类:

    package org.luyangsiyi.seckill.dto;
    
    /**
     * 所有ajax请求返回类型:封装jsonn结果
     * Created by luyangsiyi on 2020/2/23
     */
    public class SeckillResult<T> {
    
        private boolean success;
    
        private T data;
    
        private String error;
    
        public SeckillResult(boolean success, T data) {
            this.success = success;
            this.data = data;
        }
    
        public SeckillResult(boolean success, String error) {
            this.success = success;
            this.error = error;
        }
    
        public boolean isSuccess() {
            return success;
        }
    
        public void setSuccess(boolean success) {
            this.success = success;
        }
    
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    
        public String getError() {
            return error;
        }
    
        public void setError(String error) {
            this.error = error;
        }
    }
    

    四、基于bootstrap开发页面结构

    在WEB-INF/jsp下基于bootstrap框架编写list.jsp和detail.jsp,并将共同的头部head.jsp和标签tag.jsp存在WEB-INF/jsp/common文件夹下:
    list.jsp

    <%--
      Created by IntelliJ IDEA.
      User: luyangsiyi
      Date: 2020/2/23
      Time: 7:26 下午
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <!--引入jstl-->
    <%@include file="common/tag.jsp"%>
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <title>秒杀列表页</title>
        <%@ include file="common/head.jsp"%>
    </head>
    <body>
        <!--页面显示部分-->
        <div class="container">
            <div class="panel panel-default">
                <div class="panel-heading text-center">
                    <h2>秒杀列表</h2>
                </div>
                <div class="panel-body">
                    <table class="table table-hover">
                        <thread>
                            <tr>
                                <th>名称</th>
                                <th>库存</th>
                                <th>开始时间</th>
                                <th>结束时间</th>
                                <th>创建时间</th>
                                <th>详情页</th>
                            </tr>
                        </thread>
                        <tbody>
                            <c:forEach var="sk" items="${list}">
                                <tr>
                                    <td>${sk.name}</td>
                                    <td>${sk.number}</td>
                                    <td>
                                        <fmt:formatDate value="${sk.startTime}" pattern="yyyy-MM-dd HH:mm:ss"/>
                                    </td>
                                    <td>
                                        <fmt:formatDate value="${sk.endTime}" pattern="yyyy-MM-dd HH:mm:ss"/>
                                    </td>
                                    <td>
                                        <fmt:formatDate value="${sk.createTime}" pattern="yyyy-MM-dd HH:mm:ss"/>
                                    </td>
                                    <td>
                                        <a class="btn btn-info" href="/seckill/${sk.seckillId}/detail" target="_blank">link</a>
                                    </td>
                                </tr>
                            </c:forEach>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    
    
    </body>
    <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
    <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
    <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
    </html>
    

    detail.jsp(这个页面没有完全编写完成,之后会修改)

    <%--
      Created by IntelliJ IDEA.
      User: luyangsiyi
      Date: 2020/2/23
      Time: 7:26 下午
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <title>秒杀详情页</title>
        <%@ include file="common/head.jsp"%>
    </head>
    <body>
        <div class="container">
            <div class="panel panel-default text-center">
                <div class="panel-heading">${seckill.name}</div>
                <div class="panel-body">
    
                </div>
            </div>
        </div>
    
    
    </body>
    <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
    <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
    <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
    </html>
    

    head.jsp

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <!-- Bootstrap -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- HTML5 shim 和 Respond.js 是为了让 IE8 支持 HTML5 元素和媒体查询(media queries)功能 -->
    <!-- 警告:通过 file:// 协议(就是直接将 html 页面拖拽到浏览器中)访问页面时 Respond.js 不起作用 -->
    <!--[if lt IE 9]>
    <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
    <![endif]-->
    

    tag.jsp

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
    

    五、交互逻辑编程

    1、修改detail.jsp添加登录弹出层

    <%@page contentType="text/html; charset=UTF-8" language="java" %>
    <%@include file="common/tag.jsp" %>
    <!DOCTYPE html>
    <html>
    <head>
        <title>秒杀详情页</title>
        <%@include file="common/head.jsp" %>
    </head>
    <body>
        <div class="container">
            <div class="panel panel-default text-center">
                <div class="pannel-heading">
                    <h1>${seckill.name}</h1>
                </div>
    
                <div class="panel-body">
                    <h2 class="text-danger">
                        <%--显示time图标--%>
                        <span class="glyphicon glyphicon-time"></span>
                        <%--展示倒计时--%>
                        <span class="glyphicon" id="seckill-box"></span>
                    </h2>
                </div>
            </div>
        </div>
        <%--登录弹出层 输入电话--%>
        <div id="killPhoneModal" class="modal fade">
            <!--如果不加这行,那么运行后modal会出现蒙层无法点击!-->
            <div class="modal-backdrop fade in">
                <style>.modal-backdrop{z-index:0;}</style>
            </div>
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h3 class="modal-title text-center">
                            <span class="glyphicon glyphicon-phone"></span>秒杀电话:
                        </h3>
                    </div>
                    <div class="modal-body">
                        <div class="row">
                            <div class="col-xs-8 col-xs-offset-2">
                                <input type="text" name="killPhone" id="killPhoneKey"
                                       placeholder="填写手机号^o^" class="form-control">
                            </div>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <%--验证信息--%>
                        <span id="killPhoneMessage" class="glyphicon"> </span>
                        <button type="button" id="killPhoneBtn" class="btn btn-success">
                            <span class="glyphicon glyphicon-phone"></span>
                            Submit
                        </button>
                    </div>
    
                </div>
            </div>
        </div>
    </body>
    <%--jQery文件,务必在bootstrap.min.js之前引入--%>
    <script src="http://apps.bdimg.com/libs/jquery/2.0.0/jquery.min.js"></script>
    <script src="http://apps.bdimg.com/libs/bootstrap/3.3.0/js/bootstrap.min.js"></script>
    <%--使用CDN 获取公共js http://www.bootcdn.cn/--%>
    <%--jQuery Cookie操作插件--%>
    <script src="http://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
    <%--jQuery countDown倒计时插件--%>
    <script src="http://cdn.bootcss.com/jquery.countdown/2.1.0/jquery.countdown.min.js"></script>
    
    <script src="/resources/script/seckill.js" type="text/javascript"></script>
    
    <script type="text/javascript">
        $(function () {
            //使用EL表达式传入参数
            seckill.detail.init({
                seckillId:${seckill.seckillId},
                startTime:${seckill.startTime.time},//毫秒
                endTime:${seckill.endTime.time}
            });
        })
    </script>
    </html>
    

    注意:如果出现modal灰色(即蒙层,无法点击)的时候,需要增加如下设置:

    <!--如果不加这行,那么运行后modal会出现蒙层无法点击!-->
    <div class="modal-backdrop fade in">
        <style>.modal-backdrop{z-index:0;}</style>
    </div>
    

    2、开始编写交互逻辑
    seckill.js

    //存放主要交互逻辑js代码
    //javascript 模块化
    var seckill = {
        //封装秒杀相关ajax的url,方便维护修改
        URL:{
            now : function () {
                return '/seckill/time/now';
            },
            exposer : function (seckillId) {
                return '/seckill/'+seckillId+'/exposer';
            },
            execution : function (seckillId, md5) {
                return '/seckill/'+seckillId+'/'+md5+'/execution';
            }
        },
        handlerSeckillkill : function(seckillId,node){
            //处理秒杀逻辑
            node.hide()
                .html('<button class="btn btn-primary btn-lg" id="killBtn">开始秒杀</button>');//按钮
            $.post(seckill.URL.exposer(seckillId),{},function (result) {
                //在回调函数中,执行交互流程
                if(result && result['success']){
                    var exposer = result['data'];
                    if(exposer['exposed']){
                        //开启秒杀
                        //获取秒杀地址
                        var md5 = exposer['md5'];
                        var killUrl = seckill.URL.execution(seckillId,md5);
                        console.log("killUrl:"+killUrl);
                        //绑定一次点击事件
                        $('#killBtn').one('click',function () {
                            //执行秒杀请求的操作
                            //1:先禁用按钮
                            $(this).addClass('disabled');
                            //2:发送秒杀请求执行秒杀
                            $.post(killUrl,{},function (result) {
                                if(result && result['success']){
                                    var killResult = result['data'];
                                    var state = killResult['state'];
                                    var stateInfo = killResult['stateInfo'];
                                    //3:显示秒杀结果
                                    node.html('<span class="label label-success">'+stateInfo+'</span>');
                                } else {
    
                                }
                            });
                        });
                        node.show();
                    } else {
                        //未开启秒杀(客户端到达时间,而服务器端没有开始)
                        var now = exposer['now'];
                        var start = exposer['start'];
                        var end = exposer['end'];
                        //重新计算计时逻辑
                        seckill.countdownTime(seckillId,now,start,end);
                    }
                } else {
                    console.log('result:'+result);
                }
            })
    
        },
        //验证手机号
        validatePhone : function(phone){
            if(phone && phone.length == 11 && !isNaN(phone)) {
                return true;
            } else {
                return false;
            }
        },
        countdownTime : function(seckillId,nowTime,startTime,endTime){
            //时间的判断
            if(nowTime > endTime){
                var seckillBox = $('#seckill-box');
                //秒杀结束
                seckillBox.html('秒杀结束!');
            } else if(nowTime < startTime){
                //秒杀未开启,计时事件绑定
                var killTime = new Date(startTime+1000);//加1秒防止用户时间出现偏移
                $('#seckill-box').countdown(killTime,function (event) {//这边不能调用seckillBox因为不能被初始化
                    //时间格式
                   var format = event.strftime('秒杀倒计时: %D天 %H时 %M分 %S秒');
                   $(this).html(format);//同样因为不能被初始化,所以用$(this)
                }).on('finish.countdown',function () {//时间完成后回调事务
                    //获取秒杀地址,控制显示逻辑,执行秒杀
                    seckill.handlerSeckillkill(seckillId,seckillBox);
                });
            } else {
                //秒杀开始
                seckill.handlerSeckillkill(seckillId,$('#seckill-box'));
            }
        },
        //详情页秒杀逻辑
        detail:{
            //详情页初始化
            init : function (params) {
                //手机验证和登录,计时交互
                //规划我们的交互流程
                //在cookie中查找手机号
                var killPhone = $.cookie('killPhone');
                //验证手机号
                if(!seckill.validatePhone(killPhone)){
                    //绑定phone
                    //控制输出
                    var killPhoneModal = $('#killPhoneModal');
                    //显示弹出层
                    killPhoneModal.modal({
                        show:true,
                        backdrop:'static',//禁止位置关闭
                        keyboard:false//关闭键盘事件
                    });
                    $('#killPhoneBtn').click(function () {
                       var inputPhone = $('#killPhoneKey').val();
                       if(seckill.validatePhone(inputPhone)){
                           //电话写入cookie
                           $.cookie('killPhone',inputPhone,{expires:7,path:'/seckill'});
                           //刷新页面
                           window.location.reload();
                       } else {
                            $('#killPhoneMessage').hide().html('<label class="label label-danger">手机号错误!</label>').show(300);
                       }
                    });
                }
                //已经登录
                //计时交互
                var startTime = params['startTime'];
                var endTime = params['endTime'];
                var seckillId = params['seckillId'];
                //将SeckillController中的time()返回的结果放在result中
                $.get(seckill.URL.now(),{},function (result) {
                    if(result && result['success']){
                        var nowTime = result['data'];
                        //时间判断,抽取出来放在countdownTime()中
                        seckill.countdownTime(seckillId,nowTime,startTime,endTime);
                    } else {
                        console.log('result:'+result);
                    }
                });
            }
        }
    }
    

    六、测试结果

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 由Wiki、Folksonomy及Mashup所构成后Ajax化的Web 2.0世界中, 精心设计的信息架构显得格外重要。你该如何向众人展现大量信息,从而 使他们能迅速找到所需信息呢?这本经典之作将教导信息架构师、设计师 及...
  •  本书可作为高等院校“网页设计与开发”类课程教材,也可作为网站制作、Web程序设计培训教材,还可作为网页设计Web编程爱好者自学参考书。  本书特点  ●构思清晰,结构合理。  ●内容全面系统,语言简洁...
  • DataX WebDataX之上开发分布式数据同步工具,提供简单易用 操作界面,降低用户使用DataX学习成本,缩短任务配置时间,避免配置过程中出错。用户可通过页面选择数据源即可创建数据同步任务,RDBMS数据源可...
  • 本文列出了几款好用数据库管理工具(有些并非开源或免费),以供开发者们参考选择,做过开发小伙伴们都知道,实现一个需求,一般情况下都需要设计到数据库表结构的修改。那么我们怎么能保证项目多人开发,多个...

    什么是数据库版本管理?

    任何web软件和应用程序都需要强大的数据库管理工具,因此开发者选择一款合适的数据库管理工具尤为重要。本文列出了几款好用的数据库管理工具(有些并非开源或免费),以供开发者们参考选择,做过开发的小伙伴们都知道,实现一个需求时,一般情况下都需要设计到数据库表结构的修改。那么我们怎么能保证项目多人开发时,多个数据库环境(测试,生产环境)能够保持一致呢?在没有数据库版本管理工具之前,需要将数据库修改脚本拷贝到每个数据库环境进行执行。而有了数据库版本管理工具之后,程序在启动的时候就会根据实现定义好的规则来进行数据库脚本的执行。

    使用flyway

    使用环境

    #我自己用的是springboot项目,mysql数据库

    导入flayway和mysql依赖

    org.flywaydb    flyway-coremysql    mysql-connector-javaorg.springframework.boot    spring-boot-starter-jdbc

    创建数据库脚本目录

    在resources资源目录下创建db/migration目录。

    添加数据库脚本

    #脚本命名规则 V__.sql,P__.sql。V代表只执行一次,P代表可以执行多次#VERSION代表数据库脚本版本,NAME代表数据名称。#这里使用V1_test.sql,脚本内容如下所示。DROP TABLE IF EXISTS `role`;CREATE TABLE `role`  (  `id` int(11) NOT NULL,  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,  PRIMARY KEY (`id`) USING BTREE) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;INSERT INTO `role` VALUES (1, '1');

    properties文件配置

    #指定数据库脚本为UTF-8, flyway的配置有很多,有兴趣的小伙伴可以去看下spring.flyway.encoding=utf-8#如果原来的数据库不为空,则需要设置spring.flyway.baseline-on-migrate=true#设置数据库起始版本为0,默认为1。如果你写的sql脚本version小于等于起始版本则不会执行。spring.flyway.baseline-version=0#数据源配置spring.datasource.url=jdbc:mysql://127.0.0.1/test?useUnicode=true&characterEncoding=utf8&useSSL=falsespring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.username=rootspring.datasource.password=123456

    启动应用程序,查看控制台输出

    4a866aca164e50d730168237fe1bfc49.png

    数据库查看

    72e8725308dab77e963de5926f6404da.png

    此时flyway会默认添加一张记录数据库版本信息的表,每次启动时会根据version值判断是否需要执行sql。

    flyway是怎么执行的?

    #spring-boot-dependencies 导入了flyway,mysql依赖。#spring-boot-autoconfigure 中导入了FlywayAutoConfiguration自动配置类
    展开全文
  • C++网络爬虫项目

    2018-07-04 00:59:17
    项目的目录结构如下所示: WebCrawler/ ├── bin/ │ ├── WebCrawler │ ├── WebCrawler.cfg │ └── WebCrawler.scr ├── docs/ │ ├── 概要设计.pdfWEBCRAWLER 网络爬虫实训项目 11 │ └── ...
  • 2.4.4 解决打开文件可能遇到问题 2.5 写文件 2.5.1 fwrite()参数 2.5.2 文件格式 2.6 关闭文件 2.7 读文件 2.7.1 以只读模式打开文件:fopen() 2.7.2 知道何时读完文件:feof() 2.7.3 每次读取一行...
  • 音视频是一门很复杂技术,涉及概念、原理、理论非常多,很多初学者不学基础理论,而是直接做项目,往往会看到c/c++代码一头雾水,不知道代码到底是什么意思,这是为什么呢?   因为没有学习音视频...
  • windows 程序设计

    2011-07-24 21:16:30
    这些动态链接库是些具有.DLL或者有时是.EXE扩展名文件,Windows 98中通常位于\WINDOWS\SYSTEM子目录中,Windows NT中通常位于\WINNT\SYSTEM和\WINNT\SYSTEM32子目录中。 早期,Windows主要部分仅通过三个...
  • JAVA上百实例源码以及开源项目

    千次下载 热门讨论 2016-01-03 17:37:40
     用JAVA开发的一个小型的目录监视系统,系统会每5秒自动扫描一次需要监视的目录,可以用来监视目录中文件大小及文件增减数目的变化。 Java日期选择控件完整源代码 14个目标文件 内容索引:JAVA源码,系统相关,日历,...
  • Java目录监视器源程序 9个目标文件 内容索引:JAVA源码,综合应用,目录监视 用JAVA开发的一个小型的目录监视系统,系统会每5秒自动扫描一次需要监视的目录,可以用来监视目录中文件大小及文件增减数目的变化。...
  • 软件界面设计工具_3款合集

    千次下载 热门讨论 2010-06-29 03:52:47
    可以用命令行进行导出操作,这样就能让我写个脚本,从svn里checkout某个目录所有设计文件后,导出图片,打包后用邮件发到项目经理,工程师甚至客户那; 跨平台,Balsamiq Mokups是用Flex和Air实现,所以Mac...
  • 虽然Cassandra 本书完成仍然没有达到1.0发布版本,但已经被互联网领域很多巨头使用了生产系统之中,他们包括Facebook、Twitter、Cisco、Rackspace、Digg、Cloudkick、Reddit 等。  因为它非常出色技术...
  • 出于简洁性考虑,本书对原型设计过程进行了简化,但依旧由易到难完整地阐述了一个UX项目的要素,如定义商业和技术需求、建立用例和流程图、构建高(低)保真线框图、设计交互、编注说明、产出详细UX规格文档及追踪...
  • 项目目录结构 src ├─ App.vue ├─ assets 用来存放css文件和项目的一些图片 │ ├─ css │ │ ├─ base.css 设置项目基本样式 │ │ └─ normalize.css 使不同的浏览器渲染网页元素的时候形式更统一 │ └...
  • 本文内容是关于用CMS思想,设计web页面和数据库内容。其中web页面页面设计储存模板中,页面内容储存数据库中,我这里用数据库连接是数据库缓存池来缓存。这种方式设计网页能够适应大部分门户...
  • 组件设计之BEM法则

    2020-11-25 23:26:53
    我们的目录结构应该这样去组织 ;true" /> 代码可能这样去写 <pre><code> js // tabset app.directive('tabset', function(){ return { restrict:'E', templateUrl:'tab-set.html', ...
  • ASP.NET网页代码模型及生命周期

    热门讨论 2009-07-28 14:22:11
    创建Application,首先需要新建项目用于开发Web Application,单击菜单栏上【文件】按钮,下拉菜单中选择【新建项目】选项,弹出窗口中选择【ASP.NET应用程序】选项,如图4-5所示。 图4-5 创建ASP.NET应用...
  • 在项目目录中,可以运行: npm start 开发模式下运行应用程序。 打开浏览器中查看。 如果进行编辑,页面将重新加载。 您还将控制台中看到任何棉绒错误。 npm test 交互式监视模式下启动测试运行程序。 ...
  • 全书共分4个部分,第一部分介绍最基本概念、术语及建模原则,第二部分描述了关系数据模型和关系型DBMS,第三部分讨论数据库设计,第四部分主要描述数据库系统中使用物理文件结构和存取方法。书中涉及内容非常...
  • 当客户机第一次调用一个Stateful Session Bean ,容器必须立即服务器中创建一个新Bean实例,并关联到客户机上,以后此客户机调用Stateful Session Bean 方法容器会把调用分派到与此客户机相关联Bean实例...
  • asp.net知识库

    2015-06-18 08:45:45
    一完美的关于请求的目录不存在而需要url重写的解决方案! C#中实现MSN消息框的功能 XmlHttp实现无刷新三联动ListBox 鼠标放在一个连接上,会显示图片(类似tooltip) 使用microsoft.web.ui.webcontrols的TabStrip与...
  • CruiseYoung提供带有详细书签电子书籍目录 http://blog.csdn.net/fksec/article/details/7888251 数据库系统基础:高级篇(第5版)(讲述数据库系统原理经典教材) 基本信息 原书名: Fundamentals of Database ...
  • 该开源仓库的文章都是我个人原创,公众号发过的技术文章(干货)也会有相关的目录整理,很多知识点我还不停的总结和完善。点击关注【Java3y公众号】 及时获取最新文章 :sparkling_heart:我希望这个开源仓库: 能...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 186
精华内容 74
关键字:

在设计web项目的目录结构时