Java前后端分离实现登陆

1后台代码编写

使用Tomcat的服务器

使用Servlet处理请求和响应

先导入Servelet包

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

伪造数据库数据

       // 模拟的用户数据
        Map<String, String> users = new HashMap<>();
        users.put("admin", "password"); // 简单的用户名和密码对
        users.put("user1", "pass123");
        users.put("user2", "pass456");

继承HttpServlet父类重写doPost和doGet方法

doGet

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 返回405 Method Not Allowed
        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "GET method is not supported for this resource.");
    }

doPost

 @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置响应内容类型为JSON,并指定字符编码
        resp.setContentType("application/json;charset=UTF-8");
        resp.setHeader("Access-Control-Allow-Origin", "*"); // 允许所有来源,生产环境中应限制到具体域名
        resp.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        resp.setHeader("Access-Control-Max-Age", "3600");
        resp.setHeader("Access-Control-Allow-Headers", "Content-Type");

        // 读取并解析请求体中的JSON数据
        BufferedReader reader = req.getReader();
        StringBuilder jsonBuffer = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            jsonBuffer.append(line);
        }
        String jsonString = jsonBuffer.toString();

        ObjectMapper mapper = new ObjectMapper();
        Map<String, String> data = mapper.readValue(jsonString, Map.class);

        // 获取用户名和密码
        String username = data.get("username");
        String password = data.get("password");
        System.out.println(username+"=>>>>>>"+password);
        // 模拟的用户数据
        Map<String, String> users = new HashMap<>();
        users.put("admin", "password"); // 简单的用户名和密码对
        users.put("user1", "pass123");
        users.put("user2", "pass456");

        // 构建响应对象
        Map<String, Object> responseData = new HashMap<>();

        if (users.containsKey(username) && users.get(username).equals(password)) {
            // 如果认证成功,创建会话
            HttpSession session = req.getSession();
            session.setAttribute("user", username);
            responseData.put("status", "success");
            responseData.put("message", "登录成功!");

        } else {
            // 如果认证失败,设置错误消息
            responseData.put("status", "error");
            responseData.put("message", "用户名或密码错误,请重试。");
        }

        // 将响应对象转换为JSON字符串并写入响应
        mapper.writeValue(resp.getWriter(), responseData);
    }

导入需要的jar包处理json数据

  <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.15.2</version>
    </dependency>

处理步骤

1读取请求体内容

BufferedReader reader = req.getReader();
StringBuilder jsonBuffer = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
    jsonBuffer.append(line);
}
String jsonString = jsonBuffer.toString();

2JSON 解析( 使用 Jackson 库中的 ObjectMapper 类来将 JSON 字符串解析(反序列化)为 Java 对象。

ObjectMapper mapper = new ObjectMapper();
Map<String, String> data = mapper.readValue(jsonString, Map.class);

最后后端处理账号密码验证,实现登陆逻辑

        if (users.containsKey(username) && users.get(username).equals(password)) {
            // 如果认证成功,创建会话
            HttpSession session = req.getSession();
            session.setAttribute("user", username);
            responseData.put("status", "success");
            responseData.put("message", "登录成功!");

        } else {
            // 如果认证失败,设置错误消息
            responseData.put("status", "error");
            responseData.put("message", "用户名或密码错误,请重试。");
        }

使用Postman测试后台

测试接口

@WebServlet("/api/login")

Post的请求

前台发送json数据

{
  "username": "admin",
  "password": "password"
}

后台接收json数据

返回前台响应

2前台代码编写使用vue3

首相用npm下载相关依赖库

  "vue-router": "^4.5.0"
  "element-plus": "^2.9.1"

编写登陆界面

<template>
  <div class="login-container">
    <h3 class="login-title">用户登录</h3>
    <el-form :model="form" :rules="rules" ref="ruleFormRef" label-width="100px" class="demo-ruleForm">
      <el-form-item label="用户名" prop="username">
        <el-input v-model="form.username"></el-input>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input type="password" v-model="form.password" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm">登录</el-button>
        <el-button type="primary" @click="resetForm">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup>
import { reactive, ref } from 'vue';
import { ElMessage } from 'element-plus';

const form = reactive({
  username: '',
  password: ''
});

const rules = reactive({
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { min: 3, max: 16, message: '长度应在3到16个字符之间', trigger: 'blur' }
  ],
  password: [
    { required: true, message: '请输入密码', trigger: 'blur' },
    { min: 6, max: 16, message: '长度应在6到16个字符之间', trigger: 'blur' }
  ]
});
import {useRouter} from "vue-router"
let router = useRouter();

function goHome(){
  router.push("/index")
}
const ruleFormRef = ref(null);

const submitForm = async () => {
  // 开始加载状态
  ElMessage.info('正在登录...');

  try {
    const isValid = await ruleFormRef.value.validate();
    if (isValid) {
      // 获取表单数据
      const formData = {
        username: form.username,
        password: form.password
      };

      // 发送POST请求到服务器,使用相对路径
      const response = await fetch('/api/login', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(formData)
      });

      // 解析JSON响应
      const data = await response.json();

      if (data.status === 'success') {
        // 登录成功后的处理逻辑
        ElMessage.success(data.message);
        // 更新应用状态(如设置用户信息)
        // 导航到主页或其他页面
        goHome();
        // router.push('/home');
      } else {
        // 处理登录失败的情况
        ElMessage.error(data.message || '登录失败,请重试。');
      }
    }
  } catch (error) {
    // 捕获并处理网络错误等异常情况
    console.error('提交失败:', error);
    ElMessage.error('提交失败,请检查网络连接或稍后再试。');
    return false;
  }
};

// 重置表单函数保持不变
const resetForm = () => {
  ruleFormRef.value.resetFields();
};
</script>

<style scoped>

body, html {
  height: 100%;
  margin: 0;

}

.login-container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh; /* 使用视口单位确保容器高度为整个视窗 */
  background-image: url("https://img.keaitupian.cn/newupload/05/1684145291133817.jpg");
  padding: 20px; /* 可选:添加一些内边距 */
}

.login-title {
  margin-bottom: 20px; /* 标题与表单之间的间距 */
}

.demo-ruleForm {
  width: 360px; /* 设置表单宽度 */
  padding: 24px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
</style>

编写首页页面

<template>
    <div class="home-container">
      <header class="home-header">
        <h1>欢迎来到我们的网站</h1>
        <p>探索更多,发现无限可能。</p>
      </header>
      <main class="home-content">
        <section class="features">
          <h2>我们的特色</h2>
          <ul>
            <li><strong>便捷性:</strong>快速访问所需信息。</li>
            <li><strong>创新性:</strong>持续推出新功能。</li>
            <li><strong>安全性:</strong>保护您的数据安全。</li>
          </ul>
        </section>
        <section class="call-to-action">
          <p>立即加入我们,开启精彩之旅!</p>
          <router-link to="/signup" class="cta-button">注册</router-link>
        </section>
      </main>
      <footer class="home-footer">
        <p>&copy; 2024 我们的公司. 保留所有权利.</p>
      </footer>
    </div>
  </template>
  
  <style scoped>
  body, html {
    margin: 0;
    padding: 0;
    height: 100%;
  }
  
  .home-container {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
  }
  
  .home-header {
    background-color: #4CAF50;
    color: white;
    text-align: center;
    padding: 2rem 1rem;
  }
  
  .home-content {
    flex: 1;
    padding: 2rem;
    background-color: #f9f9f9;
  }
  
  .features {
    margin-bottom: 2rem;
  }
  
  .call-to-action {
    text-align: center;
  }
  
  .cta-button {
    display: inline-block;
    padding: 0.5rem 1.5rem;
    background-color: #4CAF50;
    color: white;
    text-decoration: none;
    border-radius: 4px;
    transition: background-color 0.3s ease;
  }
  
  .cta-button:hover {
    background-color: #45a049;
  }
  
  .home-footer {
    background-color: #333;
    color: white;
    text-align: center;
    padding: 1rem;
  }
  </style>

配置路由信息

import {createRouter, createWebHistory} from "vue-router"

import Login from'../components/Login.vue'
 
import index from'../components/index.vue'
let router=createRouter({
    history:createWebHistory(),
    routes:[
        {   path:'/',
            component:Login
        },
        {
            path:'/index',
            component:index
        }]})
export default router;

注册路由和ElementPlus

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
import router from './route/router';
const app = createApp(App)
app.use(ElementPlus)
app.use(router)
app.mount('#app')

最后编写路由出口

<script setup>
import Login from "./components/Login.vue";
</script>

<template>
<router-view></router-view>
</template>

<style scoped>

</style>

和后台数据交互实现用户登陆

      // 发送POST请求到服务器,使用相对路径
      const response = await fetch('http://localhost:8080/api/login', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(formData)
      });

此时用这种方式跨域访问tomcat的服务器,会报以下错误

然后我通过前端代理来解决跨域

首先找到

添加配置信息

export default defineConfig({
  plugins: [vue()],
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:8080', // API服务器地址
        changeOrigin: true,
        pathRewrite: {
          '^/api': '' // 重写路径,例如将 /api/login 转发为 /login
        }
      }
    }
  }
})

此时就可以顺利实现登陆了

相关推荐
softshow10262 分钟前
Solon 集成 activemq-client
java·activemq·java-activemq
成长之路5143 分钟前
【绿色碳中和】全国各省各地级市绿色金融数据(1990-2022年)
大数据·did
组合缺一5 分钟前
solon 集成 activemq-client (sdk)
java·solon·activemq
小马超会养兔子5 分钟前
如何写一个转盘
开发语言·前端·vue
lucky_syq10 分钟前
Spark和Hive的区别
大数据·hive·spark
B站计算机毕业设计超人12 分钟前
计算机毕业设计hadoop+spark视频推荐系统 短视频推荐系统 视频流量预测系统 短视频爬虫 视频数据分析 视频可视化 视频大数据 大数据
大数据·人工智能·python·机器学习·课程设计·数据可视化·推荐算法
sinat_3070215314 分钟前
大数据技术与应用——大数据处理技术(一)(山东省大数据职称考试)
大数据·云计算
南郁17 分钟前
答:C++需要学到什么程度再开始学 qt 比较合理?
开发语言·c++·qt·学习
No0d1es17 分钟前
GESP CCF C++八级编程等级考试认证真题 2024年12月
开发语言·c++·青少年编程·gesp·ccf·八级
NiNg_1_23420 分钟前
Hadoop实现WordCount详解
大数据·hadoop·分布式