美文网首页
电信计费(一)

电信计费(一)

作者: 包佳奇 | 来源:发表于2018-07-10 17:26 被阅读268次

    一.创建项目

    1.创建web项目,起名为netctoss 1.png
    2.png
    3.png

    2.导入Tomcat中的jar包

    • 高亮选中项目->鼠标右键->Properties


      3.png

      3.在pom.xml中导入相关jar包

      <!-- 数据库连接池 -->
      <dependency>
      <groupId>commons-dbcp</groupId>
      <artifactId>commons-dbcp</artifactId>
      <version>1.4</version>
      </dependency>
      <!-- 连接oracle数据库 -->
      <dependency>
      <groupId>com.jslsolucoes</groupId>
      <artifactId>ojdbc6</artifactId>
      <version>11.2.0.1.0</version>
      </dependency>
      <!-- JSTL标签 -->
      <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
      </dependency>
    

    二.资费查询的图解分析

    4.png

    分析:首先连接oracle数据库,然后查询数据库中cost的表的信息,然后通过servlet去查询资费,并转发到jsp(这里面规定访问路径为/findCost.do)

    三.查询功能

    1.在src/main/resource目录下创建db.properties配置文件,并书写相应的配置信息

    # db connection parameters
    driver=oracle.jdbc.driver.OracleDriver
    url=jdbc:oracle:thin:@localhost:1521:xe
    user=system
    pwd=oracle
    
    # datasource parameters
    initsize=1
    maxsize=2
    

    2.在src/main/java目录下创建util包,在包下创建DBUtil工具类,用来读取db.properties配置文件中的参数,并实现连接、失败、回滚的方法.
    注:这里要使用连接池对象

    package util;
    
    import java.io.IOException;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.Properties;
    
    import org.apache.commons.dbcp.BasicDataSource;
    
    public class DBUtil {
    
        //连接池对象-由DBCP提供
        private static BasicDataSource ds;
        
        static {
            Properties p = new Properties();
            try {
                p.load(DBUtil.class.getClassLoader()
                    .getResourceAsStream("db.properties"));
                //读取参数
                String driver = p.getProperty("driver");
                String url = p.getProperty("url");
                String user = p.getProperty("user");
                String pwd = p.getProperty("pwd");
                String initsize = p.getProperty("initsize");
                String maxsize = p.getProperty("maxsize");
                //创建连接池
                ds = new BasicDataSource();
                //设置参数
                //使用这个参数注册驱动
                ds.setDriverClassName(driver);
                //使用这3个参数创建连接
                ds.setUrl(url);
                ds.setUsername(user);
                ds.setPassword(pwd);
                //使用其他参数管理连接
                ds.setInitialSize(new Integer(initsize));
                ds.setMaxActive(new Integer(maxsize));
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException(
                    "加载db.properties失败", e);
            }
            
        }
        
        public static Connection getConnection() 
            throws SQLException {
            return ds.getConnection();
        }
        
        /**
         * 由连接池创建的连接,连接的close方法
         * 被连接池重写了,变为了归还连接的逻辑,
         * 即:连接池会将连接的状态设置为空闲,
         * 并清空连接中所包含的任何数据.
         */
        public static void close(Connection conn) {
            if(conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(
                        "归还连接失败", e);
                }
            }
        }
        
        
        public static void rollback(Connection conn) {
            if (conn != null) {
                try {
                    conn.rollback();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException("回滚失败",e);
                }
            }
        }
    }
    

    3.在src/main/java目录下创建entity实体类包,在包下创建Cost类,添加成员方法并生成setter和getter方法

    package entity;
    
    import java.io.Serializable;
    import java.sql.Timestamp;
    
    public class Cost implements Serializable {
      // 因为封装类型可以为null
      // 主键
      private Integer costId;
      private String name;
      // 基本时长
      private Integer baseDuration;
      // 基本费用
      private Double baseCost;
      // 单位费用
      private Double unitCost;
      // 状态(枚举): 0-开通;1-暂停;
      private String status;
      // 资费说明
      private String descr;
      // 创建时间
      private Timestamp creatime;
      // 开通时间
      private Timestamp startime;
      // 资费类型(枚举):1-包月;2-套餐;3-计时;
      private String costType;
    
      public Integer getCostId() {
          return costId;
      }
    
      public void setCostId(Integer costId) {
          this.costId = costId;
      }
    
      public String getName() {
          return name;
      }
    
      public void setName(String name) {
          this.name = name;
      }
    
      public Integer getBaseDuration() {
          return baseDuration;
      }
    
      public void setBaseDuration(Integer baseDuration) {
          this.baseDuration = baseDuration;
      }
    
      public Double getBaseCost() {
          return baseCost;
      }
    
      public void setBaseCost(Double baseCost) {
          this.baseCost = baseCost;
      }
    
      public Double getUnitCost() {
          return unitCost;
      }
    
      public void setUnitCost(Double unitCost) {
          this.unitCost = unitCost;
      }
    
      public String getStatus() {
          return status;
      }
    
      public void setStatus(String status) {
          this.status = status;
      }
    
      public String getDescr() {
          return descr;
      }
    
      public void setDescr(String descr) {
          this.descr = descr;
      }
    
      public Timestamp getCreatime() {
          return creatime;
      }
    
      public void setCreatime(Timestamp creatime) {
          this.creatime = creatime;
      }
    
      public Timestamp getStartime() {
          return startime;
      }
    
      public void setStartime(Timestamp startime) {
          this.startime = startime;
      }
    
      public String getCostType() {
          return costType;
      }
    
      public void setCostType(String costType) {
          this.costType = costType;
      }
    
    }
    

    4.在src/main/java目录下创建dao的包,在包下创建CostDao类,用来查找cost中的对象信息,并返回集合

    package dao;
    
    import java.io.Serializable;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.List;
    
    import entity.Cost;
    import util.DBUtil;
    
    public class CostDao implements Serializable {
    
        public List<Cost> findAll() {
            Connection conn = null;
            try {
                conn = DBUtil.getConnection();
                String sql = 
                    "select * from cost_bao "
                    + "order by cost_id";
                Statement smt = 
                    conn.createStatement();
                ResultSet rs = smt.executeQuery(sql);
                List<Cost> list = new ArrayList<Cost>();
                while(rs.next()) {
                    Cost c = new Cost();
                    c.setCostId(rs.getInt("cost_id"));
                    c.setName(rs.getString("name"));
                    c.setBaseDuration(rs.getInt("base_duration"));
                    c.setBaseCost(rs.getDouble("base_cost"));
                    c.setUnitCost(rs.getDouble("unit_cost"));
                    c.setStatus(rs.getString("status"));
                    c.setDescr(rs.getString("descr"));
                    c.setCreatime(rs.getTimestamp("creatime"));
                    c.setStartime(rs.getTimestamp("startime"));
                    c.setCostType(rs.getString("cost_type"));
                    list.add(c);
                }
                return list;
            } catch (SQLException e) {
                e.printStackTrace();
                throw new RuntimeException(
                    "查询资费失败", e);
            } finally {
                DBUtil.close(conn);
            }
        }
    }
    

    对于只执行一次的SQL语句选择Statement是最好的. 相反, 如果SQL语句被多次执行选用PreparedStatement是最好的.

    5.在src/main/java目录下创建web的包,在包下创建MainServlet类并继承HttpServlet和实现转发到jsp

    package web;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import dao.CostDao;
    import entity.Cost;
    
    public class MainServlet extends HttpServlet {
    
        @Override
        protected void service(
            HttpServletRequest req, 
            HttpServletResponse res) throws ServletException, IOException {
            //获取访问路径
            String path = req.getServletPath();
            //根据规范(图)处理路径
            if("/findCost.do".equals(path)) {
                findCost(req,res);
            } else {
                throw new RuntimeException("没有这个页面");
            }
        }
        
        //查询资费
        protected void findCost(
            HttpServletRequest req, 
            HttpServletResponse res) throws ServletException, IOException {
            //查询所有的资费
            CostDao dao = new CostDao();
            List<Cost> list = dao.findAll();
            //将请求转发到jsp
            req.setAttribute("costs", list);
            //当前:/netctoss/findCost.do
            //目标:/netctoss/WEB-INF/cost/find.jsp
            req.getRequestDispatcher(
                "WEB-INF/cost/find.jsp").forward(req, res);
        }
    }
    

    四种访问路径的区别:
    req.getContextPath()//获取项目名
    req.getServletPath()//获取访问路径
    req.getRequestURI()//获取绝对路径
    req.getRequestURL()//获取完整路径

    6.完成web.xml中的配置信息

      <servlet>
      <servlet-name>main</servlet-name>
      <servlet-class>web.MainServlet</servlet-class>
      </servlet>
      
      <servlet-mapping>
      <servlet-name>main</servlet-name>
      <url-pattern>*.do</url-pattern>
      </servlet-mapping>
    

    7.在src->main->webapp->WEB-INF下创建cost文件,并在cost文件下创建find.jsp文件,并且把之前写好的静态页(fee_list)代码粘贴到find.jsp文件中
    8.在src->main->webapp下把images和style资源导入进来,部署项目到tomcat服务器上,在网址上进行访问

    5.png
    9.资源不显示是因为导入资源路径有问题,那么需要在jsp中引入资源的路径把../去掉
    6.png
    10.导入Libraries->jstl->META_INF->c.tld标签
    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    

    11.使用EL表达式获取数据,使用JSTL对数据进行遍历

      <c:forEach items="${costs}" var="c">                
      <tr>
              <td>${c.costId}</td>
              <td><a href="fee_detail.html">${c.name}</a></td>
              <td>${c.baseDuration}</td>
              <td>${c.baseCost}</td>
              <td>${c.unitCost}</td>
              <td>${c.creatime}</td>
              <td>${c.startime}</td>
              <td>
                       <c:if test="${c.status==0}">开通</c:if>
                       <c:if test="${c.status==1}">暂停</c:if>
              </td>
              <td>                                
                       <input type="button" value="启用" class="btn_start" onclick="startFee();" />
                       <input type="button" value="修改" class="btn_modify" onclick="location.href='fee_modi.html';" />
                       <input type="button" value="删除" class="btn_delete" onclick="deleteFee();" />
              </td>
      </tr>
      </c:forEach> 
    
    7.png
    12.格式化jsp上显示的时间,如图所示,创建时间显示的数据带毫秒 8.png

    注:使用fmt.tld下的 formatDate

    <td> <fmt:formatDate value="${c.creatime}" pattern="yyyy-MM-dd HH:mm:ss"/> </td>
    

    四.问题解析

    1.在jsp上引用样式文件和图片为什么没写../?

    浏览器在加载网页时获取图片,这个是加载的网页和图片的相对关系,加载的网页的访问路径是/netctoss/findCost.do(浏览器不知道这件事),图片的访问路径/netctoss/images/logo.png,故相对路径是不加../的

    2.为什么要将jsp放在WEB-INF下?

    WEB-INF是具有保护功能的,它可以保护内部的资源,避免该资源被直接访问,需要通过转发才能访问.将jsp放到WEB-INF下,就是要保护它,避免它被直接访问,从而丢掉数据来源,导致报错

    3.为什么要将静态资源放在webapp下 ?

    静态资源是浏览器直接访问的,不存在转发,所以直接放在webapp下就可以,不需要放在WEB-INF里面

    4.为什么jsp上有2处声明了编码?

    <%@page pageEncoding="utf-8"%>
    

    pageEncoding是给服务器翻译jsp时用的

    <meta charset="utf-8">
    

    meta中的编码是给浏览器加载HTML时用的

    相关文章

      网友评论

          本文标题:电信计费(一)

          本文链接:https://www.haomeiwen.com/subject/lobfpftx.html