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

电信计费(一)

作者: 包佳奇 | 来源:发表于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时用的

相关文章

  • 电信计费(一)

    一.创建项目 2.导入Tomcat中的jar包 高亮选中项目->鼠标右键->Properties3.png3.在p...

  • 电信计费(二)

    一.增加资费图解分析 分析:完成此功能需要发送三个请求1.点击浏览器界面的增加按钮,访问路径为/toAddCost...

  • 电信计费(五)

    一.验证码匹配图解分析 分析:1.浏览器通过访问路径/toLogin.do访问服务器,服务器用MianServle...

  • 电信计费(四)

    一.异常处理 1.新建一个jsp页面起名为error,在代码中把location.href的路径做修改 2.在we...

  • 电信计费(三)

    一.登录功能图解分析 分析:1.浏览器输入/toLogin.do网址,进行访问服务器使用MainServlet中的...

  • 电信计费系统ETL开发

    本项目进行电信计费系统开发,基于ETL工具Informatica,SQL,数据库Oracle和PL/SQL进行开发...

  • 技术代码bug处理记录汇总(更新ing)

    自签名版本2改版本1的代码 安卓电信计费文件:关闭第三方支付 计费点名称时不时发生错误(名称不对) 华为测试1:无...

  • 2021-01-18计费出账工作的一点思考(一)

    电信运营商的计费出账是一件非常复杂要求又非常高的系统性的工作。在运营商内部负责处理计费出账工作的组织很长一段时间都...

  • 北京今天财富:电信运营商大数据变现关键技术环节

    传统的电信经营分析系统主要处理计费清单、客户业务 关系以及业务平台使用数据,采用文件批处理的方式进行数据仓库的ET...

  • 电信计费业务模型1.0学习笔记-总论分册

    概述 进入新公司,各方面都挺适应的,感恩公司能给予我一个发挥的平台,好好努力。 公司的业务是做电信计费支撑系统,这...

网友评论

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

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