Java单体应用 - 架构模式 - 04.实践练习

原文地址:http://www.work100.net/training/monolithic-architecture-test.html
更多教程:光束云 - 免费课程

实践练习

序号 文内章节 视频
1 构建项目结构
2 代码实现
3 网站实现
4 测试运行
5 总结

请参照如上章节导航进行阅读

1.构建项目结构

我们以用户登录功能进行演示 三层架构 + MVC架构 如何实现。

1.1.创建项目

打开 IDEA ,在前述章节 stage2 文件夹下创建文件夹 login-demo,如下图:

1.2.创建 POM 文件

创建文件夹后,在 login-demo 文件夹上 右击,然后 New - File,新建一个 pom.xml 文件,文件内容如下:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
   http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>net.work100.training.stage2</groupId>
    <artifactId>login-demo</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

    </properties>

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>
    </dependencies>

</project>

1.3.创建目录结构

接下来,在 login-demo 文件夹下创建如下目录结构:

目录 含义
src/main/java 源码
src/main/resources 资源文件
src/main/webapp 网站文件
src/test/java 测试源码

1.4.托管 POM 文件到 Maven

pom.xml 托管到 Maven,操作方式如下:

托管后,点击 刷新 重新导入所有 Maven 项目,结果如下:

1.5.创建包结构

在文件夹 src/main/java右击 - New - Package,包名为:net.work100.training.stage2.login.demo

然后创建我们的 三层 + MVC 包架构:

含义
dao 数据访问层
entity 实体类
service 服务层
web.controller Web控制器

2.代码实现

2.1.定义实体类

entity 包上 右击 - New - Java Class 创建名为 User 的类。

User.java 文件代码如下:

package net.work100.training.stage2.login.demo.entity;

import java.io.Serializable;

/**
 * <p>Title: User</p>
 * <p>Description: 用户表</p>
 *
 * @author liuxiaojun
 * @date 2020-02-09 10:43
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-09   liuxiaojun     初始创建
 * -----------------------------------------------
 */
public class User implements Serializable {
    private String userName;
    private String loginId;
    private String loginPwd;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getLoginId() {
        return loginId;
    }

    public void setLoginId(String loginId) {
        this.loginId = loginId;
    }

    public String getLoginPwd() {
        return loginPwd;
    }

    public void setLoginPwd(String loginPwd) {
        this.loginPwd = loginPwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", loginId='" + loginId + '\'' +
                '}';
    }
}

2.2.实现dao层

创建 UserDao 接口

在包 dao右击 - New - Java ClassKind 选择 Interface,接口命名为 UserDao

UserDao.java 代码如下:

package net.work100.training.stage2.login.demo.dao;

import net.work100.training.stage2.login.demo.entity.User;

/**
 * <p>Title: UserDao</p>
 * <p>Description: 用户数据访问</p>
 *
 * @author liuxiaojun
 * @date 2020-02-09 10:49
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-09   liuxiaojun     初始创建
 * -----------------------------------------------
 */
public interface UserDao {
    /**
     * 登录验证
     *
     * @param loginId  登录ID
     * @param loginPwd 登录密码
     * @return
     */
    User login(String loginId, String loginPwd);
}

接口实现 UserDaoImpl

在包dao右击 - New - Package,类包名称为 impl,然后在包impl右击 - New - Java Class,新建类 UserDaoImpl

UserDaoImpl.java 文件代码如下:

package net.work100.training.stage2.login.demo.dao.impl;

import net.work100.training.stage2.login.demo.dao.UserDao;
import net.work100.training.stage2.login.demo.entity.User;

/**
 * <p>Title: UserDaoImpl</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-02-09 11:04
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-09   liuxiaojun     初始创建
 * -----------------------------------------------
 */
public class UserDaoImpl implements UserDao {

    @Override
    public User login(String loginId, String loginPwd) {
        // 根据 loginId 查询出用户信息
        User user = getUserByLoginId(loginId);
        if (user!=null) {
            // 验证 loginPwd 是否正确(区分大小写)
            if(user.getLoginPwd().equals(loginPwd)){
                return user;
            }
        }
        return null;
    }

    private User getUserByLoginId(String loginId){
        // 模拟 DB 存在的用户数据
        User dbUser = new User();
        dbUser.setUserName("Xiaojun");
        dbUser.setLoginId("admin");
        dbUser.setLoginPwd("admin");

        // 判断是否存在 loginId 的用户(忽略大小写)
        if(dbUser.getLoginId().equalsIgnoreCase(loginId)){
            return dbUser;
        }
        return null;
    }
}

2.3.实现service层

创建 UserService 接口

在包 service右击 - New - Java ClassKind 选择 Interface,接口命名为 UserService

UserService.java 代码如下:

package net.work100.training.stage2.login.demo.service;

/**
 * <p>Title: UserService</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-02-09 11:20
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-09   liuxiaojun     初始创建
 * -----------------------------------------------
 */
public interface UserService {
    /**
     * 登录验证
     *
     * @param loginId  登录ID
     * @param loginPwd 登录密码
     * @return
     */
    boolean login(String loginId, String loginPwd);
}

接口实现 UserServiceImpl

在包 service右击 - New - Package,类包名称为 impl,然后在包impl右击 - New - Java Class,新建类 UserServiceImpl

UserServiceImpl.java 文件代码如下:

package net.work100.training.stage2.login.demo.service.impl;

import net.work100.training.stage2.login.demo.dao.UserDao;
import net.work100.training.stage2.login.demo.dao.impl.UserDaoImpl;
import net.work100.training.stage2.login.demo.service.UserService;

/**
 * <p>Title: UserServiceImpl</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-02-09 11:22
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-09   liuxiaojun     初始创建
 * -----------------------------------------------
 */
public class UserServiceImpl implements UserService {

    // 数据访问层的具体实现
    private UserDao userDao = new UserDaoImpl();

    @Override
    public boolean login(String loginId, String loginPwd) {
        return userDao.login(loginId, loginPwd) != null;
    }
}

2.4.实现Web控制器

在包 web.controller右击 - New - Java Class,新建一个 LoginController 控制器。

LoginController.java 代码如下:

package net.work100.training.stage2.login.demo.web.controller;

import net.work100.training.stage2.login.demo.service.UserService;
import net.work100.training.stage2.login.demo.service.impl.UserServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * <p>Title: LoginController</p>
 * <p>Description: 登录控制器</p>
 *
 * @author liuxiaojun
 * @date 2020-02-09 11:36
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-09   liuxiaojun     初始创建
 * -----------------------------------------------
 */
public class LoginController extends HttpServlet {

    private UserService userService = new UserServiceImpl();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String loginId = req.getParameter("loginId");
        String loginPwd = req.getParameter("loginPwd");

        boolean success = userService.login(loginId, loginPwd);

        // 登录失败
        if (!success) {
            req.getRequestDispatcher("/fail.jsp").forward(req, resp);
        }
        // 登录成功
        else {
            req.getRequestDispatcher("/success.jsp").forward(req, resp);
        }
    }
}

LoginController 需要扩展继承 HttpServlet,所以我们需要在 pom.xml 文件中引入依赖的类包 javax.servlet-api

3.网站实现

3.1.构建网站目录结构

目录 含义
WEB-INF/web.xml 网站配置文件
index.jsp 登录页
success.jsp 登录成功
fail.jsp 登录失败

3.2.网站配置文件

WEB-INF/web.xml 配置文件代码如下:

<?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">
   <display-name>login-demo</display-name>

   <servlet>
      <servlet-name>LoginController</servlet-name>
      <servlet-class>net.work100.training.stage2.login.demo.web.controller.LoginController</servlet-class>
   </servlet>
   <servlet-mapping>
      <servlet-name>LoginController</servlet-name>
      <url-pattern>/login</url-pattern>
   </servlet-mapping>
</web-app>

3.3.登录页

index.jsp 文件代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录</title>
</head>
<body>
<form action="/login" method="post">
    <input name="loginId" type="text" />
    <input name="loginPwd" type="password" />
    <input type="submit" value="登录" />
</form>
</body>
</html>

3.4.登录成功页

success.jsp 文件代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>成功</title>
</head>
<body>
登录成功
</body>
</html>

3.5.登录失败页

fail.jsp 文件代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>失败</title>
</head>
<body>
登录失败
</body>
</html>

4.测试运行

4.1.配置Tomcat

打开 Run/Debug Configurations,点击 + - Tomcat Server - Local ,然后点击 OK 确认

Tomcat-Server 命名 login-demo,选择安装好的 Application Server

切换到 Deployment 选项卡,添加 Artifact,有两种方式:

方式一

点击 + - Artifact

弹出画面中选择 login-demo:war exploded

方式二

右下角选择 Fix

弹出画面中选择 login-demo:war exploded

设置 Application context/,即为根目录:

4.2.运行

点击下图 运行 按钮:

运行成功后将打开浏览器,或者您手动打开浏览器,输入地址:

http://localhost:8080/

运行效果如下图:

表单输入以下错误的登录数据:

名称
用户名 admin
密码 123456

页面将转向 登录失败 页面,如下图:

表单输入以下正确的登录数据:

名称
用户名 admin
密码 admin

页面将转向 登录成功 页面,如下图:

5.总结

如上详细讲解了 三层 + MVC 架构的典型实现方式,课件将每个步骤都进行了截图,请认真阅读文档并实践练习。

通过练习做到深刻理解三层架构及MVC架构,同时熟练掌握 IntelliJ IDEA 构建 Maven 项目的详细步骤。

后续的章节将不再对通过 IntelliJ IDEA 构建 Maven 项目的步骤进行讲解,将主要以代码实现为讲解内容。



上一篇:访问者模式

原文地址:https://www.cnblogs.com/liuxiaojun/p/training-monolithic-architecture-test.html

时间: 2024-10-09 06:51:14

Java单体应用 - 架构模式 - 04.实践练习的相关文章

Java单体应用 - 架构模式 - 02.MVC架构

原文地址:http://www.work100.net/training/monolithic-architecture-mvc.html 更多教程:光束云 - 免费课程 MVC架构 序号 文内章节 视频 1 什么是MVC架构 2 MVC架构程序的工作流程 3 三层架构+MVC示意图 请参照如上章节导航进行阅读 1.什么是MVC架构 MVC,即 Model 模型.View 视图,及 Controller 控制器. View:视图,为用户提供使用界面,与用户直接进行交互. Model:模型,承载数

大型电商分布式网站架构设计与实践,Java分布式架构,Java事务分布式高并发-视频教程

15套java架构师.集群.高可用.高可扩 展.高性能.高并发.性能优化.Spring boot.Redis.ActiveMQ.Nginx.Mycat.Netty.Jvm大型分布 式项目实战视频教程 视频课程包含: 高级Java架构师包含:Spring boot.Spring  cloud.Dubbo.Redis.ActiveMQ.Nginx.Mycat. Spring.MongoDB.ZeroMQ.Git.Nosql.Jvm.Mecached.Netty.Nio.Mina.性能调优.高并发.

熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。

熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器.过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验. 1.说一说Servlet生命周期(非常重要) Servlet生命周期包括三部分: 初始化:Web容器加载servlet,调用init()方法 只执行一次 处理请求:当请求到达时,运行其service()方法.service()自动调用与请求相对应的doXXX

JAVA微服务架构视频教程

教程目录:┣━JAVA微服务架构视频教程┃ ┣━Java教程:第1章 微服务简介 4┃ ┃ ┣━Java教程:001构建单体应用┃ ┃ ┣━Java教程:002微服务解决复杂问题┃ ┃ ┣━Java教程:003微服务的优点┃ ┃ ┣━Java教程:004微服务的缺点┃ ┣━Java教程:第2章 Linux使用 19┃ ┃ ┣━Java教程:005Linux 简介┃ ┃ ┣━Java教程:006Linux 与 Windows 比较┃ ┃ ┣━Java教程:007安装 Linux┃ ┃ ┣━Java

Java单体应用 - 常用框架 - 05.综合实例(iot-admin)

原文地址:http://www.work100.net/training/monolithic-frameworks-example.html更多教程:光束云 - 免费课程 综合实例 序号 文内章节 视频 1 概述 - 2 创建项目 - 3 使用AdminLTE模板 - 4 创建登录页 - 5 登录功能实现 - 6 提升用户体验 - 7 实例源码 - 请参照如上章节导航进行阅读 1.概述 本节将把「Java单体应用」课程做一个阶段性的总结,通过一个综合的案例将所学知识完整实践一下. 我们后续阶段

mvp架构模式

今天是国庆节,祝大家节日快乐,愿祖国越发繁荣昌盛.假期程序员也不能偷懒,更新一些博文吧. 看到封面图片喜欢NBA的人可能很容易就想到了最有价值球员.但是此mvp非彼MVP,此mvp指的是现在Android开发中比较常见的一种软件架构模式.mvp架构模式是Google官方推荐的架构模式,特别是近年来的新项目,mvp+retrofit+rxjava+dragger2配合使用已经在引领程序界的潮流了,在github上可以轻易的搜到一大堆这样的开源项目.前端时间笔者也在公司的一个sdk上进行了尝试,在此

软件开发架构分析和架构模式一

架构分析: 架构分析工作主要从宏观上考虑一个软件系统应该如何组织.通常,在架构分析工作中,我们需要确定一些策略性的设计方针,原则和基本模式.在它们的指导下,我们可以高屋建瓴地分析软件系统的宏观结构,认识软件系统由哪些组件构成,了解组件之间的接口和协作关系.架构分析的结果对于后续的面向对象设计工作也是一种约束,有助于消除设计和实现过程中的随意性.因此,架构分析有时也被称为策略设计 组件指的是一组对象构成的,有固定接口的有机体,当设计者的观察视角不同,组件的规模不同或者组件内部的封装度程度不同时,这

大型分布式网站架构设计与实践

大型分布式网站架构设计与实践(一线工作经验总结,囊括大型分布式网站所需技术的全貌.架构设计的核心原理与典型案例.常见问题及解决方案,有细节.接地气/京东:大型分布式网站所需技术的全貌.架构设计的核心原理与典型案例.常见问题及解决方案) 陈康贤 著   ISBN 978-7-121-23885-7 2014年9月出版 定价:79.00元 460页 16开 编辑推荐 --作者一直奋战在阿里巴巴及淘宝网一线,书中所讲是其亲身经验的总结,显得更加实战和珍贵. --全面介绍大型分布式网站架构所涉及的技术细

微服务架构模式简介

转自 http://blog.jobbole.com/96948/ 在2014年,Sam Newman,Martin Fowler在ThoughtWorks的一位同事,出版了一本新书<Building Microservices>.该书描述了如何按照Microservice架构模式设计及搭建一个具有良好扩展性并可持续开发的系统.除此之外,该书还将基于该模式的系统演化流程与Continuous Delivery等当前甚为流行的开发流程结合在了一起,使得Microservice架构模式看起来非常具