【Maven基础】单一架构案例(四)

该博客详细介绍了如何实现一个奏折列表显示及详情查看的业务功能。包括WorkServlet、MemorialsService和MemorialsDao的创建与方法实现,以及页面样式和登录信息的展示。用户登录后可以查看奏折列表,点击奏折进入详情页,详情页中可进行批复操作,奏折状态会随查看与批复自动更新。

第七节 业务功能:显示奏折列表

1、流程图

在这里插入图片描述

2、创建组件

2.1、创建 WorkServlet

2.1.1、创建 Java 类

刚开始是空的,还没有写方法:

在这里插入图片描述

public class WorkServlet extends ModelBaseServlet {
    
    private MemorialsService memorialsService = new MemorialsServiceImpl();
    
}
2.1.2、注册
<servlet>
    <servlet-name>workServlet</servlet-name>
    <servlet-class>com.atguigu.imperial.court.servlet.module.WorkServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>workServlet</servlet-name>
    <url-pattern>/work</url-pattern>
</servlet-mapping>

2.2、创建 MemorialsService

2.2.1、接口

在这里插入图片描述

2.2.2、实现类

在这里插入图片描述

public class MemorialsServiceImpl implements MemorialsService {

    private MemorialsDao memorialsDao = new MemorialsDaoImpl();

}

3、WorkServlet 方法

在这里插入图片描述

protected void showMemorialsDigestList(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    // 1、调用 Service 方法查询数据
    List<Memorials> memorialsList = memorialsService.getAllMemorialsDigest();

    // 2、将查询得到的数据存入请求域
    request.setAttribute("memorialsList", memorialsList);

    // 3、渲染视图
    String templateName = "memorials-list";
    processTemplate(templateName, request, response);
}

4、MemorialsService 方法

在这里插入图片描述

@Override
public List<Memorials> getAllMemorialsDigest() {
    return memorialsDao.selectAllMemorialsDigest();
}

5、MemorialsDao 方法

在这里插入图片描述

@Override
public List<Memorials> selectAllMemorialsDigest() {

    String sql = "select memorials_id memorialsId,\n" +
            "       memorials_title memorialsTitle,\n" +
            "       concat(left(memorials_content, 10), \"...\") memorialsContentDigest,\n" +
            "       emp_name memorialsEmpName,\n" +
            "       memorials_create_time memorialsCreateTime,\n" +
            "       memorials_status memorialsStatus\n" +
            "from t_memorials m left join  t_emp e on m.memorials_emp=e.emp_id;";

    return getBeanList(sql, Memorials.class);
}

6、页面显示

在这里插入图片描述

6.1、页面上的样式声明

<style type="text/css">
    table {
        border-collapse: collapse;
        margin: 0px auto 0px auto;
    }

    table th, td {
        border: 1px solid black;
        text-align: center;
    }

    div {
        text-align: right;
    }
</style>

6.2、用户登录信息部分

<!-- 登录信息部分 -->
<div>
    <span th:if="${session.loginInfo.empPosition == 'emperor'}">恭请皇上圣安</span>
    <span th:if="${session.loginInfo.empPosition == 'minister'}"><span th:text="${session.loginInfo.empName}">XXX</span>大人请安</span>
    <a th:href="@{/auth?method=logout}">退朝</a>
</div>

6.3、数据展示信息部分

<!-- 数据显示部分 -->
<table>
    <thead>
        <tr>
            <th>奏折标题</th>
            <th>内容摘要</th>
            <th>上疏大臣</th>
            <th>上疏时间</th>
            <th>奏折状态</th>
            <th>奏折详情</th>
        </tr>
    </thead>
    <tbody th:if="${#lists.isEmpty(memorialsList)}">
        <tr>
            <td colspan="6">没有人上过折子</td>
        </tr>
    </tbody>
    <tbody th:if="${not #lists.isEmpty(memorialsList)}">
        <tr th:each="memorials : ${memorialsList}">
            <td th:switch="${memorials.memorialsStatus}">
                <span th:text="${memorials.memorialsTitle}" th:case="0" style="color: red;">奏折标题</span>
                <span th:text="${memorials.memorialsTitle}" th:case="1" style="color: blue;">奏折标题</span>
                <span th:text="${memorials.memorialsTitle}" th:case="2">奏折标题</span>
            </td>
            <td th:switch="${memorials.memorialsStatus}">
                <span th:text="${memorials.memorialsContentDigest}" th:case="0" style="color: red;">内容摘要</span>
                <span th:text="${memorials.memorialsContentDigest}" th:case="1" style="color: blue;">内容摘要</span>
                <span th:text="${memorials.memorialsContentDigest}" th:case="2">内容摘要</span>
            </td>
            <td th:switch="${memorials.memorialsStatus}">
                <span th:text="${memorials.memorialsEmpName}" th:case="0" style="color: red;">上疏大臣</span>
                <span th:text="${memorials.memorialsEmpName}" th:case="1" style="color: blue;">上疏大臣</span>
                <span th:text="${memorials.memorialsEmpName}" th:case="2">上疏大臣</span>
            </td>
            <td th:switch="${memorials.memorialsStatus}">
                <span th:text="${memorials.memorialsCreateTime}" th:case="0" style="color: red;">上疏时间</span>
                <span th:text="${memorials.memorialsCreateTime}" th:case="1" style="color: blue;">上疏时间</span>
                <span th:text="${memorials.memorialsCreateTime}" th:case="2">上疏时间</span>
            </td>
            <td th:switch="${memorials.memorialsStatus}">
                <span th:case="0" style="color: red;">未读</span>
                <span th:case="1" style="color: blue;">已读</span>
                <span th:case="2">已批示</span>
            </td>

            <td>
                <a th:href="@{/work?method=detail}">奏折详情</a>
            </td>
        </tr>
    </tbody>
</table>

7、和登录成功对接

在这里插入图片描述

protected void login(
        HttpServletRequest request,
        HttpServletResponse response)
        throws ServletException, IOException {

    try {
        // 1、获取请求参数
        String loginAccount = request.getParameter("loginAccount");
        String loginPassword = request.getParameter("loginPassword");

        // 2、调用 EmpService 方法执行登录逻辑
        Emp emp = empService.getEmpByLoginAccount(loginAccount, loginPassword);

        // 3、通过 request 获取 HttpSession 对象
        HttpSession session = request.getSession();

        // 4、将查询到的 Emp 对象存入 Session 域
        session.setAttribute(ImperialCourtConst.LOGIN_EMP_ATTR_NAME, emp);

        // 5、前往指定页面视图
        // 前往临时页面
        // String templateName = "temp";
        // processTemplate(templateName, request, response);

        // 前往正式的目标地址
        response.sendRedirect(request.getContextPath() + "/work?method=showMemorialsDigestList");

    } catch (Exception e) {
        e.printStackTrace();

        // 6、判断此处捕获到的异常是否是登录失败异常
        if (e instanceof LoginFailedException) {
            // 7、如果是登录失败异常则跳转回登录页面
            // ①将异常信息存入请求域
            request.setAttribute("message", e.getMessage());

            // ②处理视图:index
            processTemplate("index", request, response);

        }else {
            // 8、如果不是登录异常则封装为运行时异常继续抛出
            throw new RuntimeException(e);

        }

    }

}

第八节 业务功能:显示奏折详情

1、流程图

在这里插入图片描述

2、调整奏折列表页面的超链接

<a th:href="@{/work(method='showMemorialsDetail',memorialsId=${memorials.memorialsId})}">奏折详情</a>

3、WorkServlet 方法

在这里插入图片描述

protected void showMemorialsDetail(
        HttpServletRequest request,
        HttpServletResponse response)
        throws ServletException, IOException {

    // 1、从请求参数读取 memorialsId
    String memorialsId = request.getParameter("memorialsId");

    // 2、根据 memorialsId 从 Service 中查询 Memorials 对象
    Memorials memorials = memorialsService.getMemorialsDetailById(memorialsId);

    // 3、将 Memorials 对象存入请求域
    request.setAttribute("memorials", memorials);

    // 4、解析渲染视图
    String templateName = "memorials_detail";
    processTemplate(templateName, request, response);

}

4、MemorialsService 方法

在这里插入图片描述

    @Override
    public Memorials getMemorialsDetailById(String memorialsId) {

        return memorialsDao.selectMemorialsById(memorialsId);

    }

5、MemorialsDao 方法

在这里插入图片描述

@Override
public Memorials selectMemorialsById(String memorialsId) {

    String sql = "select memorials_id memorialsId,\n" +
            "       memorials_title memorialsTitle,\n" +
            "       memorials_content memorialsContent,\n" +
            "       emp_name memorialsEmpName,\n" +
            "       memorials_create_time memorialsCreateTime,\n" +
            "       memorials_status memorialsStatus,\n" +
            "       feedback_time feedbackTime,\n" +
            "       feedback_content feedbackContent\n" +
            "from t_memorials m left join  t_emp e on m.memorials_emp=e.emp_id " +
            "where memorials_id=?;";

    return getSingleBean(sql, Memorials.class, memorialsId);
}

6、详情页

在这里插入图片描述

<!-- 登录信息部分 -->
<div>
    <span th:if="${session.loginInfo.empPosition == 'emperor'}">恭请皇上圣安</span>
    <span th:if="${session.loginInfo.empPosition == 'minister'}"><span th:text="${session.loginInfo.empName}">XXX</span>大人请安</span>
    <a th:href="@{/auth?method=logout}">退朝</a>
</div>

<table>
    <tr>
        <td>奏折标题</td>
        <td th:text="${memorials.memorialsTitle}"></td>
    </tr>
    <tr>
        <td>上疏大臣</td>
        <td th:text="${memorials.memorialsEmpName}"></td>
    </tr>
    <tr>
        <td>上疏时间</td>
        <td th:text="${memorials.memorialsCreateTime}"></td>
    </tr>
    <tr>
        <td>奏折内容</td>
        <td th:text="${memorials.memorialsContent}"></td>
    </tr>
    <tr th:if="${memorials.memorialsStatus == 2}">
        <td>批复时间</td>
        <td th:text="${memorials.feedbackTime}"></td>
    </tr>
    <tr th:if="${memorials.memorialsStatus == 2}">
        <td>批复时间</td>
        <td th:text="${memorials.feedbackContent}"></td>
    </tr>
</table>

<div th:if="${memorials.memorialsStatus != 2}">
    <form th:action="@{/work}" method="post">

        <input type="hidden" name="method" value="feedBack" />
        <input type="hidden" name="memorialsId" th:value="${memorials.memorialsId}"/>

        <textarea name="feedbackContent"></textarea>

        <button type="submit">御批</button>

    </form>
</div>

<a th:href="@{/work?method=showMemorialsDigestList}">返回列表</a>

7、更新状态

7.1、业务逻辑规则

一份未读奏折,点击查看后,需要从未读变成已读。

7.2、WorkServlet 方法

在这里插入图片描述

增加判断:

protected void showMemorialsDetail(
        HttpServletRequest request,
        HttpServletResponse response)
        throws ServletException, IOException {

    // 1、从请求参数读取 memorialsId
    String memorialsId = request.getParameter("memorialsId");

    // 2、根据 memorialsId 从 Service 中查询 Memorials 对象
    Memorials memorials = memorialsService.getMemorialsDetailById(memorialsId);

    // **********************补充功能**********************
    // 获取当前奏折对象的状态
    Integer memorialsStatus = memorials.getMemorialsStatus();
    
    // 判断奏折状态
    if (memorialsStatus == 0) {
        // 更新奏折状态:数据库修改
        memorialsService.updateMemorialsStatusToRead(memorialsId);

        // 更新奏折状态:当前对象修改
        memorials.setMemorialsStatus(1);
    }
    // **********************补充功能**********************

    // 3、将 Memorials 对象存入请求域
    request.setAttribute("memorials", memorials);

    // 4、解析渲染视图
    String templateName = "memorials_detail";
    processTemplate(templateName, request, response);

}

7.3、MemorialsService 方法

在这里插入图片描述

@Override
public void updateMemorialsStatusToRead(String memorialsId) {
    memorialsDao.updateMemorialsStatusToRead(memorialsId);
}

7.4、MemorialsDao 方法

在这里插入图片描述

@Override
public void updateMemorialsStatusToRead(String memorialsId) {
    String sql = "update t_memorials set memorials_status=1 where memorials_id=?";
    update(sql, memorialsId);
}

第九节 业务功能:批复奏折

1、本质

提交表单,更新数据。

2、WorkServlet 方法

protected void feedBack(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    // 获取表单提交的请求参数
    String memorialsId = request.getParameter("memorialsId");
    String feedbackContent = request.getParameter("feedbackContent");

    // 执行更新
    memorialsService.updateMemorialsFeedBack(memorialsId, feedbackContent);

    // 重定向回显示奏折列表页面
    response.sendRedirect(request.getContextPath() + "/work?method=showMemorialsDigestList");
}

3、MemorialsService 方法

@Override
public void updateMemorialsFeedBack(String memorialsId, String feedbackContent) {
    memorialsDao.updateMemorialsFeedBack(memorialsId, feedbackContent);
}

4、MemorialsDao 方法

@Override
public void updateMemorialsFeedBack(String memorialsId, String feedbackContent) {

    String feedbackTime = new SimpleDateFormat("yyyy-MM-dd").format(new Date());

    String sql = "update t_memorials set memorials_status=2,feedback_content=?,feedback_time=? where memorials_id=?";
    
    update(sql, feedbackContent, feedbackTime, memorialsId);
}

本文章参考B站 尚硅谷2022版Maven教程(maven入门+高深,全网无出其右!),仅供个人学习使用,部分内容为本人自己见解,与尚硅谷无关。

<think>好的,我现在需要帮助用户解决关于使用IntelliJ IDEA从零开始构建分布式架构项目的问题。用户之前已经得到了一些分步指南,现在根据提供的站内引用和之前的回答,我需要进一步优化回答,并确保符合用户的需求和引用内容。 首先,我需要回顾用户提供的引用内容。引用[1]到[5]主要涉及IDEA的项目创建、模块管理、构建工具使用以及多模块项目的配置。特别是引用[2]和[4]强调了IDEA中Project和Module的结构,与Eclipse的不同之处,比如一个Project对应一个窗口,多Module结构适合分布式项目。引用[5]提到了如何创建子模块并添加依赖,这在实际的多模块项目搭建中非常关键。 用户当前的问题是寻找零基础教程,因此需要从最基础的步骤开始,结合这些引用内容。用户可能对IDEA的界面和概念不太熟悉,所以需要详细解释每个步骤,特别是如何创建Project、添加Module、配置依赖等。同时,用户之前的问题中提到了使用Spring Cloud Alibaba组件,如Nacos、Seata等,需要将这些技术整合到教程中,确保步骤连贯。 接下来,我需要确保回答结构清晰,分步骤进行,并引用相关的内容来支持说明。例如,在创建多模块项目时,引用[2]和[4]的Project和Module结构说明非常重要,需要明确指出IDEA中的项目结构与Eclipse的不同,避免用户混淆。此外,引用[5]中的pom.xml配置示例可以用来展示如何添加模块依赖,确保各个子模块能够正确引用公共模块。 另外,用户可能遇到的常见问题,比如依赖冲突、配置错误等,需要提供解决方案,如使用Maven的依赖树分析,或者如何通过IDEA的构建工具窗口管理任务(引用[3])。同时,分布式架构中的服务注册、配置中心设置等步骤需要详细说明,可能结合代码示例和配置文件,确保用户能够跟随操作。 在验证部分,需要指导用户如何测试服务注册是否成功,网关路由是否生效,这可以通过curl命令或IDEA内置的HTTP客户端来实现。此外,分布式事务和链路追踪的集成可能需要额外的步骤,比如引入Seata和Sleuth,但根据用户之前的回答,这些内容可能已经涵盖,需要简要提及并引导用户参考之前的指南或相关文档。 最后,生成的相关问题需要围绕用户可能进一步关心的主题,如具体组件的配置细节、调试技巧、部署策略等,确保用户能够找到后续的学习路径。 总结来说,我需要将站内引用中的关键点融入教程步骤,确保每个环节都有据可依,同时保持语言简洁明了,适合零基础用户理解。需要特别注意IDEA特有的操作,如多窗口管理、模块创建、依赖配置等,避免用户在使用过程中因IDE差异而遇到障碍。</think>### 从零开始使用IntelliJ IDEA构建分布式架构项目实战指南 --- #### 一、项目创建与多模块搭建(结合引用[2][4][5]) 1. **创建父工程** - 选择菜单栏 `File → New → Project` - 选择`Maven` → 勾选`Create from archetype` → 选择`org.apache.maven.archetypes:maven-archetype-quickstart` - 填写GroupId(如`com.example`)和ArtifactId(如`distributed-parent`) - **关键配置**:父工程pom.xml需添加`<packaging>pom</packaging>` 2. **添加子模块** - 右键父工程 → `New → Module` - 选择`Maven` → 命名模块(如`service-order`) - 重复创建`common`, `gateway`, `service-auth`等模块 - **注意**:每个模块的pom.xml需继承父工程[^2] ```xml <!-- 子模块示例:service-product/pom.xml --> <parent> <groupId>com.example</groupId> <artifactId>distributed-parent</artifactId> <version>1.0-SNAPSHOT</version> </parent> ``` --- #### 二、分布式组件集成(基于Spring Cloud Alibaba) 1. **服务注册与发现(Nacos)** - 在`common`模块添加依赖: ```xml <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> ``` - 子模块启动类添加注解`@EnableDiscoveryClient`[^1] 2. **跨模块依赖配置(引用[5])** ```xml <!-- service-order模块依赖common模块 --> <dependency> <groupId>com.example</groupId> <artifactId>common</artifactId> <version>${project.version}</version> </dependency> ``` --- #### 三、核心功能开发 1. **API网关配置(Spring Cloud Gateway)** ```yaml # gateway模块application.yml spring: cloud: gateway: routes: - id: auth_route uri: lb://service-auth predicates: - Path=/api/auth/** ``` 2. **服务间通信(OpenFeign)** ```java // 在service-order模块创建Feign客户端 @FeignClient(name = "service-product", path = "/products") public interface ProductFeignClient { @GetMapping("/{id}") ProductDTO getById(@PathVariable Long id); } ``` --- #### 、项目验证与调试 1. **启动顺序建议**: ``` 1. Nacos Server(控制台http://localhost:8848) 2. 网关服务(gateway) 3. 业务服务(service-auth/service-order等) ``` 2. **服务发现验证**: ```bash # 查看注册服务列表 curl http://localhost:8848/nacos/v1/ns/service/list ``` 3. **接口调试技巧**: - 使用IDEA内置HTTP Client工具 - 示例请求: ``` GET http://localhost:8080/api/order/1 Authorization: Bearer token ``` --- #### 五、典型问题解决方案 1. **依赖冲突排查**: - 在IDEA右侧Maven面板 → 点击`Show Dependencies`生成依赖树 - 使用`mvn dependency:tree -Dverbose`命令分析[^3] 2. **多模块热部署**: - 开启`Build → Compile → Build Project automatically` - 添加`spring-boot-devtools`依赖 3. **配置中心使用**: ```yaml # 在nacos控制台创建dataId:service-auth-dev.yaml spring: cloud: nacos: config: server-addr: localhost:8848 file-extension: yaml ``` --- $$ \text{分布式系统设计原则} = \begin{cases} \text{单一职责} & \text{每个服务独立部署} \\ \text{最终一致性} & \text{允许短时数据不一致} \\ \text{容错设计} & \text{熔断+降级+限流} \end{cases} $$ ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值