项目总体框架(servlet+axios+Mybatis)

项目总体框架

先暂时这样子(后续发现错误的话就改)

com.hope-tieba/                          ← 项目根
├─ .idea/                            ← IDEA 工程配置
├─ src/
│  ├─ main/
│  │  ├─ java/
│  │  │  └─ com/hope/
│  │  │      ├─ config/              ← Spring / MyBatis 配置
│  │  │      ├─ controller/
│  │  │      │  └─ LoginController   ← 登录接口
│  │  │      ├─ DAO/                 ← Mapper 接口
│  │  │      │  ├─ pojo/             ← 实体类(User 等)
│  │  │      │  ├─ dto/              ← 请求/响应 DTO
│  │  │      │  └─ vo/               ← 视图对象
│  │  │      ├─ mybatis/             ← MyBatis 工具类
│  │  │      ├─ mapper/
│  │  │      │  └─ UserMapper        ← MyBatis Mapper 接口
│  │  │      ├─ service/
│  │  │      │  └─ UserService       ← 业务层
│  │  │      └─ util/                ← 公共工具(JwtUtil、BaseServlet…)
│  │  └─ resources/
│  │      ├─ mapper/
│  │      │  └─ UserMapper.xml       ← SQL 映射
│  │      ├─ mybatis-config.xml      ← MyBatis 全局配置
│  │      └─ application.yml         ← Spring / 数据源配置(可选)
│  └─ webapp/                        ← Web 资源
│      ├─ WEB-INF/
│      │  └─ web.xml                 ← Servlet 映射
│      ├─ html/
│      │  └─ login.html              ← 前端登录页
│      └─ index.html                 ← 主页
├─ target/                           ← Maven 编译输出
├─ pom.xml                           ← Maven 依赖
└─ package*.json                     ← 前端 npm 依赖(可选)
请求执行流程
前端 axios.post('/login', {username, password})↓ HTTP POST /login
web.xml 把 /login 映射到 LoginControllerLoginController.login() 被调用↓
UserService.login() 查库↓
成功 → 生成 accessToken / refreshToken → JSON 回前端
失败 → 返回 {"status":"error","message":"账号密码错误"}

为什么要使用axios呢

之前一直没有搞懂为什么使用axios

axios把请求发送到web.xml中/login,用了axios,会将其转化为json对象发送给LoginController,如果只是单纯的表单提交,就是发送的一段类似于请求体username=zhangsan&password=123456。

请求登录发送给controller后,controller调用UserService方法,UserService调用UserMapper方法,

映射到xml文件中的sql语句操作数据库

<servlet><servlet-name>LoginController</servlet-name><servlet-class>com.hope.controller.LoginController</servlet-class>
</servlet>
<servlet-mapping><servlet-name>LoginController</servlet-name><url-pattern>/login</url-pattern>
</servlet-mapping>
调用Controller层

Controller就是继承了BaseServlet

BaseServlet封装Servlet


public class BaseServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("Baseservlet1");request.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");response.setHeader("Access-Control-Allow-Origin", "http://localhost:9000");String uri=request.getRequestURI();System.out.println(uri);//        String methodName=new StringBuffer(uri.substring(uri.lastIndexOf("/"))).toString();
//        System.out.println("获得方法的名字+methodName:"+methodName);
//
//        //获取请求头
//        String contentType = request.getContentType();
//        ObjectMapper mapper = new ObjectMapper();
//        JsonNode jsonNode = null;
//        if (contentType!=null&&contentType.startsWith("multipart/form-data")) {
//            System.out.println("如果不是文件就不进行改变");
//        }else {
//            //处理json数据部分
//            BufferedReader reader = request.getReader();;
//            if(reader!=null){
//                System.out.println("请求体为空");
//            }
//            jsonNode = mapper.readTree(reader);
//        }//获取请求方法String methodText = request.getParameter("method");if (methodText == null || methodText.isEmpty()) {methodText = request.getHeader("X-Custom-Method");}if (methodText == null || methodText.isEmpty()) {methodText = uri.substring(uri.lastIndexOf("/") + 1);}if (methodText == null || methodText.isEmpty()) {response.getWriter().println("Method is not specified");return;}System.out.println("methodText: " + methodText);//得到请求头String contentType = request.getContentType();ObjectMapper mapper=new ObjectMapper();JsonNode jsonNode=null;if (contentType != null&&contentType.startsWith("multipart/form-data")) {System.out.println("contentType: " + contentType);}else{jsonNode=mapper.readTree(request.getReader());}//获取请求方法Method[] methods = this.getClass().getDeclaredMethods();for (Method me : methods) {if (me.isAnnotationPresent(RequestMethod.class)) {RequestMethod requestMethod = me.getAnnotation(RequestMethod.class);System.out.println("jsonMethod:" + requestMethod.value());if (requestMethod.value().equals(methodText)) {Object[] objects = getParameter(me, jsonNode);me.setAccessible(true);try {Object result = me.invoke(this, objects);if (result != null) {String message = mapper.writeValueAsString(result);System.out.println(message);response.getWriter().println(message);} else {response.getWriter().println("null");}return;} catch (IllegalAccessException | InvocationTargetException e) {System.out.println("Error: invoke method" + e.getMessage());e.printStackTrace();return;}}}}}private static Object[] getParameter(Method me, JsonNode node) {Class<?>[] parameterTypes = me.getParameterTypes();Parameter[] parameters = me.getParameters();Object[] parameterValues = new Object[parameterTypes.length];for (int i = 0; i < parameterTypes.length; i++) {Parameter parameter = parameters[i];if (parameter.isAnnotationPresent(JsonParam.class)) {JsonParam jsonParam = parameter.getAnnotation(JsonParam.class);System.out.println("jsonParam:" + jsonParam.value());String value = jsonParam.value();JsonNode jsonNodeValueNode = node.get(value);if (jsonNodeValueNode != null) {parameterValues[i] = convertJsonNodeToJavaType(jsonNodeValueNode, parameterTypes[i]);}else{System.out.println("jsonNodeValueNode is null");}}else{System.out.println("没有JsonParam.class注解");parameterValues[i]=null;}}return parameterValues;}private static Object convertJsonNodeToJavaType(JsonNode jsonNodeValueNode, Class<?> parameter) {JsonMapper mapper =new JsonMapper();try {return mapper.treeToValue(jsonNodeValueNode, parameter);} catch (JsonProcessingException e) {System.out.println("Error convertJsonNodeToJavaType"+e.getMessage());e.printStackTrace();return null;}}
}
调用UserService
public class UserService {/*** 实现登录** @param username* @param password* @return*/public Map<String, String> login(String username, String password) {try (SqlSession sqlSession = MybatisUtil.getSqlSession()) {UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = userMapper.login(username, password);if (user != null) {return null;}Map<String, String> result = new HashMap<>();result.put("status", "success");result.put("id", String.valueOf(user.getId()));result.put("username", username);result.put("role", user.getRole().toString());return result;}}
}
调用UserMapper
public interface UserMapper {List<User> list();User getId(Integer id);int insert(User user);User login(String username, String password);
}
映射到xml文件中
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hope.mybatis.mapper.UserMapper"><select id="login" resultType="com.hope.DAO.pojo.User">select id,username,age,email,password,role,intro from user where id = #{id}</select>
</mapper>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/915104.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/915104.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RestTemplate 实现后端 HTTP 调用详解

1. 方法签名解析方法名和返回类型说明了这个方法的业务意图和数据结构。Override 表示实现接口方法&#xff0c;利于规范开发和自动检查。Override public List<RobotInfo> listRobots() {这里 RobotInfo 是假设的业务数据结构&#xff0c;实际项目中按你的类名即可。2. …

Python单例模式详解:从原理到实战的完整指南

引言 单例模式是软件设计中最常用的模式之一&#xff0c;它确保一个类只有一个实例&#xff0c;并提供全局访问点。在Python中&#xff0c;实现单例模式有多种优雅的方式&#xff0c;本文将详细讲解6种主流实现方法&#xff0c;包含完整代码示例和注释。 一、模块级单例&#x…

拼团系统中的幂等性防护 , 前置性查询,Redis 库存预判

这段内容涉及两个关键点&#xff1a;幂等性防护 和 拼团目标量判断&#xff0c;下面我将分别解释这两个问题&#xff0c;并重点说明&#xff1a; “如果没有拦截&#xff0c;最终访问数据&#xff0c;也会有数量判断拦截。” 这句话的意思。 ✅ 1. 查询外部交易 outTradeNo 是…

【Python】LEGB作用域 + re模块 + 正则表达式

文章目录一 LEGB作用域二 re&#xff08;Regular Expression&#xff09;预览1. re.match() —— 从字符串开头匹配2. re.search() —— 搜索整个字符串3. re.findall() —— 返回所有匹配的字符串列表4. re.finditer() —— 返回所有匹配的迭代器5. re.sub() —— 替换匹配的字…

JavaSE -- 数据操作流

6. 数据操作流在执行文件存储一个对象的时候&#xff0c;如果该对象只有少量属性需要存储&#xff0c;并且这些属性的类型都是基本数据类型&#xff0c;此时则不需要对象序列化技术。使用数据操作流既可以实现。 DataOutputStreamDataInputStream 注意&#xff1a; 读取数据的时…

GI6E 加密GRID電碼通信SHELLCODE載入

GI6E https://github.com/MartinxMax/gi6e 「它似乎能從特製的音訊信號中提取敏感資訊。」 HEX-GRID CODEX&#xff08;簡稱 HGC&#xff09;是一種自定義的 6 位元結構編碼系統&#xff0c;使用三位元的群組識別碼&#xff08;Group Bits&#xff09;加上三位元的索引識別碼…

实习十三——传输层协议

补充子网划分的主要目的就是为了节约IP&#xff0c;降低成本&#xff0c;但是如果划分私有IP网段&#xff0c;则完全没有意义&#xff0c;因为私有IP可重复&#xff0c;不要钱&#xff0c;所以私有IP严禁进行子网掩码划分传输层协议TCP三次握手TCP协议数据格式第一次握手&#…

RPG59.玩家拾取物品三:可拾取物品的提示UI

1。以WarriorWidgetBase作为父类&#xff0c;创建一个子类的userwidget2.布局为两个值都为1203。然后我们需要想办法&#xff0c;在合适的位置&#xff0c;用bool来控制此控件的显示与隐藏。情况为&#xff1a;当玩家触发与可拾取物体的重叠时&#xff0c;我们将广播一个bool值…

Vue.js 国际化 (i18n) 实践:让你的应用走向全球,多语言支持如此简单!

文章目录一、为何你的 Vue.js 应用需要“说多种语言”&#xff1f;国际化的重要性二、Vue I18n 基础实践&#xff1a;从零开始搭建多语言环境2.1 安装 Vue I18n2.2 配置 Vue I18n 实例2.3 在组件中使用翻译三、进阶实践&#xff1a;让国际化更强大、更灵活3.1 动态语言切换3.2 …

在CentOS7.9服务器上安装.NET 8.0 SDK

在 CentOS 7.9 系统上手动安装 .NET 8.0 SDK&#xff08;使用本地的 dotnet-sdk-8.0.101-linux-x64.tar.gz 文件&#xff09;&#xff0c;可以按照以下步骤进行操作。由于 CentOS 7.9 已不再被微软官方支持&#xff0c;可能会遇到依赖库版本问题&#xff08;如 GLIBCXX 和 GLIB…

HarmonyOS-ArkUI Web控件基础铺垫4--TCP协议- 断联-四次挥手解析

HarmonyOS-ArkUI&#xff1a; Web组件加载流程1 HarmonyOS-ArkUI Web控件基础铺垫1-HTTP协议-数据包内容 HarmonyOS-ArkUI Web控件基础铺垫2-DNS解析 HarmonyOS-ArkUI Web控件基础铺垫3--TCP协议- 从规则本质到三次握手-CSDN博客 接上文&#xff0c;上文我们讲解了: 数据在…

如何用AI 生成论文/书籍的摘要

不知道大家是否有这样的感觉&#xff0c;上网浏览信息&#xff0c;看到好的文章就兴奋地下载了下来&#xff0c;文件的名称通常是一串奇奇怪怪的字符串。过了几天就在电脑中找不着了。没有网络上搜索不到的文章&#xff0c;而是在你的电脑中却找不到它们。几年下来&#xff0c;…

ubuntu系统+N卡 | docker compose+ollama+dify(dify和ollama在同一容器)

1、安装NVIDIA驱动 2、安装docker&#xff0c;docker compose 3、安装NVIDIA Container Toolkit Installing the NVIDIA Container Toolkit — NVIDIA Container Toolkit&#xff08;仅 GPU 场景需要&#xff09; # Configure the production repository: curl -fsSL https://…

实习手记:基于大模型的搜索引擎开发实践

初入团队&#xff1a;从理论到实践的跨越五月份开始&#xff0c;我怀着忐忑又期待的心情以线上的方式加入了公司AI研发中心的搜索引擎优化小组。作为一名数据科学与大数据技术专业的学生&#xff0c;这是我第一次参与工业级AI项目的开发&#xff0c;团队的任务是构建一个基于大…

用Python实现神经网络(二)

#Overfitting是机器学习的主要问题。下面我们来看一下过拟合现像&#xff1a;import numpy as npimport matplotlib.pyplot as pltimport matplotlib as mplimport tensorflow as tffrom scipy.optimize import curve_fit# Generic matplotlib parameters for plots and figure…

数据结构入门 (二):挣脱连续空间的束缚 —— 单向链表详解

TOC(目录) 引言&#xff1a;整齐的代价 在上一篇文章中&#xff0c;我们一起探索了数据结构大家族的第一位成员——顺序表。我们了解到&#xff0c;顺序表作为一种线性结构&#xff0c;其最大的特点在于逻辑顺序与物理顺序的一致性&#xff0c;即元素之间不仅存在逻辑上的前后关…

AI-视频一致性与多帧控制在AIGC中的技术挑战与突破!

全文目录&#xff1a;开篇语前言1. 视频中人物一致性建模的难点与现有解决方案**人物一致性建模的挑战****现有解决方案****案例代码&#xff1a;基于姿态估计的多帧一致性保持**2. 光照/纹理/姿态跨帧保持方法剖析**跨帧光照与纹理一致性****跨帧姿态一致性**3. 帧间插值与关键…

基于Qwen2.5-3B-Instruct的LoRA微调与推理实战指南

前言 大语言模型(LLM)的微调是当前AI领域的热门话题&#xff0c;而参数高效微调方法(如LoRA)因其低成本和高效率备受关注。本文将手把手教你如何使用Qwen2.5-3B-Instruct模型进行LoRA微调&#xff0c;并构建完整的推理流程。 一、环境准备 1.1 硬件要求 • GPU: 至少16GB显存(如…

电脑插上u盘不显示怎么回事

对于经常使用电脑的用户来说&#xff0c;U盘是一种再熟悉不过的存储工具。不管是拷贝资料、备份文件&#xff0c;还是制作启动盘&#xff0c;U盘都发挥着重要作用。然而&#xff0c;有时候你可能会遇到这样的情况&#xff1a;“U盘插上电脑&#xff0c;灯亮了&#xff0c;但电脑…

2025年6月GESP(C++二级): 幂和数

2025年6月GESP(C++二级): 幂和数 题目描述 对于正整数 n n n,如果 n n n 可以表为两个