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

网站建设课程设计目的和内容郑州网站建设专注乐云seo

网站建设课程设计目的和内容,郑州网站建设专注乐云seo,品牌设计的概念,个人设计网站论文摘要博客系统的具体实现 文章目录博客系统的具体实现软件开发的基本流程具体实现的八大功能数据库设计创建数据库操作数据库引入依赖封装DataSource创建实体类将JDBC增删改查封装起来实现博客列表页web.xml的配置文件实现博客系统的展示功能登录功能强制要求用户登录显示用户信息退…博客系统的具体实现 文章目录博客系统的具体实现软件开发的基本流程具体实现的八大功能数据库设计创建数据库操作数据库引入依赖封装DataSource创建实体类将JDBC增删改查封装起来实现博客列表页web.xml的配置文件实现博客系统的展示功能登录功能强制要求用户登录显示用户信息退出登录状态发布博客删除博客在Linux上部署博客系统安装jdk安装tomcat安装mysql使用yum安装必要的包启动正式部署在正式写后端程序之前,我已经将博客系统的前端最基本的页面写好,详情可以见我的gitee https://gitee.com/dengchuanfei/vscode_demo/tree/master/blog_system 软件开发的基本流程 可行性分析需求分析概要设计详细设计编码测试发布 具体实现的八大功能 实现博客列表的展示功能实现博客详情的展示功能登录功能强制用户登录显示用户的信息实现注销发布博客删除博客 数据库设计 写之前首先要进行规划要做到“谋定而后动” 首先进行“数据库设计”也就是想清楚需要几个库几张表每个表长啥样属性是干什么的是什么类型 需要找到实体然后分析实体之间的关联关系再思考表的属性 这里业务比较简单所以只需要两张表 博客表blog (blogId, tittle, content, postTime, userId) 用户表user (userId username password) 创建数据库 先建一个数据库往里面添加数据 -- 拿到的数据库很可能并不干净所以创建之前要确保之前没有同名的还要删除同名的注意这是十分危险的操作所以务必谨慎使用 create database if not exists java_blog_system; use java_blog_system; drop table if exists blog; -- 注意这里添加属性是使用() create table blog(blogId int primary key auto_increment,title varchar(256),content text,postTime datetime,--userId是文章作者的IDuserId int);drop table if exists user; create table user (userId int primary key auto_increment,username varchar(50),password varchar(50) ); -- 添加几个数据测试一下 insert into blog values(null,这是第一篇博客,从今天开始我要好好写代码好好上课,now(),1); insert into blog values(null,这是第二篇博客,我要好好写代码好好上课,now(),1);insert into user values(null, zhangsan,123); insert into user values(null, lisi,123);这里设计的content是text类型的text能放64KB的内容一般是够博客使用的了博客中的截图和博客文字不是存储在一起的所以不用担心截图放不下 注意 在SQL中的注释是 “-- ”在–后面还有一个空格 操作数据库 引入依赖 首先要先引入maven依赖在.xml的中引入依赖 去中央仓库中搜索servlet API3.1.0mysql connect Java5.1.49), jackson Databind(2.13.4.2)(将JSON格式进行转换) 封装DataSource 由于DataSource只有一份所以使用单例模式来实现会比较好 import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource; import javax.xml.crypto.Data; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement;//使用这个类来封装DataSource,使用单例模式(懒汉模式 多线程判断) //实现数据库的连接和断开 public class DBUtil {private static volatile DataSource dataSource null;public static DataSource getDataSource() {//第一次判断是否需要加锁if (dataSource null) {synchronized (DBUtil.class) { //针对类对象加锁//第二次判断是会否需要new对象if (dataSource null) {dataSource new MysqlDataSource();((MysqlDataSource)dataSource).setURL(jdbc:mysql://127.0.0.1:3306/java_blog_system?characterEncodingutf8useSSLfalse);((MysqlDataSource)dataSource).setUser(root);((MysqlDataSource)dataSource).setPassword(1111);}}}return dataSource;}//建立连接private static Connection getConnection() throws SQLException {return getDataSource().getConnection();}//关闭连接//建立连接的顺序是connection statement resultSet,所以关闭的顺序是反着的private static void close(Connection connection, Statement 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();}}}}在关闭资源的时候, 要是像这样直接使用依次try catch就会导致一旦上面的抛出异常,下面的就不会被执行到了,此时就会导致资源泄漏,很严重 要是使用的是throws相当于上面的情况,后面的代码还是不会执行,导致资源泄漏 所以还是应该 细分一下,多用几个try catch,来保证3个对象都关闭了 创建实体类 一个实体类对象就对应表中的一条记录 表中的属性怎么写,实体类就这么写 这里需要创建2个实体类 User 和 Blog 里面需要有属性和getter和setter方法, IDEA快捷键是alt fn insert import java.security.Timestamp;public class Blog {private int blogId;private String tittle;private String content;//mysql中的datetime和timestamp类型在java中都是使用Timestamp表示的private Timestamp postTime;private int userId;public int getBlogId() {return blogId;}public void setBlogId(int blogId) {this.blogId blogId;}public String getTittle() { return tittle;}public void setTittle(String tittle) {this.tittle tittle;}public String getContent() {return content;}public void setContent(String content) {this.content content;}public Timestamp getPostTime() {return postTime;}public void setPostTime(Timestamp postTime) {this.postTime postTime;}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId userId;} }public class User {private int userId;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;} }将JDBC增删改查封装起来 ​ 这里创建的是BlogDao和UserDao类,这里的DAO是 Data Acess Object 数据访问对象 也就是说访问数据库的操作就可以使用这几个DAO对象来进行 import java.sql.*; import java.util.ArrayList; import java.util.List; //封装关于博客的相关操作 public class BlogDao {//插入博客--发布博客public void insert(Blog blog) {Connection connection null;PreparedStatement statement null;//此处只要判断改变的行数是不是1就行了,所以没有resultSettry {//1.建立连接connection DBUtil.getConnection();//2.构造SQL//sql对应着blog的属性//blogId tittle content postTime userIdString sql insert into blog values (null, ? , ?, now(), ?);statement connection.prepareStatement(sql);statement.setString(1, blog.getTittle());statement.setString(2, blog.getContent());statement.setInt(3, blog.getUserId());//3.执行sqlint ret statement.executeUpdate();//executeUpdate的返回值是修改的行数if (ret ! 1) {System.out.println(博客插入失败!);} else {System.out.println(博客插入成功!);}//4.释放相关的资源--但是这里还是不适合,要是上面代码抛异常了,这里就会导致资源没有释放,资源泄露} catch (SQLException e) {e.printStackTrace();} finally{//方法哦finally就一定会执行到了,但是connection和statement是局部变量,所以就将这两个放到最外面,先置为nullDBUtil.close(connection, statement, null);//这里没有涉及到resultSet,所以填null}}//查询一个博客--博客详情页public Blog selectOne(int blogId) {Connection connection null;PreparedStatement statement null;ResultSet resultSet null;try {//1.建立连接connection DBUtil.getConnection();//2.构造SQLString sql select * from blog where blogId ?;statement connection.prepareStatement(sql);statement.setInt(1, blogId);//3.执行SQLresultSet statement.executeQuery();//遍历结果集合if (resultSet.next()) {Blog blog new Blog();blog.setBlogId(resultSet.getInt(blogId));blog.setTittle(resultSet.getString(tittle));blog.setContent(resultSet.getString(content));blog.setPostTime(resultSet.getTimestamp(postTime));blog.setUserId(resultSet.getInt(userId));return blog;}} catch (SQLException e) {e.printStackTrace();}finally {//关闭资源DBUtil.close(connection,statement,resultSet);}return null;//要是没有找到直接返回null就行}//查询所有博客--博客展示页public ListBlog selectAll() {ListBlog blogs new ArrayList();Connection connection null;PreparedStatement statement null;ResultSet resultSet null;try {//1.建立连接connection DBUtil.getConnection();//2.构造SQLString sql select * from blog;statement connection.prepareStatement(sql);//3.执行SQLresultSet statement.executeQuery();//遍历结果集合,这里使用的是while循环来寻找while(resultSet.next()) {Blog blog new Blog();blog.setBlogId(resultSet.getInt(blogId));blog.setTittle(resultSet.getString(tittle));blog.setContent(resultSet.getString(content));blog.setPostTime(resultSet.getTimestamp(postTime));blog.setUserId(resultSet.getInt(userId));blogs.add(blog);//将所有搜到的blog都添加到blogs中} } catch (SQLException e) {e.printStackTrace();}finally {//4.关闭资源DBUtil.close(connection,statement,resultSet);}return blogs;}//删除博客public void delete(int blogId) {Connection connection null;PreparedStatement statement null;try {//1.建立连接connection DBUtil.getConnection();//2.构造SQLString sql delete from blog where blogId ?;statement connection.prepareStatement(sql);statement.setInt(1, blogId);//3.执行sqlint ret statement.executeUpdate();//executeUpdate的返回值是修改的行数if (ret ! 1) {System.out.println(博客删除失败!);} else {System.out.println(博客删除成功!);}//4.释放相关的资源--但是这里还是不适合,要是上面代码抛异常了,这里就会导致资源没有释放,资源泄露} catch (SQLException e) {e.printStackTrace();} finally{//方法哦finally就一定会执行到了,但是connection和statement是局部变量,所以就将这两个放到最外面,先置为nullDBUtil.close(connection, statement, null);//这里没有涉及到resultSet,所以填null}} }import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException;public class UserDao {//根据用户名来查询用户--登录模块//隐含条件:用户名必须要是唯一的public User selectByName(String username) {Connection connection null;PreparedStatement statement null;ResultSet resultSet null;try {//1.建立连接connection DBUtil.getConnection();//2.构造SQLString sql select * from blog where username ?;statement connection.prepareStatement(sql);statement.setString(1, username);//3.执行SQLresultSet statement.executeQuery();//遍历结果集合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 e) {e.printStackTrace();}finally {//关闭资源DBUtil.close(connection,statement,resultSet);}return null;}//根据用户ID来查询用户--在获取用户信息的时候会用到public User selectById(int userId) {Connection connection null;PreparedStatement statement null;ResultSet resultSet null;try {//1.建立连接connection DBUtil.getConnection();//2.构造SQLString sql select * from blog where userId ?;statement connection.prepareStatement(sql);statement.setInt(1, userId);//3.执行resultSet statement.executeQuery();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 e) {e.printStackTrace();}finally {//4.关闭资源DBUtil.close(connection,statement,resultSet);}return null;} }将上面的几个函数的实现都看明白,其实JDBC的操作都是差不多的 下面主要是服务端和客户端的代码实现,由于服务端的代码比较长,就只有贴出核心功能的客户端代码 详细的客户端 服务端代码将会在文章最后给出 实现博客列表页 将之前写的前端代码复制到webapp目录下 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实现博客展示,是从数据库中读取数据,然后写到前端网页上 在博客列表页,需要做一个很重要的事情,页面在加载的时候通过ajax发起HTTP请求,从服务端获取到博客列表的数据 所以需要实现想好发什么样的请求,返回什么样的响----约定前后端接口 [请求] GET /blog[响应] [{blogId: 1,title: 第一篇博客,content: 博客正文,userId: 1,postTime: 2021-07-07 12:00:00},{blogId: 2,title: 第二篇博客,content: 博客正文,userId: 1,postTime: 2021-07-07 12:10:00},... ] 由页面发起请求,后服务端进行响应 import com.fasterxml.jackson.databind.ObjectMapper;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; import java.util.List;WebServlet(/blog) public class BlogServlet extends HttpServlet {private ObjectMapper objectMapper new ObjectMapper();Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {BlogDao blogDao new BlogDao();ListBlog blogs blogDao.selectAll();resp.setContentType(application/json;charsetutf8);resp.getWriter().write(objectMapper.writeValueAsString(blogs));} } 在之前已经写过blog_list.html页面上进行修改 !-- 发送ajax从服务端上获取数据 -- script srchttp://code.jquery.com/jquery-2.1.1.min.js/script script//在页面加载的时候通过ajax给服务端发送消息获取到博客列表信息并且显示在页面上function getBlog(){$.ajax({type:get,url:blog,success:function(body){//获取到的body就是一个js对象数组每个元素就是一个js对象根据这个对象来构造一个div//1.把原来.right里面原有的内容清空替换成从数据库服务端拿到的let rightDivdocument.querySelector(.container-right);rightDiv.innerHTML;//清空原有数据//2.遍历body构造出一个个blogDivfor(let blog of body){let blogDivdocument.createElement(div);//针对blogDiv设置一个属性类名设为blogblogDiv.classNameblog;//构造内部元素//构造标题let titleDivdocument.createElement(div);titleDiv.classNametitle;titleDiv.innerHTMLblog.title;//作为子元素添加进去blogDiv.appendChild(titleDiv);//构造发布时间let dateDivdocument.createElement(div);dateDiv.classNamedate;dateDiv.innerHTMLblog.postTime;blogDiv.appendChild(dateDiv);//构造摘要let descDivdocument.createElement(div);descDiv.classNamedesc;descDiv.innerHTMLblog.content;blogDiv.appendChild(descDiv);//链接 查看全文(这里用的是a标签)let adocument.createElement(a);a.innerHTML查看全文 gt;gt;;//希望点击后能跳转到博客详情页//跳转要告知哪个博客的详情页a.hrefblog_detail.html?blogIdblog.blogId;blogDiv.appendChild(a);//把blogDiv挂到dom树上rightDiv.appendChild(blogDiv);}},error:function(){alert(获取博客列表失败);}});}getBlog(); /script这里的时间很明显就是一个时间戳,并不直观,所以还是要改的,通过fiddler可以看到返回的响应就是时间戳的格式,所以也就是要将get方法的返回值变成String类型的时间格式 此处就要使用SimpleDateFormat类了 public String getPostTime() {//使用IDEA提供的原生的,返回的是时间戳,所以需要改一下返回值//使用SimpleDateFormat来将时间戳转换成指定的时间格式//这里的参数标准格式建议查一下,因为在不同的语言中表示放方式是不一样的SimpleDateFormat simpleDateFormat new SimpleDateFormat(yyyy-MM-dd HH:mm:ss);return simpleDateFormat.format(postTime);}时间的格式确实改好了,但是发现最上面的博客确实比较老的博客,不符合常规的博客展示思路 此时只要在BlogDao中将selectAll的搜索改成select * from blog order by postTime desc 按时间降序排列就行了 要是正文很长,在博客展示页就应该显示一部分文章,此时就对内容进行截断 在BlogDao 中进行content的判断和截断: String content resultSet.getString(content); if(content.length() 100){content content.substring(0,100) ......; } blog.setContent(content);实现博客系统的展示功能 在展示的时候,发送ajax请求来访问服务端,获取到服务端返回的响应之后,填充到博客的详情页面中 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();String blogId req.getParameter(blogId);if(blogId null){//说明是博客列表页发起的请求ListBlog blogs blogDao.selectAll();resp.getWriter().write(objectMapper.writeValueAsString(blogs));}else{//说明是博客详情页发起的请求Blog blog blogDao.selectOne(Integer.parseInt(blogId));resp.getWriter().write(objectMapper.writeValueAsString(blog));}} }客户端核心代码: function getBlog(){$.ajax({type:get,url:blog location.search,success : function(body){let h3 document.querySelector(.blog-detailh3);h3.innerHTML body.title;let dateDiv document.querySelector(.blog-detail.blog-date);dateDiv.innerHTML body.postTime; //方法1://let contentDiv document.querySelector(#content);//contentDiv.innerHTML body.content;//方法2://此处使用editor.md来进行渲染,主要是后面实现博客编辑的时候使用editormd.markdownToHTML(content, {markdown: body.content}); }});}getBlog();关于前端代码: 要是想显示具体的哪篇博客,就要知道具体的博客id,所以这里写URL的时候将location.search添加上去了为什么这里要使用方法2,而不是方法1,主要是因为博客是以markdown的形式来写的,所以渲染的时候也要以markdown格式来渲染 登录功能 所谓的登录功能就是在登录之后跳转到博客列表页 服务端代码: 其实登录操作就是先根据请求获取到用户输入的账号密码,之后进行判断,看看用户输入的账号密码是不是符合要求,要是符合的话,再查询数据库,要是账号密码都是正确的,就创建出一个会话,重定向到博客列表页 WebServlet(/login) public class LoginServlet extends HttpServlet {Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.获取用户名和密码req.setCharacterEncoding(utf-8);String username req.getParameter(username);String password req.getParameter(password);if (username null || username.equals() || password null || password.equals()) {//用户名或者密码不存在(为空)resp.setContentType(text/html;charset utf8);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;charset utf8);resp.getWriter().write(用户名或者密码错误,登录失败!);return;}//3.要是登录成功,就创建一个会话HttpSession session req.getSession(true);//在会话中保存user,方便后面知道当前的user是谁session.setAttribute(user, user);//4.构造302响应报文(重定向)resp.sendRedirect(blog_list.html);} }客户端核心代码: div classlogin-containerform actionlogin methodpost!-- 实现登录对话框 --div classdialogh3登录/h3div classrowspan用户名/spaninput typetextidusername name username/divdiv classrowspan密码/spaninput typepassword id password name password /divdiv classrowinput classlogin-btn value登录 type submit /div/div/form/div 强制要求用户登录 在博客系统中要求要先登录之后才能查看博客和编辑博客,所以要检查用户的登录状况,要是没有登录的话就自动跳转到登录页面 服务端核心代码: 首先要判断当前有没有创建出会话,要是当前存在session并且user也存在,说明已经登录了,就不进行操作,返回一个状态码200就行了,要是没有session或者user就说明当前没有登录,重定向到登录页面 Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.首先先获取一下会话//getSession的参数是false,就是说要是没有会话,也不用创建会话HttpSession session req.getSession(false);if(session null){//当前没有会话,说明没有登录resp.setStatus(403);return;}//为什么要判断user是否存在,其实还是会存在有session但是没有user对象这种情况的,这种情况会在后面退出登录的时候出现,所以此处一定要判断user对象是否存在User user (User) session.getAttribute(user);if (user null) {//说明此时虽然有会话,但是没有user对象,还是不行resp.setStatus(403);return;}//当前已经是登录状态,其实这行代码不写也行,但是写上更清楚resp.setStatus(200);}客户端核心代码 : function checkLogin() {$.ajax({type:get,url:login,success: function(body) {// 成功不做处理},error: function() {// 失败就会强行跳转到登录页面location.assign(login.html);}}) }显示用户信息 当李四登录进去之后看到张三的文章,之后点了进去,此时就要修改一下用户的信息 这里的服务端逻辑要分成两种情况: 要是当前用户是在博客列表页,登录的信息就在session中要是当前用户是在博客详情页中,就要求数据库中查询文章作者的信息 import com.fasterxml.jackson.databind.ObjectMapper;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(/userInfo) public class UserInfoServlet extends HttpServlet {private ObjectMapper objectMapper new ObjectMapper();Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//首先获取用户信息String blogId req.getParameter(blogId);//getParameter是用来获取表单中的值的,返回值是String,所以此时的blogId就变成了String类型if (blogId null) {//博客ID为0说明当前是在列表页,登录的用户信息在session里面,所以从session中拿getUserInfoFromSession(req,resp);}else{//存在博客ID说明当前是在博客展示页,要获取作者信息,就要查询数据库,不能从session中拿,因为文章作者可能不是自己,所以要从数据库中拿getUserInfoFromDB(req,resp, Integer.parseInt(blogId));//将blogId转换成int类型}}private void getUserInfoFromDB(HttpServletRequest req, HttpServletResponse resp, int blogId) throws IOException {//先根据blogId查询blog对象,获取到userId(作者是谁)// 根据user查询对应的User对象即可BlogDao blogDao new BlogDao();Blog blog blogDao.selectOne(blogId);if (blog null) {//这种情况是: blogId是随便写的,数据库中查不到,是不符合要求的resp.setStatus(404);resp.setContentType(text/html;charsetutf8);resp.getWriter().write(blogId不存在);return;}UserDao userDao new UserDao();User user userDao.selectById(blog.getUserId());if (user null) {resp.setStatus(404);resp.setContentType(text/html;charsetutf8);resp.getWriter().write(user不存在);return;}//排除了上面两种错误情况,接下来只有将user以JSON的形式返回就行了user.setPassword();resp.setContentType(application/json;charsetutf8);resp.getWriter().write(objectMapper.writeValueAsString(user));}private void getUserInfoFromSession(HttpServletRequest req, HttpServletResponse resp) throws IOException {//首先先获取会话HttpSession session req.getSession(false);if (session null) {resp.setStatus(403);resp.setContentType(text/html;charsetutf8);resp.getWriter().write(当前未登录!);return;}//获取user对象User user (User) session.getAttribute(user);if (user null) {resp.setStatus(403);resp.setContentType(text/html;charsetutf8);resp.getWriter().write(当前未登录!);return;}//在获取到user对象之后为了安全起见,将密码设置为空//以JSON的形式返回响应,所以要提前创建objectMapperuser.setPassword();resp.setContentType(application/json;charsetutf8);resp.getWriter().write(objectMapper.writeValueAsString(user));} }服务端核心代码: //针对博客列表页,获取到当前用户的信息function getUserInfo(){$.ajax({type:get,url:userInfo,success : function(body){//修改头像let h3 document.querySelector(.container-left.cardh3)h3.innerHTML body.username;}})}getUserInfo();退出登录状态 在页面上一个注销按钮,要求实现点击一下按钮就能退出当前的账号 服务端代码: 后端服务端在收到请求之后,将当前会话的信息删除,然后重定向到登录页面即可 //实现注销功能(退出登录状态) 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.setStatus(403);return;}//删除user对象,并重定向到登录页面session.removeAttribute(user);resp.sendRedirect(login.html);} } 这里需要注意的是: 在登录状态下,既有session又有user属性,要是想要删除用户的信息,只要删除其中一个就行了,但是这里选择的是删除user属性,因为没有提供删除session的api,并不是很好删除session 服务端代码: a hreflogout注销/a只要将注销按钮变成一个链接形式即可 发布博客 发布博客的意思是在用户写完博客之后,点击提交按钮,服务端收到请求之后,在数据库中添加一条记录,并且在最后还会跳转到博客列表页 有一个前提: 用户要写上了标题和正文之后点击提交按钮才能提交 所以还要判断一下是否用户写了标题和正文 服务端代码: 接着在原本的BlogServlet类中写 Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//使用这个post方法来实现创建新的博客//1.检查一下用户的登录状态和用户信息,要是未登录就不能创建新的博客HttpSession session req.getSession(false);if (session null) {resp.setStatus(403);resp.setContentType(text/html;charsetutf8);resp.getWriter().write(当前未登录,不能创建博客!);return;}//检查是否存在user对象User user (User) session.getAttribute(user);if (user null) {resp.setStatus(403);resp.setContentType(text/html;charsetutf8);resp.getWriter().write(当前未登录,不能创建博客!);return;}//2.当前已经登录,获取请求的参数(博客的标题和内容)req.setCharacterEncoding(utf8);//将请求变成utf8的格式,防止乱码String title req.getParameter(title);String content req.getParameter(content);//3.构造Blog对象,并插入到数据库中Blog blog new Blog();blog.setTitle(title);blog.setContent(content);//博客的blogId是自增主键,所以不用专门指定设置,postTime是now()函数,所以也不用指定blog.setUserId(user.getUserId());BlogDao blogDao new BlogDao();blogDao.insert(blog);//4.插入新的博客之后重定向到博客列表页resp.sendRedirect(blog_list.html);//有一个疑问:前面已经实现了未登录状态下是不能进入博客编辑页的,那么此时为什么还要先判断一下是否登录呢?//1.要是有人使用postman直接构造post请求,直接绕开了登录,插入数据怎么办?//2.在上面的代码中,要想给新的博客设置userId需要使用user.getUserId(),所以前面要保证存在user对象//结合上面的两点理由,加上登录判断是很有必要的 }客户端核心代码: 使用form表单来提交请求 !-- 这个编辑页的版心 --div classblog-edit-container styleheight: 100%!-- 套上一个form标签 --form actionblog methodpost styleheight: 100%!-- 标题的编辑区 --div classtitleinput typetext id blog-title placeholder请在这里输入文章的标题 name titleinput id submit value发布文章 typesubmit /div!-- 正文的编辑区 --div id editor!-- editor.md规定,要想使用form表单来提交数据,就要按照下面的标准来写 --textarea namecontent styledisplay: none/textarea/div/form/div删除博客 要是想要删除博客,在不考虑管理员的情况下,只能由博客的作者自己来删除 所以就要判断当前登录的用户是不是博客的作者,要是不是的话,他是没有权限删除别人的博客的 在删除之后还要重定向到博客列表页 服务端代码: 主要的思路就是看看博客作者id和登陆者id是不是一样的,要是一样的,就有权限去删除博客 但是在此之前,还有很多要考虑的 当前用户是否已经登录?(这个问题是要考虑的,前面已经解释过)客户端传过来的blogId是否可能是null(前端没有传过来blogId)传过来的blogId是否可能不存在(客户端传了blogId,但是在服务端这边根本就没有) 在经历了上面的错误情况之后,就是客户端传来正确的blogId,服务端也有对应的博客作者的id,此时只要对比一下登录用户id和博客作者id即可 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(/blog_delete) public class BlogDeleteServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.先判定用户的登录状态HttpSession session req.getSession(false);if (session null) {resp.setStatus(403);resp.setContentType(text/html;charsetutf8);resp.getWriter().write(您当前未登录,不能删除博客!);return;}User user (User) session.getAttribute(user);if (user null) {resp.setStatus(403);resp.setContentType(text/html;charsetutf8);resp.getWriter().write(您当前未登录,不能删除博客 !);return;}//能走到这一步,说明已经是登录状态了//2.获取到blogIdString blogId req.getParameter(blogId);if (blogId null) {//说明这个blogId为空,这种情况是前端没传blogIdresp.setStatus(403);resp.setContentType(text/html;charsetutf8);resp.getWriter().write(您当前要删除的blogId有误!);return;}//3.查询这个blogId对应的blog作者BlogDao blogDao new BlogDao();Blog blog blogDao.selectOne(Integer.parseInt(blogId));if (blog null) {//此时是存在一个blogId,但是它并没有对应的文章,这种情况是前端传了blogId,但是后端没有对应的数据resp.setStatus(404);resp.setContentType(text/html;charsetutf8);resp.getWriter().write(您当前要删除的博客不存在! blogId blogId);return;}//观察上面的四个if可以感受到,这就是在排错,先将错误的情况都写出来,起到过滤的作用.//4.判断登录用户是不是文章作者if (blog.getUserId() ! user.getUserId()) {//blog.getUserId是当前文章的作者//user.getUserId是从session中拿的登录用户信息//要是不一样,直接返回403,并且提示resp.setStatus(403);resp.setContentType(text/html;charsetutf8);resp.getWriter().write(您不能删除别人的博客!);return;}//5.真正执行删除操作//将String类型的blogId转换成int类型的,准备删除blogDao.delete(Integer.parseInt(blogId));//6.返回302,重定向到博客列表页,要是失败就提示失败resp.sendRedirect(blog_list.html);} } 客户端核心代码: function upDateDeleteURL(){// 这里的location.search就是?blogId?//可以在网页开发者工具的console中输入查看let deleteBtn document.querySelector(#delete-btn);deleteBtn.href blog_delete location.search;}upDateDeleteURL();在Linux上部署博客系统 在完成了博客系统之后,只是可以在自己的电脑上查看博客系统, 别人还是看不到的,所以要借助公网ip来让所有人都能访问博客系统 要是想要部署java web程序,首先要配置环境 jdk tomcat mysql 安装jdk 推荐的方法是使用yum直接安装openjdk(开源的,与官方的jdk功能差不多),目前使用的最多的就是jdk8系列 yum list | grep jdk 在源上搜索所有关于jdk的文件 devel表示development的意思,就是软件开发包 后面的x86_64的意思是支持64位的系统 选中之后按ctrl insert来复制,之后使用yum install 粘贴(shift insert ) 就下载好了 安装tomcat 当前的程序使用的是tomcat8.5的版本,但是使用yum list | grep tomcat 并没有8.5版本(当前的centos7系统有点老) 此时有一个好方法,找到之前的tomcat压缩包,直接拖到Linux上就能安装,主要是因为tomcat是java写的,能跨平台 注意: 在拖压缩包之前,要确认压缩包是不是zip格式的,因为Linux默认不支持rar格式的压缩包,只支持zip格式 可能会出现拖不过去的情况,此时就要安装一个lrzsz, yum insatll lrzsz 之后就能将tomcat的压缩包拖过去了 之后进行解压,需要使用unzip ,所以要先安装unzip, yum insatll unzip 之后进行解压 unzip apache apache-tomcat-8.5.85.zip(后面的文件可以用TAB来补全) 进入到tomcat的bin目录下,就可以看到启动的脚本 在Windows上使用的是startup.bat,但是在Linux上使用的是startup.sh 要想启动这里的程序,首先要赋予他们可执行权限,也就是chmod x *.sh, 之后后面的文件就会变成绿色,表示可以执行 启动tomcat的过程: 下载安装包(要是zip格式的压缩包)上传压缩包到Linux上(要使用到 lszrz命令)解压缩(要使用到unzip 命令)进入Tomcat目录的bin目录给启动脚本增加可执行权限(chmod x *.sh) --此时.sh的文件就会变成绿色使用 sh startup.sh来启动 tomcat 验证tomcat是否启动成功 通过ps aux | grep tomcat来查看进程 通过nststat -anp | grep 8080 查看端口号是否被绑定 tomcat也是用java写的,所以此时8080已经被tomcat绑定了 还有一种验证tomcat是否启动的方式,就是直接访问tomcat的欢迎页面 公网IP地址:8080 但是大概率是不能访问的,这是因为云服务器的防火墙或者安全组没有对8080允许访问,所以要去云服务器那边手动添加一个8080端口号的规则 添加完8080端口号的规则之后就能正常访问tomcat的欢迎页面 但是在平时的时候还是不要开启端口号规则,防止服务器被攻击 安装mysql linux安装mysql有很多的方式,最简单的一种安装方式是使用yum 安装mariadb(开源的,是mysql的孪生兄弟) 使用yum安装必要的包 直接执行这几个命令就行了 yum install -y mariadb-serveryum install -y mariadbyum install -y mariadb-libsyum install -y mariadb-devel启动 启动mariadb服务 systemctl start mariadb设置服务自启动 systemctl enable mariadb查看服务的状态 systemctl status mariadb验证是否连接上 mysql -uroot这样子就是连接成功了 创建数据库的时候为了支持中文,这里统一使用utf8mb4字符集 create database demo_db charset utf8mb4;此时就将mariadb安装连接好了 正式部署 在安装好了jdk tomcat mysql之后,就可以开始将博客系统部署到云服务器上 首先要理清楚 博客系统的依赖,先将依赖的内容打通 将博客系统的程序打包, 将war包上传到云服务器的webapps目录下即可 在我的博客系统中的依赖就是mysql,必须要知道的是,本地的电脑上的数据库与云服务器上的数据库是两台不一样的电脑,所以本地的数据库有数据,但是云服务器上的数据库还没有数据 所以此时要将SQL指令在云服务器上输入(粘贴)一下 进入mariadb 的命令: mysql -uroot,退出mariadb: ctrl c 在开始打war包之前要先调整一下DBUtil的代码,主要就是要调整一下连接数据库的代码 需要将这里的密码设置成云服务器的数据库的密码,要是没有单独设置过云服务器上的密码,那么就是空字符串 这里的setURL也基本上不用改,因为云服务器也是在我主机上的,所以还是可以使用环回IP, 后面的3306端口号也是不用改的 打war包的时候 改好之后双击maven的package就好了 打好war包之后找到war包 在Linux上进入到apache tomcat目录中,在进入webapps目录中 将之前打好的war包拖到webapp下面 之后就会自动进行解压缩和部署,变成蓝色的了 要是之后修改了代码,务必要重新打包,重新上传 部署(也叫上线)是一个很重要,很有仪式感的事情,所以一定要小心谨慎! 此时就已经是部署完毕了! 注意: 要是发现网页打不卡,先检测一下tomcat的欢迎页面能不能打开,要是不能打开说明是tomcat8080端口被阻止了,就要去云服务器那边将防火墙新增8080端口的规则 要知道本地电脑上能运行,不能说明部署到云服务器上就能成功 此时我出现了一个问题,那就是mariadb上的中文乱码,但是我在建库的时候已经指定了utf8mb4字符集,最后我发现还要在建表的时候也要指定字符集 要是修改了任何代码都要重新使用maven双击package重新打war包 再把之前Linux上的war删除,再把新的war包拖进去,就能重新部署 此时,就正式完成了博客系统的简单功能实现和部署 博客系统的源码(服务端客户端)
http://www.dnsts.com.cn/news/157103.html

相关文章:

  • 大学生兼职网站开发广州去东莞回来要隔离吗
  • 利用js做网站erp软件是干嘛的
  • 网站建设 自学 电子版 pdf下载西城h5网站建设
  • 网站开发带后台创建公司网站 优帮云
  • 给新公司建网站wordpress栏目图标
  • 中山市建设工程 交易中心网站网站代做发布需求
  • 别人做的网站自己想更新网站的二级菜单怎么做
  • 网站板块设置做室内设计的网站
  • 做网站至少多少钱2018年怎样做淘宝客网站
  • 合肥百姓网网站建设十堰做网站最专业的公司
  • 郑州网站制作公司排名关于建设公司网站的申请
  • 如何把优酷视频放到网站上扬州市城乡建设网站
  • 自己做视频网站收益怎么来网站开发成本会计科目
  • 网站建设需要了解哪些方面做系统去哪个网站
  • 网站配色风格有哪些sem推广培训
  • 兰州网站网页专题设计
  • 微网站预约网站开发如皋市网站建设
  • 盐城网站制作网络推广it外包企业
  • 国内顶尖设计椅子图片无锡网站建设优化公司
  • 中医院网站源码深圳做微网站
  • 网站建设百度推广说词网页制作平台排行榜
  • 天津建设网站c2成绩查询wordpress主题:yusi
  • 汉口网站建设 优帮云网站建设的实验结论
  • 做网站用什么配置笔记本湖南长沙最新情况
  • 企业信息平台登录乐至seo
  • seo公司网站推广制作一个app
  • 软件开发定制seo关键词优化外包公司
  • 中小企业网站建设价格广东省建设信息中心
  • 为自己网站建设设计公司推广渠道
  • 四川省建设监理协会网站wordpress 问答模版