SCPPO(二十二):读取配置文件---程序猿必不可少的技能

简介: SCPPO(二十二):读取配置文件---程序猿必不可少的技能

【前言】


   现在在做一个.Net项目,在做项目的时候用到了读取配置文件;无巧不成书,最近在自己学习Java,刚好也学到了读取配置文件这块儿,于是乎整理了整理读取配置文件的方式。


【那点事】


   一、我与配置文件相识之路


       1、记得第一次接触配置文件是在long long ago自己做的第一个项目机房收费系统中用到,当时用到的是从配置文件中读取连接数据库的相关信息,由于那个项目是自己的练手项目一直是用的本机的数据库,说实话当时也没有感受到它很大的用处;


       2、第一次感触到它的用处的时候是在考试系统维护的时候部署系统的时候(参考:那些年我们一起参加的活动:15年上半年考试维护过程中精彩小插曲),当时为了保障高可用,部署一套正式系统和备用系统,部署中的一个最重要的环节是修改配置文件中的数据库信息;


       3、参加工作后在项目中又真正体会到它的强大威力。


   二、为什么要从配置文件中读?


       1、刚在度娘上搜了一下,结果出来的都是解决配置文件错误的;看来配置文件的好处已经深入人心,已经成为程序员的共识了吧!


       2、不过个人觉得探讨一下它的好处还是蛮有必要滴!依据本人的工作经验,目前体会到两点好处:


         (1)灵活可配;


              ①不用配置文件,修改系统过程:修改源码—>编译—>部署;


              ②加入配置文件,修改系统过程:编辑配置文件保存即可;


         (2)统一管理;


              ①不用配置文件,大部分是在程序中直接将值写死,而这些值会在系统中好多地方用到,如果要更改,需要修改多处;


              ②加入配置文件,将其做为一个变量写入到配置文件中,需要修改时只需修改配置文件中一处即可。


       3、凡事有利必有弊,目前能想到一个使用配置文件后的弊端:将很多密码等机密的东西暴露出来,比如:拿.Net项目来说,在服务器上发布好系统后,假如黑客攻陷服务器,如果使用配置文件则黑客很容易拿到数据库的密码等一些机密信息,如果是不用配置文件,这些信息是写在程序中,发布的文件是Dll,黑客想拿到不是那么容易;如果有这个顾虑的读者可以参考小编另外一篇博文—《SCPPO:IIS配置文件节点加密》。      


       4、友情提示:以上均为个人一些想法,如果大家有什么更多的想法,欢迎大家在评论中拍砖。


    三、.Net & Java 读取配置文件的方式:


       1、.Net读取配置文件的方式:


         (1)配置文件的写法:



<configuration>
         <appSettings>
               <!--测试-->
               <add key="Test" value="myTest"/>
         </appSettings>
</configuration><span style="font-family:KaiTi_GB2312;font-size:18px;">            </span>

         (2)项目公共类中读取配置文件的类:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test.Common
{
    public class CommonConfigInfo
    {
        #region 从配置文件中读取Test节点-zhanghan-2016年10月5日
        /// <summary>
        /// 从配置文件中读取Test节点
        /// </summary>
        public static string Test
        {
            get
            {
                var Test = "myTest";
                if (!string.IsNullOrEmpty(System.Configuration.ConfigurationManager.AppSettings["Test"]))
                {
                    Test = System.Configuration.ConfigurationManager.AppSettings["Test"];
                }
                return Test;
            }
        }
    }
}


         (3)程序中使用使用该值:



using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Test.Common;
namespace Test.Web.Main.Controllers
{
     public class TestController : SessionsController
    {
        //测试从配置文件中读取节点-zhanghan-2016年10月5日
        public string mytest(){
            string test= CommonConfigInfo.Test;
            return test;
        }        
    }
}


       2、Java读取配置文件的方式(采用dom4j的方式):              



         (1)配置文件的写法:



<?xml version="1.0" encoding="UTF-8"?>
<config>
  <db-info>
  <driver-name>oracle.jdbc.driver.OracleDriver</driver-name>
  <url>jdbc:oracle:thin:@127.0.0.1:1521:ORCL</url>
  <user-name>zhanghan</user-name>
  <password>haha</password>
  </db-info>
</config>


         (2)为了方便操作将数据库连接的几个封装成一个类,并将ToString方法重写:



package com.test.util;
/**
 * Jdbc相关配置
 * 
 * @author zhanghan
 * 
 */
public class JdbcConfig {
  private String driverName;
  private String url;
  private String userName;
  private String password;
  public String getDriverName() {
  return driverName;
  }
  public void setDriverName(String driverName) {
  this.driverName = driverName;
  }
  public String getUrl() {
  return url;
  }
  public void setUrl(String url) {
  this.url = url;
  }
  public String getUserName() {
  return userName;
  }
  public void setUserName(String userName) {
  this.userName = userName;
  }
  public String getPassword() {
  return password;
  }
  public void setPassword(String password) {
  this.password = password;
  }
  @Override
  public String toString() {
  return this.getClass().getName() + "{driverName:" + driverName
    + ",url:" + url + ",userName:" + userName + "}";
  }
}



         (3)将dom4j文件放到WEB-INF目录下


         (4)利用dom4j方式读取配置文件中的值,并存放到JdbcConfig类中(其中应用到了单例模式,并且将懒汉式和饿汉式两种都写出来,具体单例模式小编会在以后博文中为大家详细分析):



package test.util;
import java.io.InputStream;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
 * 解析sys-config.xml文件
 * 
 * @author zhanghan
 * 
 */
public class XmlConfigReader {
  // 饿汉式(预先加载)
  // private static XmlConfigReader instance = new XmlConfigReader();
  //
  // private XmlConfigReader() {
  //
  // }
  //
  // public static XmlConfigReader getInstance() {
  // return instance;
  // }
  // 懒汉式(延迟加载)
  private static XmlConfigReader instance = null;
  private JdbcConfig jdbcConfig = new JdbcConfig();
  private XmlConfigReader() {
  SAXReader reader = new SAXReader();
  InputStream in = Thread.currentThread().getContextClassLoader()
    .getResourceAsStream("sys-config.xml");
  try {
    Document doc = reader.read(in);
    Element driverNameElt = (Element) doc
      .selectObject("/config/db-info/driver-name");
    Element urlElt = (Element) doc.selectObject("/config/db-info/url");
    Element userNameElt = (Element) doc
      .selectObject("/config/db-info/user-name");
    Element passwordElt = (Element) doc
      .selectObject("/config/db-info/password");
    // 向Jdbc中赋值
    jdbcConfig.setDriverName(driverNameElt.getStringValue());
    jdbcConfig.setUrl(urlElt.getStringValue());
    jdbcConfig.setUserName(userNameElt.getStringValue());
    jdbcConfig.setPassword(passwordElt.getStringValue());
  } catch (DocumentException e) {
    e.printStackTrace();
  }
  }
  public static synchronized XmlConfigReader getInstance() {
  if (instance == null) {
    instance = new XmlConfigReader();
  }
  return instance;
  }
  /**
  * 返回Jdbc的相关配置
  * 
  * @return
  */
  public JdbcConfig getJdbcConfig() {
  return jdbcConfig;
  }
}



         (5)程序中读取该值:



package com.test.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
 * 数据操作
 * 
 * @author zhanghan
 * 
 */
public class DbUtil {
  /**
  * 取得Connection
  * 
  * @return
  */
  public static Connection getConnection() {
  Connection conn = null;
  try {
    // 固定死的
    // Class.forName("oracle.jdbc.driver.OracleDriver.class");
    // String url = "jdbc:oracle:thin:@127.0.0.1:1521:ORCL";
    // String username = "drp";
    // String password = "drp";
    //
    // conn = DriverManager.getConnection(url, username, password);
    // 从配置文件中读取
    JdbcConfig jdbcConfig = XmlConfigReader.getInstance()
      .getJdbcConfig();
    Class.forName(jdbcConfig.getDriverName());
    conn = DriverManager.getConnection(jdbcConfig.getUrl(),
      jdbcConfig.getUserName(), jdbcConfig.getPassword());
  } catch (ClassNotFoundException e) {
    e.printStackTrace();
  } catch (SQLException e) {
    e.printStackTrace();
  }
  return conn;
  }
}



【总结】


    1、应用配置文件使得程序更加灵活可配,从而大大减少了运维人员的工作量;


    2、不同阶段对一块儿知识的理解是不同的,随着经历的越多对同一个知识块儿理解越来越深刻;


    3、多去思考,多去总结,知识体系会越来越完善。        


相关文章
|
3月前
|
Java API 数据格式
Spring Boot API参数读取秘籍大公开!6大神器助你秒变参数处理大师,让你的代码飞起来!
【8月更文挑战第4天】Spring Boot凭借其便捷的开发和配置特性,成为构建微服务的热门选择。高效处理HTTP请求参数至关重要。本文介绍六种核心方法:查询参数利用`@RequestParam`;路径变量采用`@PathVariable`;请求体通过`@RequestBody`自动绑定;表单数据借助`@ModelAttribute`或`@RequestParam`;请求头使用`@RequestHeader`;Cookie则依靠`@CookieValue`。每种方法针对不同场景,灵活运用可提升应用性能与用户体验。
64 9
|
SQL 数据挖掘 测试技术
软件测试|弄懂GROUP BY看这一篇文章就够了
软件测试|弄懂GROUP BY看这一篇文章就够了
99 0
|
11月前
|
测试技术
【测试平台系列】第一章 手撸压力机(十)-定义场景
上一章,咱们对http请求进行了一些优化,本章节我们将组成场景去运行。首先场景就是一连串的http接口的请求,我们使用list(列表)来组装成一个场景
【测试平台系列】第一章 手撸压力机(十)-定义场景
|
Java Kotlin
开心档-软件开发入门之​Kotlin 条件控制
开心档-软件开发入门之​Kotlin 条件控制
31 0
|
SQL JSON 机器人
pytest+yaml设计接口自动化框架过程记录(一步一步记录如何设计,完结撒花),源码提供,视频教程
pytest+yaml设计接口自动化框架过程记录(一步一步记录如何设计,完结撒花),源码提供,视频教程
|
Java Spring 容器
SpringIOC注入三种方式灵活运用(第十四课)
SpringIOC注入三种方式灵活运用(第十四课)
98 0
|
NoSQL Java Redis
【JavaP6大纲】SpringCould篇:如何限流?在工作中是怎么做的?说一下具体的实现?
【JavaP6大纲】SpringCould篇:如何限流?在工作中是怎么做的?说一下具体的实现?
|
XML Java 数据库连接
Spring框架:第一章:介绍和准备工作
Spring框架:第一章:介绍和准备工作
100 0
Spring框架:第一章:介绍和准备工作
|
存储 机器学习/深度学习 自然语言处理
软件测试前置基础知识(基本概念,DOS命令)
软件测试前置基础知识(基本概念,DOS命令)
|
Python
零基础学Python【二十三、图形化界面设计 】(基础一篇全,欢迎认领)(十二)
零基础学Python【二十三、图形化界面设计 】(基础一篇全,欢迎认领)(十二)
130 0
零基础学Python【二十三、图形化界面设计 】(基础一篇全,欢迎认领)(十二)