1. 程式人生 > >從零寫一個Java WEB框架(一)

從零寫一個Java WEB框架(一)

  • 該系列,其實是對《架構探險》這本書的實踐。本人想記錄自己的學習心得所寫下的。
  • 從一個簡單的Servlet專案開始起步。對每一層進行優化,然後形成一個輕量級的框架。
  • 每一篇,都是針對專案的不足點進行優化的。
  • 專案已放上github

專案的基本搭建。

一個非常基礎的Servlet專案。
image.png

基本功能是:
- 對資料表-客戶表進行資料處理。

部分程式碼講解

例如:客戶的資料獲取

Controller 層

/*
*  獲取客戶端的資料
* */
@WebServlet("/customer_show"
) public class CustomerShowServlet extends HttpServlet{ private static CustomerService customerService; static { customerService = new CustomerService(); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getParameter("method"
); if (method != null) { if ("getList".equals(method)) { List<Customer> customerList = customerService.getCustomerList(); PrintWriter writer = resp.getWriter(); System.out.println(customerList); writer.write(customerList.toString()); writer.flush(); writer.close(); } } } @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }

思路:
- 通過HttpServletRequest 獲取到路徑上的值,然後對比值,執行相應的Servlet方法。

server 層中的獲取所有客戶資訊的方法

 /*
     *  獲取客戶列表
     * */
    public List<Customer> getCustomerList() {
        Connection conn = null;

        try {
            List<Customer> list = new ArrayList<>();
            String sql = "select * from customer";
            conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
            PreparedStatement preparedStatement = conn.prepareStatement(sql);
            ResultSet resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                Customer customer = new Customer();
                customer.setId(resultSet.getLong("id"));
                customer.setName(resultSet.getString("name"));
                customer.setContact(resultSet.getString("contact"));
                customer.setTelephone(resultSet.getString("telephone"));
                customer.setEmail(resultSet.getString("email"));
                customer.setRemark(resultSet.getString("remark"));
                list.add(customer);

            }

            return list;
            }

思路:
- 從資料庫中獲取到資料後,將資料填寫到物件裡面

缺陷:
- 程式碼太過臃腫。本來獲取客戶列表資料就3步。1 查詢 2 資料賦值給新物件 3 將新物件存進集合。 在第二步 資料賦值給物件 程式碼靈活性不高,如果物件類有修改,這裡也將需要修改,耦合度高。所以需要賦值這一步需要封裝一下。

在CustomerService 層 載入資料庫

public class CustomerService {

    private static final String DRIVER;
    private static final String URL;
    private static final String USERNAME;
    private static final String PASSWORD;

    private static final Logger logger = LoggerFactory.getLogger(CustomerService.class);


    static{
        System.out.println("配置載入");
        Properties conf = PropsUtil.loadProps("config.properties");
        DRIVER = conf.getProperty("jdbc.driver");
        URL = conf.getProperty("jdbc.url");
        USERNAME = conf.getProperty("jdbc.username");
        PASSWORD = conf.getProperty("jdbc.password");

        //JDBC流程第一步 載入驅動
        try {
            Class.forName(DRIVER);
        } catch (ClassNotFoundException e) {
            logger.error("載入jdbc驅動失敗",e);
            e.printStackTrace();
        }
    }

思路:
- 利用靜態程式碼塊,載入JDBC驅動

缺陷:
- 把JDBC驅動載入解除安裝Service層,那麼每個Service類都需要載入一次JDBC驅動。所有應該提取出來,只需要載入一次就可以。

載入Properties檔案 工具類

 /*
    *  載入屬性檔案
    * */
    public static Properties loadProps(String fileName) {
        Properties props = null;
        InputStream is = null;

        //獲取fileName的InputStream

        try {
            is = PropsUtil.class.getClassLoader().getResourceAsStream(fileName);
            props = new Properties();
            props.load(is);
            return props;
        } catch (IOException e) {
            log.error("載入Properties錯誤",e);
            e.printStackTrace();

        }finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    log.error("流關閉失敗",e);
                    e.printStackTrace();
                }
            }
        }

        return null;

    }

訪問

URL: localhost:8080/customer_show?method=getList

結果:
image.png

總結

一個專案的基本結構已經是實現出來了。從前端訪問到返回資料。可以說現在是可以完成基本業務的。但是這個專案如果需要擴充套件,那需要修改的地方就會很多。所以,為了增加專案的可擴充套件性,將會對專案進行優化,主要方向是對程式碼進行封裝,降低耦合度。