前后端分离实现博客系统
文章目录
- 博客系统
- 前言
- 1. 前端
- 1.1 登陆页面
- 1.2 博客列表页面
- 1.3 博客详情页面
- 1.4 博客编辑页面
- 2. 后端
- 2.1 项目部署
- 2.1.1 创建maven项目
- 2.1.2 引入依赖
- 2.1.3 创建目录结构
- 2.1.4 部署程序
- 2.2 逻辑设计
- 2.2.1 数据库设计
- 2.2.2 实体类设计
- 2.2.3 Dao层设计
- 2.2.3.1 BlogDao
- 2.2.4 Dao层设计
- 2.2.3 接口设计
- 2.2.3.1 登录接口
- 2.2.3.2 注销接口
- 2.2.3.3 作者查询接口
- 2.2.3.4 博客接口
- 2.2.3.4 删除博客接口
- 3. 小结
博客系统
前言
基于servlet+jdbc进行后端开发,设计了一个可以发布博客,查看博客详情,删除博客,登录注销功能的简易博客系统。
1. 前端
1.1 登陆页面
1.2 博客列表页面
1.3 博客详情页面
1.4 博客编辑页面
2. 后端
2.1 项目部署
2.1.1 创建maven项目
我们在idea里面点击new project创建一个maven项目,然后一路next选择好项目位置以及命名即可。
2.1.2 引入依赖
在创建完maven项目之后我们需要加载依赖,部分同学可能由于网络问题难以加载,可以多试几遍,实在不行可以更换国内的镜像下载此处不作多介绍。以下需要引入的依赖主要有:java.servlet-api、mysql-connector-java,以及后续发送json格式的数据需要的jackson依赖(jackson-databind)
我们通过maven仓库官网https://mvnrepository.com/ 即可获取。
如图:复制链接黏贴到我们项目的pom.xml文件
代码 : 以下是我部署的依赖可以直接复制黏贴
<dependencies>
<!-- servlet依赖--><!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency>
<!-- jackson依赖--><!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.14.2</version></dependency>
<!-- 数据库依赖--><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency></dependencies>
2.1.3 创建目录结构
在我们的webapp目录下面创建一个WEB-INF包并创建一个web.xml,此处结构以及名字不能改动。
web.xml内容:
<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app><display-name>Archetype Created Web Application</display-name>
</web-app>
2.1.4 部署程序
我们在插件市场搜索 Smart Tomcat 插件,将Tomcat集成到idea就不用我们手动打包,之后点击即可运行。
然后点击新增运行配置,将Smart Tomcat加入,此处选择Tomcat路径,如果还没有下载Tomcat,可以通过官网下载。博主使用的是 3.1版本的servlet+tomcat 8 。
然后就可以点击运行:出现以下结果就是部署成功了。之后我们就可以通过127.0.0.1:8080/MessageWall/xx.html(html页面)访问,其中MessageWall是Context path,一般默认是项目名。
2.2 逻辑设计
2.2.1 数据库设计
我们博客系统主要有用户登录以及编写博客的功能,基于此需求在当前博客系统中主要涉及两个实体,博客和用户,所以我们需要创建两张表用于存储博客和用户信息。
注意:用户与博客之间是一对多的关系;以下设计blog表和user表
- blog表包含blogId,title,content,postTime,userId属性;
- user表包含userId,userName,password;
- 通过userId建立关系,描述用户有哪些博客。
sql代码写到文本文件中用于记录,以便后续在别的机器上部署;
编写封装数据库的连接操作,代码如下:
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;/*** @author zq*/
public class DBUtil {private static DataSource dataSource = new MysqlDataSource();static {((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/blog_system?characterEncoding=utf8&useSSL=false");((MysqlDataSource) dataSource).setUser("root");((MysqlDataSource) dataSource).setPassword("123456");}public static Connection getConnection() throws SQLException {return (Connection) dataSource.getConnection();}public static void close(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet){if (resultSet!=null){try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (preparedStatement!=null){try {preparedStatement.close();} catch (SQLException e) {e.printStackTrace();}}if (connection!=null){try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}
}
2.2.2 实体类设计
根据我们用户表和博客表设计两个对应的实体类如下:
user类:
package model;/*** @author zq*/
public class User {private String username;private String password;private int 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;}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}
}
blog类:
package model;import java.sql.Timestamp;
import java.text.SimpleDateFormat;/*** @author zq*/
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 String getPostTime() {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");return simpleDateFormat.format(postTime);}public Timestamp getPostTimestamp(){return postTime;}public void setPostTime(Timestamp postTime) {this.postTime = postTime;}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}
}
2.2.3 Dao层设计
封装数据库的增删改查,针对博客表创建BlogDao,针对用户表创建UserDao并且提供对应的增删改查方法。
2.2.3.1 BlogDao
针对本项目我们需要的功能有发布博客,也就是在博客表新增一条数据;显示博客详情即根据博客id查询博客内容;删除博客即根据博客id删除博客;博客列表页即查询该用户发布的所有博客;
具体实现如下:
package model;import com.mysql.jdbc.Connection;
import model.Blog;
import model.DBUtil;import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;/*** @author zq*/
//针对博客表提供的基本操作,此处暂时不考虑修改
public class BlogDao {//1。新增一个博客public void add(Blog blog) {//1.先于数据库建立连接、Connection connection = null;PreparedStatement preparedStatement = null;try {connection = DBUtil.getConnection();//2.构造sql1语句String sql = "insert into blog values(null,?,?,now(),?)";preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1, blog.getTitle());preparedStatement.setString(2, blog.getContent());// preparedStatement.setTimestamp(3,blog.getPostTimestamp());preparedStatement.setInt(3,blog.getUserId());//3.执行sqlpreparedStatement.executeUpdate();} catch (SQLException e) {e.printStackTrace();}finally {DBUtil.close(connection,preparedStatement,null);}}//2.根据博客id查询指定博客,也就是页面的显示全文public Blog selectById(int blogId){Connection connection =null;PreparedStatement statement = null;ResultSet resultSet = null;try {//1.建立连接connection = DBUtil.getConnection();//2.构造sql语句String sql = "select * from blog where blogId = ?";statement = connection.prepareStatement(sql);statement.setInt(1,blogId);//3.执行sql语句resultSet = statement.executeQuery();//由于主键具有唯一性所以如果查到数据那么就只有一条//所以不需要用while遍历所有结果,判断是否有一条就行if (resultSet.next()){Blog blog = new Blog();blog.setBlogId(resultSet.getInt("blogId"));blog.setContent(resultSet.getString("content"));blog.setTitle(resultSet.getString("title"));blog.setUserId(resultSet.getInt("userId"));blog.setPostTime(resultSet.getTimestamp("postTime"));return blog;}}catch (SQLException throwables){throwables.printStackTrace();}finally {DBUtil.close(connection,statement,resultSet);}return null;}//3.直接查询数据库所有的博客列表(博客列表页)public List<Blog> selectAll(){Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;List<Blog> blogs = new ArrayList<>();try{//建立链接connection = DBUtil.getConnection();//构造sql语句String sql = "select * from blog order by postTime desc";statement = connection.prepareStatement(sql);//执行sqlresultSet = statement.executeQuery();while (resultSet.next()){Blog blog = new Blog();blog.setBlogId(resultSet.getInt("blogId"));//注意这里的正文内容在博客列表页,不需要全部显示出来String content = resultSet.getString("content");if (content.length()>=100){content = content.substring(0,100)+"....";}blog.setContent(content);blog.setTitle(resultSet.getString("title"));blog.setUserId(resultSet.getInt("userId"));blog.setPostTime(resultSet.getTimestamp("postTime"));blogs.add(blog);}}catch (SQLException throwables){throwables.printStackTrace();}finally {DBUtil.close(connection,statement,resultSet);}return blogs;}//4.实现删除指定博客public void delete(int blogId){Connection connection = null;PreparedStatement statement = null;try{//建立链接connection = DBUtil.getConnection();//构造sql语句String sql = "delete from blog where blogId =?";statement = connection.prepareStatement(sql);statement.setInt(1,blogId);//执行sqlstatement.executeUpdate();}catch (SQLException throwables){throwables.printStackTrace();}finally {DBUtil.close(connection,statement,null);}}
}
2.2.4 Dao层设计
本项目在设计用户表的主要功能,登录需要验证用户名与密码即根据用户名查询用户信息;主页右侧显示的用户信息即根据用户id查询用户信息;
具体实现:
package model;import com.mysql.jdbc.Connection;
import model.DBUtil;import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;/*** @author zq*/
//针对用户表提供的基本操作,由于没有写注册功能所以就不写add,
// 也没有注销功能,所以也不写delete
public class UserDao {//1.根据userID查询用户信息public User selecetById(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();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.根据用户名查询用户信息public User selectByUsername(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();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.2.3 接口设计
在前后端进行数据交互时我们约定以json格式进行数据传输,前端通过ajax向后端发送请求。
2.2.3.1 登录接口
创建一个LoginServlet类继承HttpServlet类,重写doPost()方法实现对用户密码的校验,重写doGet()方法进行用户是否登录校验,只有登录了的用户才能进行博客编辑。
具体实现如下:
package api;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;/*** @author zq*/@WebServlet("/login")
public class LoginServlet extends HttpServlet {private ObjectMapper objectMapper = new ObjectMapper();@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.读取用户名和密码,由于是form表单格式所以不用jackson的类进行读取//注意如果此处的用户名密码如果包含中文会乱码,所以要设置字符集req.setCharacterEncoding("utf8");resp.setContentType("text/html; charset=utf8");String username = req.getParameter("username");String password = req.getParameter("password");if (username==null||"".equals(username)||password==null||"".equals(password)){//登录失败String html = "<h3> 登陆失败username或者password错误 </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(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;charset=utf8");//获取用户的登录状态,如果用户未登录当前会话就拿不到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 = (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);}
}
2.2.3.2 注销接口
创建一个LogoutServlet类继承HttpServlet类,重写doGet()方法直接将session中的该用户移除,去除该用户缓存如何自动跳转到登录页面。
具体实现如下:
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;/*** @author zq*/
@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;charset=utf8");resp.getWriter().write("当前未登录");}//然后直接romovehttpSession.removeAttribute("user");//然后跳转到登录页面resp.sendRedirect("blog_login.html");}
}
2.2.3.3 作者查询接口
创建一个AuthorServlet类继承HttpServlet类,重写doGet()方法实现通过前端传输的用户id获取用户信息。
具体实现如下:
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;/*** @author zq*/
@WebServlet("/author")
public class AuthorServlet extends HttpServlet {private ObjectMapper objectMapper;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//博客详情页根据博客id获取用户,由于是queryString所以getParameter就能拿到String blogId = req.getParameter("blogId");if (blogId==null){resp.setContentType("text/html;charset=utf8");resp.getWriter().write("参数非法缺少blogID");return;}//根据·blogId查询blog对象BlogDao blogDao = new BlogDao();Blog blog = blogDao.selectById(Integer.parseInt(blogId));if (blog==null){//说明没找到resp.setContentType("text/html;charset=utf8");resp.getWriter().write("没有找到指定博客;blogId=" + blogId);}UserDao userDao = new UserDao();User author = userDao.selecetById(blog.getUserId());String respJson = objectMapper.writeValueAsString(author);resp.setContentType("application/json;charset=utf8");resp.getWriter().write(respJson);}
}
2.2.3.4 博客接口
创建一个BlogServlet类继承HttpServlet类,重写doGet()方法实现通过判断博客id是否存在确定获取所有博客还是博客详情,重写Post()方法实现博客发布功能。
具体实现如下:
package api;import com.fasterxml.jackson.databind.ObjectMapper;
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;/*** @author zq*/
//实现前后端交互的代码@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();//尝试获取一下queryString中的blogId字段String blogId = req.getParameter("blogId");if (blogId==null){//说明本次获取的是列表页List<Blog> blogs = blogDao.selectAll();//将blogs转成符合要求的json格式字符串String respJson = objectMapper.writeValueAsString(blogs);resp.setContentType("application/json;charset=utf8");resp.getWriter().write(respJson);}else {//存在,说明此处获取的是博客内容页//根据id查询博客Blog blog = blogDao.selectById(Integer.parseInt(blogId));//可能存在博客Id不存在的情况if(blog==null){System.out.println("当前blogId=" +blogId+ "对应的博客不存在");}String respJson = objectMapper.writeValueAsString(blog);resp.setContentType("application/json;charset=utf8");resp.getWriter().write(respJson);}}@Override //实现发布博客protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//读取请求,构造blog对象,插入数据库1即可HttpSession httpSession = req.getSession(false);if (httpSession==null){resp.setContentType("text/html;charset=utf8");resp.getWriter().write("当前未登录,无法发布博客");return;}User user = (User) httpSession.getAttribute("user");if (user==null){resp.setContentType("text/html;charset=utf8");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;charset=utf8");resp.getWriter().write("当前数据为空,无法发布博客");return;}//不为空时构造blog对象然后插入到数据库Blog blog = new Blog();blog.setContent(content);blog.setTitle(title);blog.setUserId(user.getUserId());BlogDao blogDao = new BlogDao();blogDao.add(blog);//blog里面的新增博客方法//跳转到博客列表页resp.sendRedirect("blog_list.html");}
}
2.2.3.4 删除博客接口
创建一个delBlogServlet类继承HttpServlet类,重写doGet()方法实现通过判断用户是否是登录并且用户是否是博客作者,确定是否能够删除博客。
具体实现如下:
package api;import com.fasterxml.jackson.databind.ObjectMapper;
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;/*** @author zq*/
@WebServlet("/delBlog")
public class delBlogServlet extends HttpServlet {//private ObjectMapper objectMapper;@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;charset=utf-8");resp.getWriter().write("当前未登录请登录");return;}//获取到当前用户User user = (User) session.getAttribute("user");//2.判断用户是否为空if (user==null){resp.setStatus(403);resp.setContentType("text/html;charset=utf-8");resp.getWriter().write("当前未登录请登录");return;}BlogDao blogDao = new BlogDao();//3.尝试获取一下queryString中的blogId字段,判断博客是否存在String blogId = req.getParameter("blogId");//查询到博客对象Blog blog = blogDao.selectById(Integer.parseInt(blogId));if (blogId==null){resp.setStatus(404);resp.setContentType("text/html;charset=utf8");resp.getWriter().write("博客数据不存在");return;}//4.判断登录用户是否是作者if (blog.getUserId()!= user.getUserId()){resp.setStatus(403);resp.setContentType("text/html;charset=utf-8");resp.getWriter().write("当前不能删除别人的博客");return;}//根据博客Id删除博客blogDao.delete(Integer.parseInt(blogId));resp.sendRedirect("blog_list.html");}
}
3. 小结
本项目可以在我的gitee上查看源码,后续会通过SSM框架重新实现并完善博客系统功能。https://gitee.com/zxxqqa/blog_system
相关文章:
![](https://img-blog.csdnimg.cn/081d798d6494410d91ed4b01370bba48.png)
前后端分离实现博客系统
文章目录 博客系统前言1. 前端1.1 登陆页面1.2 博客列表页面1.3 博客详情页面1.4 博客编辑页面 2. 后端2.1 项目部署2.1.1 创建maven项目2.1.2 引入依赖2.1.3 创建目录结构2.1.4 部署程序 2.2 逻辑设计2.2.1 数据库设计2.2.2 实体类设计2.2.3 Dao层设计2.2.3.1 BlogDao 2.2.4 D…...
![](https://www.ngui.cc/images/no-images.jpg)
面试题-TS(六):TypeScript 中的泛型是什么?
面试题-TS(6):TypeScript 中的泛型是什么? 在TypeScript中,泛型(Generics)是一种强大的特性,它允许我们在编写可重用的代码时增加灵活性。泛型使得我们可以编写不特定数据类型的代码,从而提高代…...
![](https://img-blog.csdnimg.cn/da71bd55015f4fc9935e7c8add5b6f84.png)
QT DAY4
1.思维导图 2.手动完成服务器的实现,并具体程序要注释清楚 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> #include <QTcpSocket> #include <QMessageBox> #include <QList> #include <QD…...
![](https://img-blog.csdnimg.cn/img_convert/cf8e1f9e3ca2e172dfbcc171b3b80d74.png)
最新Ai创作源码ChatGPT商用运营源码/支持GPT4.0+支持ai绘画+支持Mind思维导图生成
本系统使用Nestjs和Vue3框架技术,持续集成AI能力到本系统! 支持GPT3模型、GPT4模型Midjourney专业绘画(全自定义调参)、Midjourney以图生图、Dall-E2绘画Mind思维导图生成应用工作台(Prompt)AI绘画广场自定…...
![](https://www.ngui.cc/images/no-images.jpg)
一个go的支持多语言的error自动生成插件
大家好,我是peachesTao,今天给大家推荐一个go的支持多语言的error自动生成的插件,插件主页可以访问下方链接。 在一个多语言国际化的项目中,后端接口返回给前端的错误描述也需要国际化,我们来看一下后端给前端返回多语…...
![](https://img-blog.csdnimg.cn/079f0a6a7a604a308c564f41e454e34f.png)
wireshark抓包新手使用教程(超详细)
一、简介 Wireshark是一款非常流行的网络封包分析软件,可以截取各种网络数据包,并显示数据包详细信息。 为了安全考虑,wireshark只能查看封包,而不能修改封包的内容,或者发送封包。 wireshark能获取HTTP,也…...
![](https://img-blog.csdnimg.cn/eadf92906d584f7eb483c25b1e0db5aa.jpeg)
平均列顺序对列排斥能的影响
( A, B )---3*30*2---( 1, 0 )( 0, 1 ) 让网络的输入只有3个节点,AB训练集各由5张二值化的图片组成,让A有6个1,B有4个1,并且让这10个1的位置没有重合。比较迭代次数的顺序。 其中有9组数据 差值结构 A-B 迭代次数 构造平均列 …...
![](https://www.ngui.cc/images/no-images.jpg)
微信小程序-处理ios无法播放语音的问题
背景 框架:tarovue3 问题:今天搞小程序语音播放功能,开放工具播放正常,但是到ios手机上调试时无法播放,在网上找到个好办法 解决方案 核心代码 Taro.setInnerAudioOption({obeyMuteSwitch: false // 解决有一些IOS无…...
![](https://img-blog.csdnimg.cn/61632a02f5484c33bc6a12e221026f1f.png)
区块链 2.0笔记
区块链 2.0 以太坊概述 相对于比特币的几点改进 缩短出块时间至10多秒ghost共识机制mining puzzle BTC:计算密集型ETH:memory-hard(限制ASIC) proof of work->proof of stake对智能合约的支持 BTC:decentralized currencyETH:decentral…...
![](https://img-blog.csdnimg.cn/6e29286affb94acfb6308b1583f4da53.webp)
深入理解Vue响应式系统:数据绑定探索
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...
![](https://img-blog.csdnimg.cn/8e61b0b48dc148efb079035031dfed2c.jpg)
web流程自动化详解
今天给大家带来Selenium的相关解释操作 一、Selenium Selenium是一个用于自动化Web浏览器操作的开源工具和框架。它提供了一组API(应用程序接口),可以让开发人员使用多种编程语言(如Java、Python、C#等)编写测试脚本&…...
![](https://img-blog.csdnimg.cn/65e9ee3ba68d40449907a2e44308595f.png)
什么是框架?为什么要学框架?
一、什么是框架 框架是整个或部分应用的可重用设计,是可定制化的应用骨架。它可以帮开发人员简化开发过程,提高开发效率。 项目里有一部分代码:和业务无关,而又不得不写的代码>框架 项目里剩下的部分代码:实现业务…...
![](https://www.ngui.cc/images/no-images.jpg)
什么是 Sass?
Sass 介绍 什么是 Sass? 官方标语 世界上最成熟、最稳定、最强大的专业级 CSS 扩展语言。怎么理解这句话呢?我们平时写的 CSS 代码可以理解为静态样式语言,而 Scss 就是动态样式语言,何为动态?就是让你写 CSS 跟写 …...
![](https://img-blog.csdnimg.cn/fc5b35303fa04150b483aa7b7e6e9c9a.png#pic_center)
Kotlin~Memento备忘录模式
概念 备忘录模式是一种行为型设计模式,用于捕获和存储对象的内部状态,并在需要时将对象恢复到之前的状态。 备忘录模式允许在不暴露对象内部实现细节的情况下,对对象进行状态的保存和恢复。 角色介绍 Originator:原发器&#x…...
![](https://img-blog.csdnimg.cn/a19cf3bfa88e487bb085c66de6931203.png)
单链表的多语言表达:C++、Java、Python、Go、Rust
单链表 是一种链式数据结构,由一个头节点和一些指向下一个节点的指针组成。每个节点包含一个数据元素和指向下一个节点的指针。头节点没有数据,只用于表示链表的开始位置。 单链表的主要操作包括: 添加元素:在链表的头部添加新…...
![](https://www.ngui.cc/images/no-images.jpg)
微信小程序 background-image直接设置本地图片路径,编辑器正常显示,真机运行不显示解决方法
项目场景 微信小程序,设置background-image直接设置本地图片路径。 问题描述 编辑器正常显示,真机运行不显示 原因分析 background-image只能用网络url或者base64图片编码。 解决方案 1、将本地图片转为网络url后设置到background-image上 例如&…...
![](https://img-blog.csdnimg.cn/e7e5326423f4464b949165be43d5d940.png)
SQLite Studio 连接 SQLite数据库
1、在SQLite中创建数据库和表 1.1、按WINR,打开控制台,然后把指引到我们的SQLite的安装路径,输入D:,切换到D盘,cd 地址,切换到具体文件夹,输入“sqlite3”,启动服务 1.2、创建数据库…...
![](https://img-blog.csdnimg.cn/img_convert/082528a76b632fb017b38ab9aade2443.png)
【业务功能篇58】Springboot + Spring Security 权限管理 【中篇】
4.2.3 认证 4.2.3.1 什么是认证(Authentication) 通俗地讲就是验证当前用户的身份,证明“你是你自己”(比如:你每天上下班打卡,都需要通过指纹打卡,当你的指纹和系统里录入的指纹相匹配时&…...
![](https://img-blog.csdnimg.cn/c6046c1b93ff4e02b73c56511b451271.png)
Docker挂载目录失败问题解决
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...
![](https://www.ngui.cc/images/no-images.jpg)
css中隐藏页面中某一个元素有什么方法?
我们可以使用css的z-index属性,将元素的-index去给它设置一个负值,使它隐藏在其他元素的后面。使用css样式进行隐藏我们可以使用display这个属性。(1)使用display:none完全进行隐藏元素,并且不占据空间也不会影响页面布…...
![](https://www.ngui.cc/images/no-images.jpg)
Unity 多语言问题C#篇
DateTime.ToString()不同语言环境问题 问题描述:PlayerPrefs.SetString("timeKey", DateTime.Now.ToString());切换系统语言后DateTime.Parse(PlayerPrefs.GetString("timeKey"));报错FormatException: String was not recognized as a valid D…...
![](https://img-blog.csdnimg.cn/935070c2f0a54663baab64cff75b5495.png)
深度学习和神经网络
人工神经网络分为两个阶段: 1 :接收来自其他n个神经元传递过来的信号,这些输入信号通过与相应的权重进行 加权求和传递给下个阶段。(预激活阶段) 2:把预激活的加权结果传递给激活函数 sum :加权 f:激活…...
![](https://www.ngui.cc/images/no-images.jpg)
在CSDN学Golang云原生(Kubernetes Volume)
一,Volume 与 configMap Kubernetes 中的 Volume 和 ConfigMap 都是 Kubernetes 中常用的资源对象。它们可以为容器提供持久化存储和配置文件等。 Volume 可以将容器内部的文件系统挂载到宿主机上,也可以将多个容器间共享一个 Volume,并且 …...
![](https://www.ngui.cc/images/no-images.jpg)
第十五章 友元 异常和其他
RTTI RTTI是什么 RTTI是运行阶段类型识别,通过运行时类型识别,程序能够使用基类的指针或者引用来检查这些指针或者引用所指向的对象的实际派生类型。 RTTI的三个元素 dynamic_cast运算符 dynamic_cast概念: dynamic_cast运算符能够将基…...
![](https://img-blog.csdnimg.cn/31c6128b2f15480b9da46fa7e60bb3e2.png)
制作DBC文件
DBC文件是CAN通讯的密码本,Matlab的SimuLink中常用DBC作为CAN通讯的解析桥梁 制作DBC文件,内容是转速、位置&…...
![](https://img-blog.csdnimg.cn/f8174c4af80b4c5394c93421f7231a96.png)
【1.1】Java微服务:初识微服务
✅作者简介:大家好,我是 Meteors., 向往着更加简洁高效的代码写法与编程方式,持续分享Java技术内容。 🍎个人主页:Meteors.的博客 💞当前专栏: 微服务 ✨特色专栏: 知识分享 &#x…...
![](https://img-blog.csdnimg.cn/9c8cc90b0b904c108a74132ea2ffd216.png#pic_center)
数据结构--串、数组、广义表
这里写目录标题 串定义案例引用串的类型定义以及存储结构抽象类型定义存储结构(顺序表较为常用)顺序存储结构链式存储结构 串的模式匹配算法(查找主串中是否有某个字串)BF算法KMP算法设计思想对字串的回溯进行了优化代码对next【j】进行优化 数组类型一维…...
![](https://www.ngui.cc/images/no-images.jpg)
白银挑战——链表高频面试算法题
算法通关村第一关–链表白银挑战笔记 开始时间:2023年7月18日14:39:36 链表 Java中定义一个链表 class ListNode {public int val;public ListNode next;ListNode(int x) {val x;next null;}}1、四种方法解决两个链表第一个公共子节点 解释一下什么是公共节点 如…...
![](https://www.ngui.cc/images/no-images.jpg)
海外腾讯云账号:腾讯云高性能计算平台 THPC
高性能计算平台(TencentCloud High Performance Computing,THPC)是一款腾讯云自研的高性能计算资源管理服务,集成腾讯云上的计算、存储、网络等产品资源,并整合 HPC 专用作业管理调度、集群管理等软件,向用…...
![](https://img-blog.csdnimg.cn/983b84c0c5964ef89395ac81bc5743de.png)
eclipse 最新版没有navigator视图如何解决
使用project exploere视图可以显示类似navigator视图 1.显示project exploere视图 window---->show view --->project exploere 2.project exploere视图转换为类似navigator视图 第一步:点击视图右上角三个点或者倒三角,点击fiters and custom…...
![](/images/no-images.jpg)
武汉哪家推广公司靠谱/seo的优化技巧有哪些
(译者注:使用EF开发应用程序的一个难点就在于对其DbContext的生命周期管理,你的管理策略是否能很好的支持上层服务 使用独立事务,使用嵌套事务,并行执行,异步执行等需求? Mehdi El Gueddari对此做了深入研究…...
![](https://img-blog.csdnimg.cn/img_convert/9daaf10bb239eb944c46951d929b49db.png)
专业的美容网站建设/百度旧版本下载
慕仰8121524Go语言操作数据库非常的简单,他也有一个类似JDBC的东西"database/sql"实现类是"github.com/go-sql-driver/mysql"使用过JDBC的人应该一看就懂对日期的处理比较晦涩,没有JAVA流畅:复制代码代码如下:package mainimport ( "da…...
![](/images/no-images.jpg)
网站建设与管理是哪个软件/站长之家最新域名查询
我为vlookup开发了代码但是我在处理错误时遇到了麻烦 . Sheet1上的列的值正在Sheet2的列中查找 . 结果显示在Sheet3上 .有2个实例会出现错误:如果查找值列中的单元格为空如果查找值不在表数组中如果查找值的单元格为空,我希望结果显示空白 . 如果查找值不…...
![](/images/no-images.jpg)
python写网页/湖南企业竞价优化首选
1. 简介 语音模块用于语音消息的存取。 2. 类与接口 m_pInstance:单例句柄 m_strFileSite:语音文件路径static CAudioModel* getInstance():创建单例 void setUrl(string& strFileUrl):设置语音文件路径,若不是以…...
![](https://img-blog.csdnimg.cn/img_convert/3a607ff7cf693fb8d2d868ccf733079c.png)
营销网站定制/优化网站收费标准
我们程序员经常迷茫于有太多东西要学,有些找不到方向、不知所措。 很多程序员都愿意说,我想变得更好,但是更好是什么却很模糊,同时我们又不知道该怎么样去做。我们的生命如此短暂,作为程序员的职业生涯可能会更短。所…...
![](/images/no-images.jpg)
重庆营销型网站随做的好/百度品牌广告多少钱
Label 欧拉函数 Description 给定整数n(1≤n≤105)n(1\leq n\leq 10^5)n(1≤n≤105),求: ∑i1n∑j1ngcd(i,j)\sum_{i1}^{n}\sum_{j1}^{n}gcd(i,j)i1∑nj1∑ngcd(i,j) Solution 看上去此题所求又是一个反演的形式(其实此题可用反演解…...