万网的网站建设好吗php网站开发优势

pingmian/2026/1/25 4:05:28/文章来源:
万网的网站建设好吗,php网站开发优势,wordpress更换图片地址,图片压缩wordpress文章目录 一. 创建项目 引入依赖二. 设计数据库三. 编写数据库代码四. 创建实体类五. 封装数据库的增删查改六. 具体功能书写1. 博客列表页2. 博客详情页3. 博客登录页4. 检测登录状态5. 实现显示用户信息的功能6. 退出登录状态7. 发布博客 一. 创建项目 引入依赖 创建blog_sy… 文章目录 一. 创建项目 引入依赖二. 设计数据库三. 编写数据库代码四. 创建实体类五. 封装数据库的增删查改六. 具体功能书写1. 博客列表页2. 博客详情页3. 博客登录页4. 检测登录状态5. 实现显示用户信息的功能6. 退出登录状态7. 发布博客 一. 创建项目 引入依赖 创建blog_system项目.将之前写的博客系统前端代码复制到webapp目录下. 在pom.xml中引入Servlet mysql jackson三个依赖: pom.xml: ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactIdblog_system/artifactIdversion1.0-SNAPSHOT/versionpropertiesmaven.compiler.source8/maven.compiler.sourcemaven.compiler.target8/maven.compiler.target/propertiesdependenciesdependencygroupIdjavax.servlet/groupIdartifactIdjavax.servlet-api/artifactIdversion3.1.0/versionscopeprovided/scope/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion5.1.49/version/dependencydependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-databind/artifactIdversion2.14.2/version/dependency/dependencies /project二. 设计数据库 结合之前的需求,在当前博客系统中,主要涉及到两个实体.即 用户和博客. 经过分析我们可以得到,用户和博客之间是一对多的关系.即一个用户可以拥有多篇博客. 所以我们可以创建两张表,来表示用户和博客. blog(blogId,title,content,postTime,userId) user(userId,userName,password) 三. 编写数据库代码 把一些基本的数据库操作,先封装好. 需要手动粘贴至MySQL -- 这个文件主要用来写 建库建表 语句create database if not exists javaee_blog_system; use javaee_blog_system;-- 删除旧表,重新建表 drop table if exists user; drop table if exists blog;-- 创建表 create table blog(blogId int primary key auto_increment,title varchar(128),content varchar(4096),postTime datetime,userId int );create table user(userId int primary key auto_increment,username varchar(20) unique,-- 要求用户名和别人的不重复password varchar(20) );接下来是封装数据库的连接操作: DBUtil: import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource; import java.sql.*;public class DBUtil {private static DataSource dataSource new MysqlDataSource();static {((MysqlDataSource)dataSource).setUrl(jdbc:mysql://127.0.0.1:3306/javaee_blog_system?characterEncodingutf8useSSLfalse);((MysqlDataSource)dataSource).setUser(root);((MysqlDataSource)dataSource).setPassword(0828);}public static Connection getConnection() throws SQLException {return dataSource.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();}}} } 四. 创建实体类 实体类就是和表中的记录对应的类: blog表 Blog类对应Blog的一个对象,就对应表中的一条记录. user表 User类对应User的一个对象,就对应表中的一个记录. 实体类有哪些属性,都是和当前表中的列是密切相关的. User: public class User {private int userId;private String username;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;}private String password; } Blog: import java.sql.Timestamp;public class Blog {private int blogId;private String title;private String content;private Timestamp postTime;private int userId;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 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;} } 五. 封装数据库的增删查改 针对博客表,创建BlogDao;(Data Access Object) 针对用户表,创建UserDao. 上述Dao用来提供一些方法.来进行增删查改. BlogDao: 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 add(Blog blog){Connection connection null;PreparedStatement statement null;try {//1.和数据库建立连接connection DBUtil.getConnection();//2.构造SQLString sql insert into blog values(null,?,?,?,?);statement connection.prepareStatement(sql);statement.setString(1,blog.getTitle());statement.setString(2, blog.getContent());statement.setTimestamp(3,blog.getPostTime());statement.setInt(4,blog.getUserId());//3.执行SQLstatement.executeUpdate();} catch (SQLException e) {throw new RuntimeException(e);}finally {DBUtil.close(connection,statement,null);}}//2.根据博客id来查询指定博客(博客详情页)public Blog selectById(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();//4.遍历结果集合if(resultSet.next()){Blog blog new Blog();blog.setBlogId(resultSet.getInt(blogId));blog.setTitle(resultSet.getString(title));blog.setContent(resultSet.getString(content));blog.setPostTime(resultSet.getTimestamp(postTime));blog.setUserId(resultSet.getInt(userId));}} catch (SQLException e) {throw new RuntimeException(e);}finally {//5.释放资源DBUtil.close(connection,statement,resultSet);}return null;}//3.查询数据库中所有的博客列表(用于博客列表页)public ListBlog selectAll(){ListBlog blogs new ArrayList();Connection connection null;PreparedStatement statement null;ResultSet resultSet null;try {//1.与数据库建立连接connection DBUtil.getConnection();//2.构造sql语句String sql select * from blog;statement connection.prepareStatement(sql);//3.执行sqlresultSet statement.executeQuery();//4.遍历结果集合while (resultSet.next()){Blog blog new Blog();blog.setBlogId(resultSet.getInt(blogId));blog.setTitle(resultSet.getString(title));//正文部分不全显示 取出的正文只限制前一百字符String content resultSet.getString(content);if(content.length() 100){content content.substring(0,100) ...;}blog.setContent(content);blog.setPostTime(resultSet.getTimestamp(postTime));blog.setUserId(resultSet.getInt(userId));blogs.add(blog);}} catch (SQLException e) {throw new RuntimeException(e);}finally {DBUtil.close(connection,statement,resultSet);}return blogs;}//4.删除指定博客public void delect(int blogId){Connection connection null;PreparedStatement statement null;try {//1.与数据库建立连接connection DBUtil.getConnection();//2.构造sql语句String sql delete from blog where bolgId ?;statement connection.prepareStatement(sql);statement.setInt(1,blogId);//3.执行sqlstatement.executeUpdate();} catch (SQLException e) {throw new RuntimeException(e);}finally {//4.关闭资源DBUtil.close(connection,statement,null);}} } UserDao: import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException;//针对用户表提供的基本操作 public class UserDao {//1.根据 userId 来查用户信息public User selectById(int userId){Connection connection null;PreparedStatement statement null;ResultSet resultSet null;try {//1.与数据库建立连接connection DBUtil.getConnection();//2.构造sqlString sql select * from user where userId ?;statement connection.prepareStatement(sql);statement.setInt(1,userId);//3.执行SQLresultSet statement.executeQuery();//4.遍历结果集合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) {throw new RuntimeException(e);}finally {//5.释放资源DBUtil.close(connection,statement,resultSet);}return null;}//2.根据username来查找用户信息.public User selectByUsername(int username){Connection connection null;PreparedStatement statement null;ResultSet resultSet null;try {//1.与数据库建立连接connection DBUtil.getConnection();//2.构造sqlString sql select * from user where userId ?;statement connection.prepareStatement(sql);statement.setInt(1,username);//3.执行SQLresultSet statement.executeQuery();//4.遍历结果集合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) {throw new RuntimeException(e);}finally {//5.释放资源DBUtil.close(connection,statement,resultSet);}return null;} }六. 具体功能书写 1. 博客列表页 当前博客列表页上的数据都是写死的.正确的做法,应该是通过数据库读取数据显示到页面上. 此处就需要打通前后端交互的操作. 让博客列表页,在加载的时候,通过ajax给服务器发一个请求服务器查数据库获取到博客列表数据,返回给浏览器,浏览器再根据数据构造页面内容.这样的交互过程,也称为“前后端分离 前端只向后端请求数据,而不请求具体的页面,后端也仅仅是返回数据.这样的设定的目的就是为了前端和后端更加解耦,由浏览器进行具体的页面渲染.减少了服务器的工作量. 上述进行实现博客列表页的基本思路 接下来需要: 约定前后端交互接口开发后端代码开发前端代码 约定前后端交互接口 请求:GET /blog 响应:使用json格式的数据来组织 [{blogId:1,title:这是第一篇博客,content:从今天开始,我要认真学习,postTime:2023-08-01 09:40:45,userId:1}{blogId:1,title:这是第一篇博客,content:从今天开始,我要认真学习,postTime:2023-08-01 09:40:45,userId:1}{blogId:1,title:这是第一篇博客,content:从今天开始,我要认真学习,postTime:2023-08-01 09:40:45,userId:1} ]开发后端代码 BlogServlet: package api;import com.fasterxml.jackson.databind.ObjectMapper; import model.Blog; import model.BlogDao;import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List;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();//需要把blogs转成符合要求的 json 格式字符串String respJson objectMapper.writeValueAsString(blogs);resp.setContentType(application/json;charset utf8);resp.getWriter().write(respJson);} }此处注意文件所在位置.model是管理数据/操作数据的部分. 开发前端代码 在博客列表页加载过程中,触发ajax访问服务器中的数据.再把拿到的数据构造到页面中. !DOCTYPE html html langen headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title博客列表页/titlelink relstylesheet hrefcss/common.csslink relstylesheet hrefcss/blog_list.css /head body!-- 导航栏 --div classnavimg srcimage/logo2.jpg altspan classtitle我的博客系统/span!-- 用于占位,将a标签挤到右侧去 --div classspacer/diva href#主页/aa href#写博客/aa href#注销/a/div!-- 页面主体部分 --div classcontainer!-- 左侧信息 --div classcontainer-left!-- 使用.card表示用户信息 --div classcard!-- 用户头像 --img srcimage/touxiang.jpg alt!-- 用户名 --h3xxxflower/h3a href#github地址/adiv classcounterspan文章/spanspan分类/span/divdiv classcounterspan2/spanspan1/span/div/div/div!-- 右侧信息 --div classcontainer-right/div/divscript srchttps://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/jquery.min.js/scriptscript// 在页面加载时, 向服务器发起请求, 获取博客列表数据function getBlogs() {$.ajax({type: get,url: blog,success: function(body) {// 响应的正文 是一个 json 字符串, 此处已经被 jquery 自动解析成 js 对象数组了. // 直接 for 循环遍历即可. let containerRight document.querySelector(.container-right);for (let blog of body) {// 构造页面内容, 参考之前写好的 html 代码// 构造整个博客 divlet 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;;// 期望点击之后能跳转到博客详情页. 为了让博客详情页知道是点了哪个博客, 把 blogId 给传过去a.href blog_detail.html?blogId blog.blogId;blogDiv.appendChild(a);// 把 blogDiv 加到父元素中containerRight.appendChild(blogDiv);}}});}// 要记得调用getBlogs();/script /body /html效果如下图所示: 但是我们发现这里的时间显示有问题: 我们需要使用SimpleDateFormat类.注意该类使用时的书写格式! 2. 博客详情页 关于博客详情页,点击查看全文按钮,就能跳转到博客详情页中.跳转过去之后,在博客详情页中发起一个ajax,从服务器获取到当前的博客的具体内容.再进行显示. 分为以下几个步骤: 约定前后端交互接口实现后端代码实现前端代码 约定前后端交互接口 请求:GET/blog?blogId 1 响应: HTTP/1.1 200 OK { blogId:1, title:“这是第一篇博客”, content:“从今天开始我要认真学习”, postTime:“2023-08-01 17:00:00”, userId:1 } 实现后端代码 !DOCTYPE html html langen headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title博客详情页/titlelink relstylesheet hrefcss/common.csslink relstylesheet hrefcss/blog_detail.css /head body!-- 导航栏 --div classnavimg srcimage/logo2.jpg altspan classtitle我的博客系统/span!-- 用于占位,将a标签挤到右侧去 --div classspacer/diva href#主页/aa href#写博客/aa href#注销/a/div!-- 页面主体部分 --div classcontainer!-- 左侧信息 --div classcontainer-left!-- 使用.card表示用户信息 --div classcard!-- 用户头像 --img srcimage/touxiang.jpg alt!-- 用户名 --h3xxxflower/h3a href#github地址/adiv classcounterspan文章/spanspan分类/span/divdiv classcounterspan2/spanspan1/span/div/div/div!-- 右侧信息 --div classcontainer-right!-- 博客标题 --h3 classtitle/h3!-- 博客发布时间 --div classdate/div!-- 博客正文, 为了配合 editormd 进行格式转换, 此处务必改成 id --div idcontent/div/div/divscript srchttps://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/jquery.min.js/script!-- 要保证这几个 js 的加载在 jquery 之后. editor.md 依赖了 jquery --script srceditor.md/lib/marked.min.js/scriptscript srceditor.md/lib/prettify.min.js/scriptscript srceditor.md/editormd.js/scriptscript$.ajax({type: get,url: blog location.search,success: function(body) {// 处理响应结果, 此处的 body 就是表示一个博客的 js 对象. // 1. 更新标题let titleDiv document.querySelector(.container-right .title);titleDiv.innerHTML body.title;// 2. 更新日期let dateDiv document.querySelector(.date);dateDiv.innerHTML body.postTime;// 3. 更新博客正文// 此处不应该直接把博客正文填充到这个标签里editormd.markdownToHTML(content, { markdown: body.content });}})/script /body /html开发后端代码 package api;import com.fasterxml.jackson.databind.ObjectMapper; import model.Blog; import model.BlogDao;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();String blogId req.getParameter(blogId);if(blogId null){ListBlog blogs blogDao.selectAll();//需要把blogs转成符合要求的 json 格式字符串String respJson objectMapper.writeValueAsString(blogs);resp.setContentType(application/json;charset utf8);resp.getWriter().write(respJson);}else{// queryString 存在, 说明本次请求获取的是指定 id 的博客.Blog blog blogDao.selectById(Integer.parseInt(blogId));if (blog null) {System.out.println(当前 blogId blogId 对应的博客不存在!);}String respJson objectMapper.writeValueAsString(blog);resp.setContentType(application/json; charsetutf8);resp.getWriter().write(respJson);}} } 这是因为浏览器自身也有缓存机制. 浏览器从服务器这边获取页面,这个操作是通过网络传输完成的,速度是比较慢的.浏览器就会把页面给缓存到本地(客户端电脑的硬盘上).后续再访问同一个页面,就直接读缓存.但是这样做有一些问题,即客户端命中缓存之后就不一定能及时感知到变化. 解决方法:强制刷新.(无视缓存,100%重新访问服务器)Ctrl f5 3. 博客登录页 在此处输入用户名和密码,点击登录,就会触发一个http请求. 服务器验证用户名和密码,然后就可以根据结果,判定是否登录成功. 分为以下几个步骤: 约定前后端交互接口实现前端代码实现后端代码 约定前后端交互接口 请求: POST/login username zhangsanpassword 123 响应: HTTP/1.1 302 Location:blog_list.html 注意: 此处的响应应是from表单(本身就会触发页面跳转),响应是302才能够进行页面跳转. 如果是ajax请求(本身不会触发),响应是302,此时是无法进行跳转的. 实现前端代码 往页面上加入from表单,使得点击登录操作能够触发请求. !DOCTYPE html html langen headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0title博客登录页/titlelink relstylesheet hrefcss/common.csslink relstylesheet hrefcss/login.css /head body!-- 导航栏 --div classnavimg srcimage/logo2.jpg altspan classtitle我的博客系统/span!-- 用于占位,将a标签挤到右侧去 --div classspacer/diva href#主页/aa href#写博客/a/div!-- 正文部分 --!-- 贯穿整个页面的容器 --div classlogin-container!-- 垂直水平登录的对话框 --div classlogin-dialogform actionlogin methodposth3登录/h3div classrowspan用户名:/spaninput typetext idusername placeholder手机号/邮箱号 nameusername/divdiv classrowspan密码:/spaninput typepassword idpassword placeholder请输入密码 namepassword/divdiv classrowinput typesubmit idsubmit value登录/div/form/div/div /body /html注意此处对应的关系: 3. 修改后端代码 package api;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 {Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//设置请求的编码,使用 utf8 理解请求req.setCharacterEncoding(utf8);//设置响应的编码,使用 utf8 构造响应//resp.setCharacterEncoding(utf8);resp.setContentType(text/html;charsetutf8);//1.读取参数中的用户名和密码String username req.getParameter(username);String password req.getParameter(password);if(username null ||.equals(username) || password null ||.equals(password)){//登录失败String html h3登录失败!用户名/密码为空!/h3;resp.getWriter().write(html);return;}//2.读取数据库,查看用户名是否存在.密码是否匹配UserDao userDao new UserDao();User user userDao.selectByUsername(username);if(user null){//用户不存在String html h3登录失败!用户名或密码错误/h3;resp.getWriter().write(html);return;}if(!password.equals(user.getPassword())){String html h3登录失败!用户名或密码错误/h3;resp.getWriter().write(html);return;}//3.用户名密码验证通过,登录成功,接下来就创建会话,使用该会话保存用户信息HttpSession session req.getSession();session.setAttribute(user,user);//4.重定向,跳转到博客列表页resp.sendRedirect(blog_list.html);} } 4. 检测登录状态 实现让页面强制要求登录, 当用户访问博客列表页/详情页/编辑页,要求用户必须是已经登录的状态.如果用户还没登录,就会强制跳转到登录页面. 实现思路: 在页面加载的时候,专门发起一个新的 ajax . (一个页面里可以发N个ajax请求)以博客列表页为例,先会发一个请求获取博客列表,再发个ajax获取用户的登录状态,如果用户已登录,相安无事.如果未登录,则页面跳转到登录页. 约定前后端交互接口实现前端代码实现后端代码 约定前后端交互接口 请求:GET/login 响应: HTTP/1.1 200 OK { userId:1, username:‘xxxflower’ } 响应就把当前登录的用户信息返回回来了,如果未登录,就返回一个userld为0的user 对象 实现后端代码 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 user new User();String respJson objectMapper.writeValueAsString(user);resp.getWriter().write(respJson);return;}User user (User) session.getAttribute(user);if (user null) {user new User();String respJson objectMapper.writeValueAsString(user);resp.getWriter().write(respJson);return;}// 确实成功取出了 user 对象, 就直接返回即可.String respJson objectMapper.writeValueAsString(user);resp.getWriter().write(respJson);}开发后端代码: function checkLogin() {$.ajax({type: get,url: login,success: function(body) {if (body.userId body.userId 0) {// 登录成功!!console.log(当前用户已经登录!!);h3.innerHTML body.username;} else {// 当前未登录// 强制跳转到登录页. location.assign(login.html);}}});}checkLogin();将此代码粘贴至博客列表页 则效果如下: 5. 实现显示用户信息的功能 此处我们是写死的,我们希望这个地方可以动态生成. 如果是博客列表页,此处显示登陆用户的信息如果此处是博客详情页,此时显示的是该文章的作者 约定前后端接口 博客列表页:(复用监测登录状态的接口) 请求: GET /login 响应: HTTP/1.1 200 OK { userId:1, username:‘huang’, password:‘234’ } 由于是在监测登录的接口中直接写,所以后端代码不变,只需要微调前端代码即可 登录可以看到: 博客详情页:前后端交互接口 请求: GET/author?blogId 1 响应: HTTP/1.1 200 OK { userId:1, username:‘huang’, password:‘234’ }后端代码: package api;import com.fasterxml.jackson.databind.ObjectMapper; import model.Blog; import model.BlogDao; 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 java.io.IOException;WebServlet(/author) public class AuthorServlet extends HttpServlet {private ObjectMapper objectMapper new ObjectMapper();Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String blogId req.getParameter(blogId);if(blogId null){resp.setContentType(text/html;charset utf8);resp.getWriter().write(参数非法,缺少blogId!);return;}//根据 blog 查询Blog对象BlogDao blogDao new BlogDao();Blog blog blogDao.selectById(Integer.parseInt(blogId));if(blog null){resp.setContentType(text/html;charset utf8);resp.getWriter().write(没有找到指定博客);return;}//根据BLog中UserId 获取到对应的用户信息UserDao userDao new UserDao();User author userDao.selectById(blog.getUserId());String respJson objectMapper.writeValueAsString(author);resp.setContentType(application/json;charsetutf8);resp.getWriter().write(respJson);} } 前端代码: function getAuthor(){$.ajax({type:get,url:author location.search,success: function(body){//将username设置到页面上let h3 document.querySelector(.container-left .card h3);h3.innerHTML body.userId;}})}getAuthor();6. 退出登录状态 判断登录状态: 看是否能查到http session对象看session对象里面有没有user 实现退出登录: 处理HttpSession getSession能够创建/获取会话,但是没有删除会话的方法.但是我们可以通过设置过期时间来达到类似效果处理user(推荐) 可以通过removeAttribute来处理 约定前后端接口 请求: GET/logout 响应: HTTP/1.1 302 Location:login.html 实现后端代码: package api;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;WebServlet(/logout) public class LogoutServlet extends HttpServlet {Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {HttpSession httpSession req.getSession(false);if(httpSession null){//未登录,直接出错resp.setContentType(text/html;charsetutf8);resp.getWriter().write(当前未登录!);return;}httpSession.removeAttribute(user);resp.sendRedirect(login.html);} } 实现前端代码 修改博客列表页 ,博客编辑页的前端代码: 7. 发布博客 约定前后端交互接口 使用form表单:页面中更多了form标签,同时让form里面能够感知到博客的内容. 请求:POST/blog title标题content正文 响应:HTTP/1.1 302 Location:blog_list.html编写服务器代码 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 发布博客// 读取请求, 构造 Blog 对象, 插入数据库中即可!!HttpSession httpSession req.getSession(false);if (httpSession null) {resp.setContentType(text/html; charsetutf8);resp.getWriter().write(当前未登录, 无法发布博客!);return;}User user (User) httpSession.getAttribute(user);if (user null) {resp.setContentType(text/html; charsetutf8);resp.getWriter().write(当前未登录, 无法发布博客!);return;}// 确保登录之后, 就可以把作者给拿到了.// 获取博客标题和正文req.setCharacterEncoding(utf8);String title req.getParameter(title);String content req.getParameter(content);if (title null || .equals(title) || content null || .equals(content)) {resp.setContentType(text/html; charsetutf8);resp.getWriter().write(当前提交数据有误! 标题或者正文为空!);return;}// 构造 Blog 对象Blog blog new Blog();blog.setTitle(title);blog.setContent(content);blog.setUserId(user.getUserId());// 发布时间, 在 java 中生成 / 数据库中生成 都行blog.setPostTime(new Timestamp(System.currentTimeMillis()));// 插入数据库BlogDao blogDao new BlogDao();blogDao.add(blog);// 跳转到博客列表页resp.sendRedirect(blog_list.html);}客户端代码: !-- 编辑区的容器 --div classblog-edit-containerform actionblog methodpost styleheight: 100%;!-- 博客标题编辑区 --div classtitleinput typetext idtitle placeholder输入文章标题 nametitleinput typesubmit idsubmit value发布文章/div!-- 博客编辑器, 这里用 id 是为了和 markdown 编辑器对接, 而设置的 --div ideditortextarea namecontent styledisplay:none/textarea/div/form/div后续点击submit就能自动提交 display:none是隐藏元素.

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

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

相关文章

网站开发就业培训阐述网络营销策略的内容

戳蓝字“CSDN云计算”关注我们哦!作者 | 刘丹出品 | CSDN云计算(ID:CSDNcloud)随着技术的飞速发展,云数据库在云计算的大背景下,作为一种新兴的共享基础架构方法逐渐发展起来,它极大地增强了数据…

个人网站建设设计persona响应式博客wordpress主题

HTML&#xff08;超文本标记语言&#xff09;是构建Web页面的标准语言&#xff0c;它包含了许多标签&#xff0c;用于定义和排列页面内容。在Web开发中&#xff0c;显示图像是非常常见的需求之一&#xff0c;为此HTML提供了<img>标签来插入图像。本文将详细介绍HTML图片标…

wordpress多站点插件网站设计方案怎么写

Django配置静态文件 目录 Django配置静态文件静态文件配置调用方法 一般我们将html文件都放在默认templates目录下 静态文件放在static目录下 static目录大致分为 js文件夹css文件夹img文件夹plugins文件夹 在浏览器输入url能够看到对应的静态资源&#xff0c;如果看不到说明…

北京 网站设计 地址通州页面设计总结

微软公司主办的Build 2016大会尚在进程中&#xff0c;但是两场重量级的主题演讲已经结束。下面列举了我个人非常关注的几个细节&#xff0c;介绍一些背景知识以饲读者。 Bash on Windows背后的历史和未来 微软和IBM二十多年前联合开发NT内核的时候就已经为接驳多种操作系统留下…

淮北市矿业工程建设公司网站中山谷歌推广

前段时间学习二叉树在处理删除操作的时候遇到一个头疼的问题&#xff1a;删除节点的时候明明已经置null了可树上该节点依旧存在&#xff0c;还必须执行node.father.left null;才可以删除node节点&#xff0c;寻找了一下原因发现还是因为对java内存管理理解不够深入。代码如下&…

wordpress获取站点链接wordpress 推荐文章

在日常开发中&#xff0c;我们需要关注 .NET 应用的资源使用情况&#xff0c;方便排查问题和扩容。通过 Ajax 请求获取统计信息&#xff0c;展示成图表&#xff0c;如下图&#xff1a;CLRStats 插件&#xff0c;一个统计 .NET 应用资源使用情况的插件&#xff0c;包含&#xff…

北京网站开发哪家专业文明网站建设情况

更大的成功&#xff0c;不是看我们用双腿走了多少路&#xff0c;而是要看我们总共行了多少路。一只萤火虫&#xff0c;靠自身的力量发出了光芒。夜晚&#xff0c;它仰头望天&#xff0c;对着月亮说&#xff1a;“我是靠自己而发光的&#xff0c;而你却是借助太阳的光芒。虽然你…

网上制作公章seo网络推广技巧

这是我自己早前听课时整理的java基础全套知识 使用于初学者 也可以适用于中级的程序员 我做成了chm文档的类型 你们可以下载 笔记是比较系统全面&#xff0c;可以抵得上市场上90%的学习资料。讨厌那些随便乱写的资料还有拿出来卖钱的人&#xff01;在这里我免费的分享出来供…

小孩做阅读的网站有哪些大连网站建设开发

http://byandby.iteye.com/blog/814277转载于:https://www.cnblogs.com/hyzhou/p/3217022.html

扬州手机网站建设cpa广告网站怎么做

来源&#xff1a; 科学网作者&#xff1a;倪思洁“我们中国的GDP大概很快会实现世界第一&#xff0c;我们什么时候也能在纯科学方面对世界有重大贡献呢&#xff1f;”3月7日&#xff0c;全国人大代表、中科院院士、中科院高能物理研究所所长王贻芳在江苏代表团上发言说。王贻芳…

大良建网站免费建站免费网站

建立一个EXE工程&#xff0c;在窗体上放一个文本框&#xff0c;一个列表框和三个按钮输入如下的代码&#xff1a; Sub Form1_Command1_BN_Clicked(hWndForm As hWnd, hWndControl As hWnd)List1.AddItem(Text1.Text)End SubSub Form1_Command2_BN_Clicked(hWndForm As hWnd, h…

珠海门户网站建设哪家专业提升学历哪种方式含金量高

旧键盘上坏了几个键&#xff0c;于是在敲一段文字的时候&#xff0c;对应的字符就不会出现。现在给出应该输入的一段文字、以及实际被输入的文字&#xff0c;请你列出肯定坏掉的那些键。 输入格式&#xff1a; 输入在 2 行中分别给出应该输入的文字、以及实际被输入的文字。每段…

企业内部门户网站建设微网站设计平台

校验规则 注意: 变量名称可以由数字、字母、美元符号$ 或者 下划线_组成&#xff0c;但是不能包含空格或者以数字为开头。 闯关: 使用var 关键字来创建一个名为salePrice的变量。

网站建设的重要性 学校云服务器怎么发布网站

目录 需求实现讲解工具 - 图片旋转、base64 转换为 file 对象组件封装组件全局注册组件使用效果展示 需求 移动端需要实现手机横屏手写签名并上传签名图片功能。 实现讲解 vue-esign 插件文档地址 https://www.npmjs.com/package/vue-esign SignCanvas 组件封装原理&#xff1a…

网站建设0基础注册城乡规划师考试时间

RAW是指未经过任何压缩或处理的原始图像数据。在摄像头中&#xff0c;原始图像数据可以是来自图像传感器的未经处理的像素值。这些原始数据通常以一种Bayer模式的形式存在&#xff0c;其中每个像素仅包含一种颜色信息&#xff08;红色、绿色或蓝色&#xff09;&#xff0c;需要…

霸州做阿里巴巴网站设计方案步骤

概念 什么是逻辑删除 逻辑删除:假删除。将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录。 数据库实现思路:插入数据时,标记为未删除状态;查询、修改时,只获取未删除状态的数据进行操作;删除时则更新删除状态为已删除…

南油网站建设沈阳专业网站制作

1.最简单的路由配置 URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表&#xff1b;你就是以这种方式告诉Django&#xff0c;对于客户端发来的某个URL调用哪一段逻辑代码对应执行。 1.1 例1&#xff1a; 第一步&#xff1a;在…

重庆网站建设接重庆零臻科技大庆建设网站首页

如何解决Oracle数据库游标连接超出问题发布时间&#xff1a;2020-07-21 10:57:35来源&#xff1a;亿速云阅读&#xff1a;103作者&#xff1a;小猪这篇文章主要讲解了如何解决Oracle数据库游标连接超出问题&#xff0c;内容清晰明了&#xff0c;对此有兴趣的小伙伴可以学习一下…

宣城市市政建设集团公司网站执行信息公开网

来源&#xff1a;雷锋网作者 | 付静1 代表着首次&#xff0c;标志着政府与企业持续合作前往国际空间站的开始。终于&#xff0c;美国太空探索技术公司&#xff08;SpaceX&#xff09;的首次正式载人飞行任务拉开大幕&#xff01;美东时间 2020 年 11 月 15 日 19 时 27 分&…

合肥网站优化选哪家北京网站建设哪里好

文章目录 前言 1 用于ESP32的DroneBridge 2 推荐的硬件 3 下载和烧录固件 4 为ESP32配置DroneBridge 前言 ESP32 是现成的 Wi-Fi 模块&#xff0c;具有完整的 TCP/IP 协议栈和微控制器功能。它们提供专用的 UART、SPI 和 I2C 接口。它们可与任何 ArduPilot 自动驾驶控制器…