项目总体框架
先暂时这样子(后续发现错误的话就改)
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 映射到 LoginController
↓
LoginController.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 {
@Override
protected 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 mapper
PUBLIC "-//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>