当前位置: 首页 > news >正文

新八建设集团网站杭州前十强装修公司有哪几家

新八建设集团网站,杭州前十强装修公司有哪几家,wordpress前端页面存放,作业设计模板✨哈喽#xff0c;进来的小伙伴们#xff0c;你们好耶#xff01;✨ #x1f6f0;️#x1f6f0;️系列专栏:【Java项目】 ✈️✈️本篇内容:个人博客系统前后端分离实现#xff01; #x1f680;#x1f680;个人代码托管github#xff1a;博客系统源码地址#xff… ✨哈喽进来的小伙伴们你们好耶✨ ️️系列专栏:【Java项目】 ✈️✈️本篇内容:个人博客系统前后端分离实现 个人代码托管github博客系统源码地址 ⛵⛵作者简介一名双非本科大三在读的Java编程小白道阻且长星夜启程 本篇博客开始之前需要说明的是前面我们已经实现了博客系统的纯前端页面详情可以参考这篇博客博客系统前端页面或者直接点击本专栏的上一篇博客即可 那么本篇博客是基于个人博客系统的前端页面编写一个后端服务器和之前写的这个页面进行联动实现前后端分离的功能 OK接下来我们开始编写博客系统 目录 一、准备工作 1、打开idea创建maven项目 2、引入依赖 3、创建相关的目录 4、编写代码 5、6打包部署 7、 在浏览器验证程序 二、开始正式编写服务器代码 model层 Controller层 一、准备工作 1、打开idea创建maven项目 1File-new Project 2选择创建maven项目然后点击next 3给咱们的maven项目取个名字博主这里取的是Blog_System2然后选择文件夹存放代码 2、引入依赖 这里我们需要引入的依赖是servletjacksonmysql 引入方法打开下面这个链接maven中央仓库 举例servlet依赖的引入方式 1打开链接在搜索框内输入servlet点击search找到下面箭头指向的这个点进去 2鼠标滚轮向下滑动找到3.0.1版本(跟自己电脑的tomcat和jdk的版本对应) 3找到下面红色框框中的内容Ctrlc复制 4粘贴到我们刚刚创建的maven项目下pom.xml里面注意需要用dependency包裹起来 博主这里只演示一下servlet是如何引入的像mysql和Jackson都是类似的直接根据上面的步骤来引入即可 3、创建相关的目录 1点开我们项目下的src文件找到main然后右键创建一个新的目录webapp在webapp下创建一个目录叫做WEB-INF然后在WEB-INF下面创建一个新的xml文件叫做web.xml创建好之后大概如下(webapp下有些css、js文件这是后来引入的这里不用管) 2在web.xml文件中填写以下代码 !DOCTYPE web-app PUBLIC-//Sun Microsystems, Inc.//DTD Web Application 2.3//ENhttp://java.sun.com/dtd/web-app_2_3.dtd web-appdisplay-nameArchetype Created Web Application/display-name /web-app 4、编写代码 这里我们先简单写个无关的测试代码方便咱们后续步骤的执行 1)找到java文件在java文件下创建一个类叫做HelloServlet 2写一个简单的实验代码 import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;WebServlet(/hello) public class HelloServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().write(你好博客系统);} } 5、6打包部署 这里打包部署在博主之前的博客已经介绍过使用idea自带的插件smart tomcat来完成 7、 在浏览器验证程序 二、开始正式编写服务器代码 1、开篇已经介绍过这里我们的前端代码可以直接全部粘贴到webapp下这样就把代码集成到我们的项目上了后续打包部署的时候这些资源会被一并打包部署也就可以在浏览器访问到了 粘贴过来之后对应的目录结构 2、先来实现我们MVC结构中的M部分博主这里在java文件下建一个包model负责编写M部分的代码 这里来介绍一下前面写的博客系统页面 1、博客列表页显示博客的列表 2、博客详情页点击博客列表页上面列出的博客篇数可以跳转到完整的博客内容 3、登录页面 4、博客编辑页基于editor.md整了一个markdown编辑器根据这个页面来发布博客 联想到数据库这里需要存储博客点击发布的时候博客被发表到服务器上需要被存储起来 获取博客在博客列表页和博客详情页能够拿到博客的内容 即我们需要设计一张博客表用来存储所有的博客数据设计一张用户表用户登录的时候就需要用到这个表 开始编写数据库代码 1在main下创建一个File叫做db.sql -- 编写建库建表的 sqlcreate database if not exists blog_system character set utf8mb4;use blog_system;-- 创建一个博客表. drop table if exists blog; create table blog (blogId int primary key auto_increment,title varchar(256),content mediumtext, -- 正文较长使用mediumtext类型userId int, -- 文章作者的 idpostTime datetime -- 发布时间 );-- 创建一个用户表 drop table if exists user; create table user (userId int primary key auto_increment,username varchar(30) unique, -- 后续会使用用户名进行登录, 一般用于登录的用户名都是不能重复的.password varchar(20) );insert into user values(null, zhangsan, 123); insert into user values(null, lisi, 123); 2编写完成之后打开mysql客户端然后复制上面的SQL语句粘贴到我们的mysql客户端 3检查数据库和表是否创建完成 2、封装数据库 model层 1首先创建一个DBUtil类用来封装数据库连接操作 package model;import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException;// 使用这个类和数据库建立连接. public class DBUtil {private static final String URL jdbc:mysql://127.0.0.1:3306/blog_system?characterEncodingutf8useSSLfalse;private static final String USERNAME root;private static final String PASSWORD ;//填写自己电脑mysql数据库密码private static volatile DataSource dataSource null;//注意加上volatileprivate static DataSource getDataSource() {if (dataSource null) {synchronized (DBUtil.class) {//双重校验锁if (dataSource null) {dataSource new MysqlDataSource();((MysqlDataSource)dataSource).setUrl(URL);((MysqlDataSource)dataSource).setUser(USERNAME);((MysqlDataSource)dataSource).setPassword(PASSWORD);}}}return dataSource;}public static Connection getConnection() throws SQLException {return getDataSource().getConnection();}public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet) {if (resultSet ! null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (statement ! null) {try {statement.close();} catch (SQLException e) {e.printStackTrace();}}if (connection ! null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}} }2创建实体类 使用实体类来表示数据库中的一条记录 这里包含了两个类分别是Blog、User User package model;// 每个 model.User 对象, 期望能够表示 user 表中的一条记录. public class User {private int userId 0;private String username ;private String password ;public int getUserId() {return userId;}public void setUserId(int userId) {this.userId userId;}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String getPassword() {return password;}public void setPassword(String password) {this.password password;} }针对用户表来设计博客表 Blog package model;import java.sql.Timestamp; import java.text.SimpleDateFormat;// 每个 model.Blog 对象, 对应 blog 表里的一条记录 public class Blog {private int blogId;private String title;//正文private String content;//内容private int userId;//博客作者private Timestamp postTime;//发布时间public int getBlogId() {return blogId;}public void setBlogId(int blogId) {this.blogId blogId;}public String getTitle() {return title;}public void setTitle(String title) {this.title title;}public String getContent() {return content;}public void setContent(String content) {this.content content;}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId userId;} 3、封装针对数据增删改查 这里有个很形象的词叫做DAO即把提供了对增删改查这样的类的叫法 创建Blog_Dao:核心代码都提供了注释 package model;import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List;// 这个类用于去封装博客表的基本操作 public class BlogDao {// 1. 往博客表里, 插入一个博客.public void insert(Blog blog) {// JDBC 基本代码Connection connection null;PreparedStatement statement null;try {// 1) 和数据库建立连接.connection DBUtil.getConnection();// 2) 构造 SQL 语句String sql insert into blog values(null, ?, ?, ?, now());statement connection.prepareStatement(sql);statement.setString(1, blog.getTitle());statement.setString(2, blog.getContent());statement.setInt(3, blog.getUserId());// 3) 执行 SQLstatement.executeUpdate();} catch (SQLException e) {e.printStackTrace();} finally {// 4) 关闭连接, 释放资源DBUtil.close(connection, statement, null);}}// 2. 能够获取到博客表中的所有博客的信息 (用于在博客列表页, 此处每篇博客不一定会获取到完整的正文)public ListBlog selectAll() {ListBlog blogs new ArrayList();Connection connection null;PreparedStatement statement null;ResultSet resultSet null;try {connection DBUtil.getConnection();String sql select * from blog order by postTime desc;statement connection.prepareStatement(sql);resultSet statement.executeQuery();while (resultSet.next()) {Blog blog new Blog();blog.setBlogId(resultSet.getInt(blogId));blog.setTitle(resultSet.getString(title));// 这里需要针对内容进行截断(太长了, 就去掉后面)String content resultSet.getString(content);// 这个 50 自定义随便给一个就行if (content.length() 50) {content content.substring(0, 50) ...;}blog.setContent(content);blog.setUserId(resultSet.getShort(userId));blog.setPostTime(resultSet.getTimestamp(postTime));blogs.add(blog);}} catch (SQLException throwables) {throwables.printStackTrace();} finally {DBUtil.close(connection, statement, resultSet);}return blogs;}// 3. 能够根据博客 id 获取到指定的博客内容 (用于在博客详情页)public Blog selectOne(int blogId) {Connection connection null;PreparedStatement statement null;ResultSet resultSet null;try {connection DBUtil.getConnection();String sql select * from blog where blogId ?;statement connection.prepareStatement(sql);statement.setInt(1, blogId);resultSet statement.executeQuery();// 此处我们是使用 主键 来作为查询条件的. 查询结果, 要么是 1 , 要么是 0.if (resultSet.next()) {Blog blog new Blog();blog.setBlogId(resultSet.getInt(blogId));blog.setTitle(resultSet.getString(title));blog.setContent(resultSet.getString(content));blog.setUserId(resultSet.getShort(userId));blog.setPostTime(resultSet.getTimestamp(postTime));return blog;}} catch (SQLException throwables) {throwables.printStackTrace();} finally {DBUtil.close(connection, statement, resultSet);}return null;}// 4. 从博客表中, 根据博客 id 删除博客.public void delete(int blogId) {Connection connection null;PreparedStatement statement null;try {connection DBUtil.getConnection();String sql delete from blog where blogId ?;statement connection.prepareStatement(sql);statement.setInt(1, blogId);statement.executeUpdate();} catch (SQLException throwables) {throwables.printStackTrace();} finally {DBUtil.close(connection, statement, null);}}// 注意, 上述操作是 增删查, 没有改 } 与Blog_Dao对应的就是User_Dao: package model;import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException;// 提供了针对用户表的基本操作 public class UserDao {// 需要实现的操作// 1. 根据用户名来查找用户信息.// 会在登录逻辑中使用public User selectByName(String username) {Connection connection null;PreparedStatement statement null;ResultSet resultSet null;try {connection DBUtil.getConnection();String sql select * from user where username ?;statement connection.prepareStatement(sql);statement.setString(1, username);resultSet statement.executeQuery();// 此处 username 使用 unique 约束, 要么能查到一个, 要么一个都查不到.if (resultSet.next()) {User user new User();user.setUserId(resultSet.getInt(userId));user.setUsername(resultSet.getString(username));user.setPassword(resultSet.getString(password));return user;}} catch (SQLException throwables) {throwables.printStackTrace();} finally {DBUtil.close(connection, statement, resultSet);}return null;}// 2. 根据用户 id 来找用户信息.// 博客详情页, 就可以根据用户 id 来查询作者的名字, 把作者名字显示出来.public User selectById(int userId) {Connection connection null;PreparedStatement statement null;ResultSet resultSet null;try {connection DBUtil.getConnection();String sql select * from user where userId ?;statement connection.prepareStatement(sql);statement.setInt(1, userId);resultSet statement.executeQuery();// 此处 username 使用 unique 约束, 要么能查到一个, 要么一个都查不到.if (resultSet.next()) {User user new User();user.setUserId(resultSet.getInt(userId));user.setUsername(resultSet.getString(username));user.setPassword(resultSet.getString(password));return user;}} catch (SQLException throwables) {throwables.printStackTrace();} finally {DBUtil.close(connection, statement, resultSet);}return null;} } OK到这里我们的数据库的操作都已经准备好了接下来开始编写服务器中的Controller层 Controller层 1、首先来约定前后端交互的接口分别编写客户端代码服务器代码 1)从博客列表页开始 这个页面的作用就是能够展示出数据库中博客的列表 效果如下 2) 约定 请求GET/blog 响应这里采用的是json格式来编写代码在括号里面应该包含: [{blogId:1,title:这是第一篇博客content这是博客正文userId:1,postTime:2023-01-20 19:00:00}{blogId:2,title:这是第二篇博客content这是博客正文userId:1,postTime:2023-01-21 19:00:00}] 由于是博客列表页博客内容只能展示一部分所以这里的content可以看成是摘要即截取正文的一部分内容 新建一个类BlogServlet:部分代码 import model.Blog; import model.BlogDao; import model.User;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.util.List;// 通过这个类, 来处理 /blog 路径对应的请求 WebServlet(/blog) public class BlogServlet extends HttpServlet {private ObjectMapper objectMapper new ObjectMapper();// 这个方法用来获取到数据库中的博客列表.Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType(application/json; charsetutf8);BlogDao blogDao new BlogDao();// 先尝试获取到 req 中的 blogId 参数. 如果该参数存在, 说明是要请求博客详情// 如果该参数不存在, 说明是要请求博客的列表.String param req.getParameter(blogId);if (param null) {// 不存在参数, 获取博客列表ListBlog blogs blogDao.selectAll();// 把 blogs 对象转成 JSON 格式.String respJson objectMapper.writeValueAsString(blogs);resp.getWriter().write(respJson);} else {// 存在参数, 获取博客详情int blogId Integer.parseInt(param);Blog blog blogDao.selectOne(blogId);String respJson objectMapper.writeValueAsString(blog);resp.getWriter().write(respJson);}} } 代码写完之后我们来验证这个代码是否正确可以使用postman来访问这个接口的数据 1首先打开postman然后输入对应的请求输入完成之后点击send可以看到结果 可以看到结果是一个空说明我们的json数组里面还没有插入数据我们可以在博客表blog中插入一些数据 -- 给博客表中插入点数据, 方便测试. insert into blog values(null, 这是第一篇博客, 从今天开始, 我要认真学 Java, 1, now()); insert into blog values(null, 这是第二篇博客, 从昨天开始, 我要认真学 Java, 1, now()); insert into blog values(null, 这是第三篇博客, 从前天开始, 我要认真学 Java, 1, now()); insert into blog values(null, 这是第一篇博客, 从今天开始, 我要认真学 C, 2, now()); insert into blog values(null, 这是第二篇博客, 从昨天开始, 我要认真学 C, 2, now()); insert into blog values(null, 这是第三篇博客, # 一级标题\n ### 三级标题\n 这是引用内容, 2, now()); 在MySQL终端中写以上数据 3、编写客户端代码 这里我们想实现的是在页面加载的时候让页面通过ajax访问服务器获取到数据库中的博客数据并且填写到页面中 首先编写的是blog_list.html之前我们已经写过大概的前端代码这里需要稍作补充 !DOCTYPE html html langen headmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0title博客列表/titlelink relstylesheet hrefcss/common.csslink relstylesheet hrefcss/blog_list.css /head body!-- 这是导航栏 --div classnavimg srcimage/logo.jpeg altspan我的博客系统/span!-- 空白元素, 用来占位置 --div classspacer/diva hrefblog_list.html主页/aa hrefblog_edit.html写博客/aa hreflogout注销/a/div!-- 这里的 .container 作为页面的版心 --div classcontainer!-- 左侧个人信息 --div classleft!-- 表示整个用户信息区域. --div classcardimg srcimage/头像.jpg alth3/h3a href#github 地址/adiv classcounterspan文章/spanspan分类/span/divdiv classcounterspan2/spanspan1/span/div/div/div!-- 右侧内容详情 --div classright!-- .blog 就对应一个博客 --!-- div classblogdiv classtitle我的第一篇博客/divdiv classdate2022-05-05 20:52:00/divdiv classdesc从今天起, 我要认真敲代码. Lorem ipsum dolor sit amet consectetur adipisicing elit. Nulla alias tenetur ut velit ex voluptatibus consequatur quam exercitationem, assumenda ea blanditiis repudiandae? Repellendus tenetur nostrum asperiores molestias doloremque cupiditate maiores./diva href#查看全文 gt;gt; /a/div --/div/div/divscript srchttp://libs.baidu.com/jquery/2.0.0/jquery.min.js/scriptscript// 在页面加载的时候, 通过 ajax 给服务器发送数据, 获取到博客列表信息, 并且显示在界面上. function getBlogList() {$.ajax({type: get,url: blog,success: function(body) {// 获取到的 body 就是一个 js 对象数组, 每个元素就是一个 js 对象, 根据这个对象构造 div// 1. 先把 .right 里原有的内容给清空let rightDiv document.querySelector(.right);rightDiv.innerHTML ;// 2. 遍历 body, 构造出一个个的 blogDivfor (let blog of body) {let blogDiv document.createElement(div);blogDiv.className blog;// 构造标题let titleDiv document.createElement(div);titleDiv.className title;titleDiv.innerHTML blog.title;blogDiv.appendChild(titleDiv);// 构造发布时间let dateDiv document.createElement(div);dateDiv.className date;dateDiv.innerHTML blog.postTime;blogDiv.appendChild(dateDiv);// 构造博客的摘要let descDiv document.createElement(div);descDiv.className desc;descDiv.innerHTML blog.content;blogDiv.appendChild(descDiv);// 构造 查看全文let a document.createElement(a);a.innerHTML 查看全文 gt;gt;;// 此处希望点击之后能够跳转到 博客详情页 !!// 这个跳转过程需要告知服务器要访问的是哪个博客的详情页. a.href blog_detail.html?blogId blog.blogId;blogDiv.appendChild(a);// 把 blogDiv 挂到 dom 树上!rightDiv.appendChild(blogDiv);}}, error: function() {alert(获取博客列表失败!);}});}getBlogList();/script!-- 在这里引入上述的 js 文件, 就可以执行到里面的代码, 也就进行了登录状态的监测了 --script srcjs/common.js/scriptscript// 针对博客列表页, 调用的时候传入参数getUserInfo(blog_list.html);/script /body /html 此时需要在浏览器访问这个url地址可以观察到我们的博客系统页面blog_list http://127.0.0.1:8080/blog_system2/blog_list.html 接下来编写blog_detail.html文件的内容 !DOCTYPE html html langen headmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0title博客详情页/titlelink relstylesheet hrefcss/common.csslink relstylesheet hrefcss/blog_detail.css!-- 引入 editor.md 的依赖 --link relstylesheet hrefeditor.md/css/editormd.min.css /script srcjs/jquery.min.js/scriptscript srceditor.md/lib/marked.min.js/scriptscript srceditor.md/lib/prettify.min.js/scriptscript srceditor.md/editormd.js/script /head body!-- 这是导航栏 --div classnavimg srcimage/logo.jpeg altspan我的博客系统/span!-- 空白元素, 用来占位置 --div classspacer/diva hrefblog_list.html主页/aa hrefblog_edit.html写博客/aa hreflogout注销/a/div!-- 这里的 .container 作为页面的版心 --div classcontainer!-- 左侧个人信息 --div classleft!-- 表示整个用户信息区域. --div classcardimg srcimage/doge.png alth3/h3a href#github 地址/adiv classcounterspan文章/spanspan分类/span/divdiv classcounterspan2/spanspan1/span/div/div/div!-- 右侧内容详情 --div classright!-- 使用这个 div 来包裹整个博客的内容详情 --div classblog-content!-- 博客标题 --h3/h3!-- 博客的时间 --div classdate/div!-- 博客的正文内容 --div idcontent styleopacity: 80%/div/div/div/divscriptfunction getBlogDetail() {$.ajax({type: get,// location.search 拿到了形如 ?blogId5 这样的一段内容url: blog location.search,success: function(body) {// 根据 body 中的内容来构造页面// 1. 构造博客标题let h3 document.querySelector(.blog-contenth3);h3.innerHTML body.title;// 2. 构造博客发布时间let dateDiv document.querySelector(.date);dateDiv.innerHTML body.postTime;// 3. 构造博客正文// 如果直接把 content 设为 innerHTML, 此时展示在界面上的内容, 是原始的 markdown 字符串// 咱们需要的是渲染后的, 带有格式的效果// let content document.querySelector(#content);// content.innerHTML body.content;// 第一个参数对应 idcontent 的 html 标签. 渲染后得到的 html 片段就会被放到这个 标签下. editormd.markdownToHTML(content, {markdown: body.content});}});}getBlogDetail();// 加上一个逻辑, 通过 GET /login 这个接口来获取下当前的登录状态~function getUserInfo(pageName) {$.ajax({type: get,url: login,success: function(body) {// 判定此处的 body 是不是一个有效的 user 对象(userId 是否非 0)if (body.userId body.userId 0) {// 登录成功!// 不做处理!console.log(当前用户登录成功! 用户名: body.username);// 在 getUserInfo 的回调函数中, 来调用获取作者信息getAuthorInfo(body);} else {// 登录失败!// 让前端页面, 跳转到 login.htmlalert(当前您尚未登录! 请登录后再访问博客列表!);location.assign(blog_login.html);}},error: function() {alert(当前您尚未登录! 请登录后再访问博客列表!);location.assign(blog_login.html);}});}// 判定用户的登录状态getUserInfo(blog_detail.html);// 从服务器获取一下当前博客的作者信息, 并显示到界面上. // 参数 user 就是刚才从服务器拿到的当前登录用户的信息function getAuthorInfo(user) {$.ajax({type: get,url: authorInfo location.search,success: function(body) {// 此处的 body, 就是服务器返回的 User 对象, 是文章的作者信息if (body.username) {// 如果响应中的 username 存在, 就把这个值设置到页面上. changeUserName(body.username);if (body.username user.username) {// 作者和登录的用户是一个人, 则显示 删除按钮let navDiv document.querySelector(.nav);let a document.createElement(a);a.innerHTML 删除;// 期望点击删除, 构造一个形如 blogDelete?blogId6 这样的请求a.href blogDelete location.search;navDiv.appendChild(a);}} else {console.log(获取作者信息失败! body.reason);}}});}function changeUserName(username) {let h3 document.querySelector(.cardh3);h3.innerHTML username;}/script /body /html blog_login.html !DOCTYPE html html langen headmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0title登录页面/titlelink relstylesheet hrefcss/common.csslink relstylesheet hrefcss/blog_login.css /head body!-- 这是导航栏 --div classnavimg srcimage/logo.jpeg altspan我的博客系统/span!-- 空白元素, 用来占位置 --div classspacer/diva hrefblog_list.html主页/aa hrefblog_edit.html写博客/a!-- 注销按钮没必要在登录页面展示 --!-- a href#注销/a --/divdiv classlogin-containerform actionlogin methodpostdiv classlogin-dialogh3登录/h3div classrowspan用户名/spaninput typetext idusername nameusername/divdiv classrowspan密码/spaninput typepassword idpassword namepassword/divdiv classrow!-- button提交/button --input typesubmit idsubmit value提交/div/div/form/div /body /html 即这里在进入博客列表页/详情页的时候先检查一下用户的登录状态如果是用户已经登录才能够继续使用如果未登录则强制跳转到login界面 直接点击登录会出现以下提示 在controller包下创建一个新的java文件LoginServlet package controller;import com.fasterxml.jackson.databind.ObjectMapper; import model.User; import model.UserDao;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException;WebServlet(/login) public class LoginServlet extends HttpServlet {private ObjectMapper objectMapper new ObjectMapper();Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding(utf8);resp.setCharacterEncoding(utf8);// 1. 获取到请求中的参数String username req.getParameter(username);String password req.getParameter(password);System.out.println(username username , password password);if (username null || .equals(username) || password null || .equals(password)) {// 请求的内容缺失, 肯定是登录失败!!resp.setContentType(text/html; charsetutf8);resp.getWriter().write(当前的用户名或密码为空!);return;}// 2. 和数据库中的内容进行比较UserDao userDao new UserDao();User user userDao.selectByName(username);if (user null || !user.getPassword().equals(password)) {// 用户没有查到或者密码不匹配, 也是登录失败!resp.setContentType(text/html; charsetutf8);resp.getWriter().write(用户名或密码错误!);return;}// 3. 如果比较通过, 就创建会话.HttpSession session req.getSession(true);// 把刚才的用户信息, 存储到会话中.session.setAttribute(user, user);// 4. 返回一个重定向报文, 跳转到博客列表页.resp.sendRedirect(blog_list.html);}// 这个方法用来让前端检测当前的登录状态.Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType(application/json;charsetutf8);HttpSession session req.getSession(false);if (session null) {// 检测下会话是否存在, 不存在说明未登录!User user new User();resp.getWriter().write(objectMapper.writeValueAsString(user));return;}User user (User) session.getAttribute(user);if (user null) {// 虽然有会话, 但是会话里没有 user 对象, 也视为未登录.user new User();resp.getWriter().write(objectMapper.writeValueAsString(user));return;}// 已经登录的状态!!// 注意, 此处不要把密码给返回到前端user.setPassword();resp.getWriter().write(objectMapper.writeValueAsString(user));} } 这个代码里面会在服务器这边拿到了session并且视为也拿到了里面的user视为登录成功 若登录成功服务器会给客户端返回sessionid浏览器会保存这个sessionid下次请求的时候就带上这个id服务器拿到了sessionid就可以去hash表里查就可以知道当前的session对象是谁 注销功能 这里的注销其实就是退出登录的状态我们这里设计的是在导航栏里面给一个注销按钮当用户点击注销就会在服务器上取消登录状态并且能够跳转到登录页面 同样这里需要先约定前后端交互的接口 请求GET/logout 响应HTTP/1.1 302 Location:login.html 注销逻辑的服务器代码 在controller包下创建一个新的类LogoutServlet package controller;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException;WebServlet(/logout) public class LogoutServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 先找到当前用户的会话,HttpSession session req.getSession(false);if (session null) {// 用户没有登录!! 谈不上注销!resp.getWriter().write(当前用户尚未登录! 无法注销!);return;}// 然后把这个用户的会话中的信息给删掉就行了!!session.removeAttribute(user);resp.sendRedirect(blog_login.html);} } 运行实例 1当点击注销按钮时会直接回到登录页面 登录状态是啥样的 这里用户有一个session同时session有一个属性两者同时具备才算登录状态那么注销的话只要破坏上面任意一个条件即可这里选择的是把user属性从session中删除掉 发布博客 在博客编辑页中当用户输入了博客标题和正文之后点击发布此时就会把博客数据提交到服务器由服务器存储到数据库中 blog_edit.html !DOCTYPE html html langen headmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0title博客编辑页/titlelink relstylesheet hrefcss/common.csslink relstylesheet hrefcss/blog_edit.css!-- 引入 editor.md 的依赖 --link relstylesheet hrefeditor.md/css/editormd.min.css /script srcjs/jquery.min.js/scriptscript srceditor.md/lib/marked.min.js/scriptscript srceditor.md/lib/prettify.min.js/scriptscript srceditor.md/editormd.js/script /head body!-- 这是导航栏 --div classnavimg srcimage/logo.jpeg altspan我的博客系统/span!-- 空白元素, 用来占位置 --div classspacer/diva hrefblog_list.html主页/aa hrefblog_edit.html写博客/aa hreflogout注销/a/div!-- 包裹整个博客编辑页内容的顶级容器 --div classblog-edit-containerform actionblog methodpost styleheight:100%div classtitleinput typetext placeholder在此处输入标题 nametitle idtitle!-- button发布文章/button --input typesubmit value发布文章 idsubmit/div!-- 放置 md 编辑器 --div ideditor!-- 为了进行 form 的提交, 此处搞一个 textarea 多行编辑框, 借助这个编辑框来实现表单的提交 --!-- 可以设置 editor.md, 让编辑器把 markdown 内容也同步的保存到这个隐藏的 textarea 中, 从而可以进行 form 提交 --textarea namecontent styledisplay:none/textarea/div/form/divscript// 初始化编辑器let editor editormd(editor, {// 这里的尺寸必须在这里设置. 设置样式会被 editormd 自动覆盖掉. width: 100%,// 设定编辑器高度height: calc(100% - 50px),// 编辑器中的初始内容markdown: # 在这里写下一篇博客,// 指定 editor.md 依赖的插件路径path: editor.md/lib/,// 此处要加上一个重要的选项, 然后 editor.md 就会自动把用户在编辑器输入的内容同步保存到 隐藏的 textarea 中了!saveHTMLToTextarea: true,});/script /body /html 与之对应的在服务器代码中在BlogServlet中添加一个doPost方法来处理上述post请求 最终效果如下 OK以上就是个人博客系统的全部分析代码解析过程了感谢您的阅读项目源码已经放在文章开头如有需要可自取我们下期再见
http://www.dnsts.com.cn/news/41886.html

相关文章:

  • 有口碑的郑州网站建设安卓app用什么开发
  • 网站可以自己维护吗望野王维原文
  • 如何抄袭网站电子商务网站建设 试卷
  • 自己怎么优化我网站关键词微信crm系统如何添加
  • 虚拟主机怎么搭建网站销售管理系统实验报告
  • 重庆森林讲的什么内容企业网站建设网站优化推广
  • 潍坊市网站wordpress返利主题
  • 网站建设 数据归属wordpress idstore
  • 深泽网站制作做英文网站賺钱
  • 长春网站建设方案优化网站设计专业公司价格
  • 广州 环保 凡人网站建设上海网站建设公司兴田德润放心
  • phpcms网站音乐代码存放在什么位置常用的网站建设技术有什么软件
  • 那个网站做百科好过钉钉怎么注册企业
  • 创建手机网站模版盘龙网站建设
  • 校园网站设计方案黄页88网站推广方案
  • 阿瓦提网站建设中国突然宣布大消息
  • cvv钓鱼网站怎么做甘肃省建设局网站首页
  • 成品短视频app大全南京seo报价
  • 网站设计需求表郑州网站seo
  • 网站建设鼠标移动变颜色网站建设公司转型
  • 网站的论坛怎么做的网站建设哪几家公司好
  • 招生网站开发的背景深圳公司排名前50
  • 网站怎么添加假备案号网站窗口代码
  • 关于网站制作青岛在线建站排名公司
  • 制作网站的流程网站策划方案
  • 网站如何运营做兼职比较好的网站
  • 专业做网站较好的公司wordpress下载页面
  • 松江泗泾网站建设互联网设计一般是什么专业
  • 天峨县建设局网站网站头部特效
  • 企业招聘网站模板广州网站开发服务