【Spring练习项目】博客系统

目录

  • 1.项目展示
  • 2.项目结构设计
  • 3.项目功能设计
  • 4 数据库准备
    • 4.1 建表
    • 4.2 DB相关数据
  • 5.项目模块
  • 6.添加项目公共模块
    • 6.1 common
    • 6.2 实现前端界面
  • 7.功能实现
    • 7.1实现博客列表
      • 约定前后端交互接口
      • 实现服务器代码
      • 实现客户端代码
    • 7.2实现博客详情
      • 约定前后端交互接口
      • 实现服务器代码
      • 实现客户端代码
    • 7.3实现登录
      • 约定前后端交互接口
      • 实现服务器代码
      • 实现客户端代码
    • 7.4实现强制要求登录
      • 添加拦截器
      • 实现客户端代码
    • 7.5实现显示用户信息
      • 约定前后端交互接口
      • 实现服务器代码
    • 7.6实现用户退出
      • 约定前后端交互接口
      • 实现服务器代码
      • 实现客户端代码
    • 7.7实现发布博客
      • 约定前后端交互接口
      • 实现服务器代码
      • 实现客户端代码
    • 7.8实现删除/编辑博客
      • 约定前后端交互接口
      • 实现服务器代码
      • 实现客户端代码
    • 7.9实现加密加盐
      • 加密工具类
      • 使用
      • 修改数据库密码

1.项目展示

项目已经发布到云服务器上,想要使用的小伙伴可以点击下面这个链接:

博客项目

由于目前没有实现注册功能,所以这里直接提供一个账号,用以登录:

账号:lisi
密码:123456

2.项目结构设计

后端框架:SpringBoot
数据库:mybatis
前后端交互:ajax

3.项目功能设计

主要功能如下图所示:

在这里插入图片描述

一共四个页面:
在这里插入图片描述
登录页面:

在这里插入图片描述

博客列表页面:

在这里插入图片描述
博客详情页:
在这里插入图片描述

写博客页面:

在这里插入图片描述

4 数据库准备

4.1 建表

一共两张表:

  • user(用户表)

  • blog(博客表)

在这里插入图片描述

创建数据库:

create database if not exists `java_blog_spring` charset utf8mb4;

创建user表:

drop table if exists `java_blog_spring`.`user`;
CREATE TABLE `java_blog_spring`.`user` (`id` INT NOT NULL AUTO_INCREMENT,`user_name` VARCHAR(128) NOT NULL,`password` VARCHAR(128) NOT NULL,`github_url` VARCHAR(128) NULL,`delete_flag` TINYINT(4) NULL DEFAULT 0,`create_time` TIMESTAMP NULL DEFAULT current_timestamp(),PRIMARY KEY (`id`),UNIQUE INDEX `user_name_UNIQUE` (`user_name` ASC))
ENGINE = InnoDB DEFAULT CHARACTER SET = utf8mb4 COMMENT = '⽤户表';

创建blog表:

drop table if exists `java_blog_spring`.`blog`;
CREATE TABLE `java_blog_spring`.`blog` (`id` INT NOT NULL AUTO_INCREMENT,`title` VARCHAR(200) NULL,`content` TEXT NULL,`user_id` INT(11) NULL,`delete_flag` TINYINT(4) NULL DEFAULT 0,`create_time` TIMESTAMP NULL DEFAULT current_timestamp(),PRIMARY KEY (`id`))
ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '博客表';

增加一些测试数据:

insert into `java_blog_spring`.`user` (`user_name`, `password`,`github_url
`)values("zhangsan","123456","https://gitee.com/bubble-fish666/class-java4
5");
insert into `java_blog_spring`.`user` (`user_name`, `password`,`github_url
`)values("lisi","123456","https://gitee.com/bubble-fish666/class-java45");
insert into `java_blog_spring`.`blog` (`title`,`content`,`user_id`) values
("第⼀篇博客","111我是博客正⽂我是博客正⽂我是博客正⽂",1);
insert into `java_blog_spring`.`blog` (`title`,`content`,`user_id`) values
("第⼆篇博客","222我是博客正⽂我是博客正⽂我是博客正⽂",2);

4.2 DB相关数据

DB相关查询:

  1. 获取所有博客列表
  2. 根据博客Id获取博客详情
  3. 插⼊博客
  4. 更新博客
  5. 根据id查询user信息
  6. 根据name查询user信息

User类:

@Data
public class User {private Integer id;private String userName;private String password;private String githubUrl;private Byte deleteFlag;private Date createTime;
}

Blog类:

@Data
public class Blog {private Integer id;private String title;private String content;private Integer userId;private Integer deleteFlag;private Date createTime;//是否为登录用户,1表示为登录用户private Integer loginUser;public String getCreateTime() {//对时间进行格式化return DateUtils.formatDate(createTime);}
}

UserMapper类:

@Mapper
public interface UserMapper {@Select("select id,user_name,password,github_url,delete_flag,create_time from user where delete_flag=0 and id=#{id}")User selectById(Integer id);@Select("select id,user_name,password,github_url,delete_flag,create_time from user where delete_flag=0 and user_name=#{name}")User selectByName(String name);
}

BlogMapper类:

@Mapper
public interface BlogMapper {@Select("select * from blog where delete_flag=0")List<Blog> selectAllBlog();@Select("select * from blog where delete_flag=0 and id=#{blogId}")Blog selectBlogById(Integer blogId);Integer updateBlog(Blog blog);@Insert("insert into blog(title,content,user_id) values (#{title},#{content},#{userId})")Integer insertBlog(Blog blog);
}

BlogMapper.xml:

<mapper namespace="com.example.springblog.mapper.BlogMapper"><update id="updateBlog">update blog<set><if test="title!=null">title=#{title},</if><if test="content!=null">content=#{content},</if><if test="userId!=null">user_id=#{userId},</if><if test="deleteFlag!=null">delete_flag=#{deleteFlag},</if></set>where id=#{id}</update>
</mapper>

5.项目模块

在这里插入图片描述

6.添加项目公共模块

6.1 common

统一异常抽取为一个类:

@Data
public class Result {//业务处理状态码  200成功  <=0失败private Integer code;//业务返回提示信息private String msg;//业务返回数据private Object data;/*** 失败时处理内容* @return*/public static  Result fail(Integer code,String msg) {Result result=new Result();result.setCode(code);result.setMsg(msg);result.setData("");return result;}public static  Result fail(Integer code,String msg,Object data) {Result result=new Result();result.setCode(code);result.setMsg(msg);result.setData(data);return result;}/*** 业务处理成功* @param data* @return*/public static  Result success(Object data) {Result result=new Result();result.setCode(200);result.setMsg("");result.setData(data);return result;}public static  Result success(String msg,Object data) {Result result=new Result();result.setCode(200);result.setMsg(msg);result.setData(data);return result;}
}

出错时统一异常处理:

@ControllerAdvice
public class ErrorAdvice {@ExceptionHandlerpublic Result error(Exception e){return Result.fail(-1,e.getMessage());}
}

数据统一返回格式:

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return true;}//在数据返回之前进行处理@SneakyThrows  //异常处理注解@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {if(body instanceof Result){return body;}if(body instanceof String){ObjectMapper objectMapper=new ObjectMapper();return objectMapper.writeValueAsString(Result.success(body));}return Result.success(body);}
}

6.2 实现前端界面

把之前写好的博客系统静态⻚⾯拷⻉到static⽬录下:

在这里插入图片描述

7.功能实现

7.1实现博客列表

约定前后端交互接口

[请求]
/blog/getlist
[响应]
[{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"},...
]

我们约定, 浏览器给服务器发送⼀个 /blog/getlist 这样的 HTTP 请求, 服务器给浏览器返回了⼀个 JSON 格式的数据.

实现服务器代码

在 BlogController 中添加⽅法:

@Slf4j
@RequestMapping("/blog")
@RestController
public class BlogController {@Autowiredprivate BlogService blogService;@RequestMapping("/getlist")public List<Blog> getBlogList(){return blogService.selectAllBlog();}
}

在BlogService 中添加⽅法:

public class BlogService {@Autowiredprivate BlogMapper blogMapper;public List<Blog> selectAllBlog(){return blogMapper.selectAllBlog();}
}

部署程序, 验证服务器是否能正确返回数据 (使⽤ URL http://127.0.0.1:8080/blog/getlist 即可)

实现客户端代码

修改 blog_list.html, 删除之前写死的博客内容, 并新增js 代码处理 ajax 请求.

    <script src="./js/jquery.min.js"></script><script src="./js/common.js"></script><script>$.ajax({type:"get",url:"/blog/getlist",success:function(result){if(result.code==200 && result.data!=null && result.data.length>0){var blogs=result.data;var finalHtml="";for(var blog of blogs){finalHtml += '<div class="blog">';finalHtml += '<div class="title">'+blog.title+'</div>'finalHtml += '<div class="date">'+blog.createTime+'</div>'finalHtml += '<div class="desc">'+blog.content+'</div>'finalHtml += '<a class="detail" href="blog_detail.html?blogId='+blog.id+'">查看全文&gt;&gt;</a>'finalHtml += '</div>'}$(".right").html(finalHtml);}},error:function(error){console.log(error);if(error!=null && error.status==401){//用户未登录location.assign("blog_login.html");}}});var url="/user/getUserInfo";getUserInfo(url);</script>

7.2实现博客详情

⽬前点击博客列表⻚的 “查看全⽂” , 能进⼊博客详情⻚, 但是这个博客详情⻚是写死的内容. 我们期望能够根据当前的 博客 id 从服务器动态获取博客内容.

约定前后端交互接口

/blog/getBlogDetail?blogId=1
[响应]
{blogId: 1,title: "第⼀篇博客",content: "博客正⽂",userId: 1,postTime: "2021-07-07 12:00:00"
}

实现服务器代码

在 BlogController 中添加getBlogDeatail ⽅法:

   /*** 获取博客详情* @param blogId* @return*/@RequestMapping("/getBlogDetail")public Result getBlogDetail(Integer blogId,HttpSession session){log.info("blogId:"+blogId);if(blogId == null){return Result.fail(-1,"非法博客id");}Blog blog=blogService.selectBlogById(blogId);//获取登录用户信息User loginUser=(User) session.getAttribute(Constants.USER_INFO_SESSION);//判断登录用户和博客作者是否是同一个人if(loginUser!=null && loginUser.getId()== blog.getUserId()){blog.setLoginUser(1);}return Result.success(blog);}

在BlogService 中添加getBlogDeatil⽅法:

    public Blog selectBlogById(Integer blogId){return blogMapper.selectBlogById(blogId);}

实现客户端代码

    <script>$.ajax({type:"get",url:"/blog/getBlogDetail"+location.search,success:function(result){if(result.code==200 && result.data!=null){var blog=result.data;$(".title").text(blog.title);$(".date").text(blog.createTime);editormd.markdownToHTML("content", {markdown: blog.content ,});//$(".detail").text(blog.content);if(blog.loginUser==1){var html="";html+= '<button onclick="window.location.href=\'blog_update.html?blogId='+blog.id+'\'">编辑</button>';html+='<button onclick="deleteBlog()">删除</button>';$(".operating").html(html);}}},error:function(error){consolo.log(error);if(error!=null && error.status==401){//用户未登录location.assign(blog_login.html);}}});var url= "/user/getAuthorInfo" + location.search;getUserInfo(url);

common.js代码:

function getUserInfo(url){$.ajax({type:"get",url:url,success:function(result){if(result!=null && result.code==200 && result.data!=null){var user=result.data;$(".left .card h3").text(user.userName);$(".left .card a").attr("href",user.githubUrl);}}});
}

7.3实现登录

  • 登陆⻚⾯提供⼀个 form 表单, 通过 form 的⽅式把⽤户名密码提交给服务器.

  • 服务器端验证⽤户名密码是否正确. 如果密码正确,

  • 则在服务器端创建 Session , 并把 sessionId 通过 Cookie 返回给浏览器

约定前后端交互接口

[请求]
/user/login
username=test&password=123
[响应]
200 登录成功
<0 登录失败

实现服务器代码

在 UserController 中添加⽅法:

@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/login")public Result login(HttpServletRequest request,String username, String password){//参数校验if(!StringUtils.hasLength(username) || !StringUtils.hasLength(password)){return Result.fail(-1,"用户名密码不能为空");}//验证密码User user=userService.selectByName(username);if(user==null || !SecurityUtils.decrypt(password,user.getPassword())){return Result.fail(-2,"用户名密码错误");}//设置sessionHttpSession session= request.getSession(true);session.setAttribute(Constants.USER_INFO_SESSION,user);return Result.success("登录成功");}
}

在UserService 中添加⽅法:

@Service
public class UserService {@Autowiredprivate UserMapper userMapper;@Autowiredprivate BlogMapper blogMapper;public User selectByName(String name){return userMapper.selectByName(name);}
}

实现客户端代码

    <script src="./js/jquery.min.js"></script><script>function login(){$.ajax({type:"post",url:"/user/login",data:{username:$("#userName").val(),password:$("#password").val()},success:function(result){if(result.code==200){location.href="blog_list.html";return;}else if(result.code<0 && result.msg!=''){alert(result.msg);return;}},error:{}});}</script>

7.4实现强制要求登录

当⽤户访问 博客列表⻚ 和 博客详情⻚ 时, 如果⽤户当前尚未登陆, 就⾃动跳转到登陆⻚⾯.

添加拦截器

登录拦截器:

@Component
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HttpSession session=request.getSession(false);if(session!=null && session.getAttribute(Constants.USER_INFO_SESSION)!=null){//用户已经登录了return true; //不拦截}response.setStatus(401);return false;}
}

使用拦截器:

@Configuration
public class AppConfig implements WebMvcConfigurer {private final List<String> excludePaths = Arrays.asList("/**/*.html","/blog-editormd/**","/css/**","/js/**","/pic/**","/user/login");@Autowiredprivate LoginInterceptor loginInterceptor;//添加拦截器@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginInterceptor).addPathPatterns("/**")  //拦截所有路径.excludePathPatterns(excludePaths);  //不拦截excludePaths包括的类型文件}
}

实现客户端代码

1.修改 blog_datail.html

  • 访问⻚⾯时, 添加失败处理代码
  • 使⽤ location.assign 进⾏⻚⾯跳转.
			error:function(error){console.log(error);if(error!=null && error.status==401){//用户未登录location.assign("blog_login.html");}}

2.修改 blog_list.html

  • 访问⻚⾯时, 添加失败处理代码
  • 使⽤ location.assign 进⾏⻚⾯跳转.
            error:function(error){consolo.log(error);if(error!=null && error.status==401){//用户未登录location.assign(blog_login.html);}}

7.5实现显示用户信息

  • 如果当前⻚⾯是博客列表⻚, 则显示当前登陆⽤户的信息.
  • 如果当前⻚⾯是博客详情⻚, 则显示该博客的作者⽤户信息.

约定前后端交互接口

在博客列表⻚, 获取当前登陆的⽤户的⽤户信息.

[请求]
/user/getUserInfo
[响应]
{
userId: 1,
username: test...
}

在博客详情⻚, 获取当前⽂章作者的⽤户信息

[请求]
/user/getAuthorInfo?blogId=1
[响应]
{
userId: 1,
username: test
}

实现服务器代码

在 UserController 中添加⽅法:

    /*** 获取登录用户信息* @return*/@RequestMapping("/getUserInfo")public Result getUserInfo(HttpSession session){if(session==null || session.getAttribute(Constants.USER_INFO_SESSION)==null){return Result.fail(-1,"用户未登录");}User user=(User)session.getAttribute(Constants.USER_INFO_SESSION);return Result.success(user);}/*** 获取博客作者信息* @return*/@RequestMapping("/getAuthorInfo")public Result getAuthorInfo(Integer blogId){if(blogId==null || blogId<=0){return Result.fail(-1,"博客不存在~");}User user=userService.selectAuthorByBlogId(blogId);return Result.success(user);}

在UserService 中添加⽅法:

    public User selectAuthorByBlogId(Integer blogId){User user=null;Blog blog=blogMapper.selectBlogById(blogId);if(blog!=null && blog.getUserId()>0){user=userMapper.selectById(blog.getUserId());}if(user!=null){user.setPassword("");}return user;}

7.6实现用户退出

约定前后端交互接口

[请求]
/user/logout
[响应]
true

实现服务器代码

在 UserController 中添加⽅法:

    /*** 注销* @return*/@RequestMapping("/logout")public Result logout(HttpSession session){session.removeAttribute(Constants.USER_INFO_SESSION);return Result.success(true);}

实现客户端代码

客户端代码, 注销改为⼀个a标签, href 设置为logout, 点击的时候就会发送GET/logout请求

<a class="nav-span" href="#" onclick="logout()">注销</a>

在common.js中添加logout⽅法:

function logout(){$.ajax({type:"get",url:"/user/logout",success:function(result){if(result!=null && result.data==true){location.href="blog_login.html";}}});
}

7.7实现发布博客

约定前后端交互接口

[请求]
/blog/add
title=标题&content=正⽂...
[响应]
true 成功
false 失败

实现服务器代码

在 BlogController 中添加⽅法:

    /*** 发布博客* @return*/@RequestMapping("/add")public Result addBlog(String title, String content,HttpSession session){if(!StringUtils.hasLength(title) || !StringUtils.hasLength(content)){return Result.fail(-1,"标题或内容不能为空");}User user= (User) session.getAttribute(Constants.USER_INFO_SESSION);if(user==null || user.getId()<=0){return Result.fail(-1,"用户不存在");}try{Blog blog=new Blog();blog.setTitle(title);blog.setContent(content);blog.setUserId(user.getId());blogService.insertBlog(blog);}catch (Exception e){return Result.fail(-1,"博客发布失败~");}return Result.success(true);}

在BlogService 中添加⽅法:

 public Integer insertBlog(Blog blog){return blogMapper.insertBlog(blog);}

实现客户端代码

给提交按钮添加click事件 <input type=“button” value="发布⽂章"id=“submit” οnclick=“submit()”>

        $("#submit").click(function(){$.ajax({type:"post",url:"/blog/add",data:{title:$("#title").val(),content:$("#content").val()},success:function(result){if(result!=null && result.code==200 && result.data==true){location.href="blog_list.html";}else{alert(result.msg);}},error:function(error){if(error!=null && error.status==401){alert("请先登录!!!");}}});});

7.8实现删除/编辑博客

进⼊⽤户详情⻚时, 如果当前登陆⽤户正是⽂章作者, 则在导航栏中显示 “删除” 按钮, ⽤户点击时则删除该⽂章.

需要实现两件事:

  • 判定当前博客详情⻚中是否要显示 删除 按钮
  • 实现删除逻辑.

约定前后端交互接口

编辑博客

[请求]
/blog?BlogId=1
[响应]
{blogId: 1,title: "第⼀篇博客",content: "博客正⽂",userId: 1,postTime: "2021-07-07 12:00:00",loginUser: 1
}

删除博客

[请求]
GET /blog/delete?blogId=1
[响应]
true 删除成功

实现服务器代码

在 BlogController 中添加⽅法:

    /*** 更新博客* @param blog* @return*/@RequestMapping("/updateBlog")public Result updateBlog(Blog blog){if(!StringUtils.hasLength(blog.getTitle()) || !StringUtils.hasLength(blog.getContent()) || blog.getId()==null){return Result.fail(-1,"标题或内容不合法");}blogService.updateBlog(blog);return Result.success(true);}/*** 删除博客* @return*/@RequestMapping("/deleteBlog")public Result deleteBlog(Integer blogId){if(blogId==null){return Result.fail(-1,"博客不存在~");}Blog blog=new Blog();blog.setId(blogId);blog.setDeleteFlag(1);blogService.updateBlog(blog);return Result.success(true);}
}

在BlogService 中添加⽅法:

    public Integer updateBlog(Blog blog){return blogMapper.updateBlog(blog);}

实现客户端代码

删除博客:

        function deleteBlog(){$.ajax({type:"post",url:"/blog/deleteBlog" + location.search,success:function(result){if(result!=null && result.code==200 && result.data==true){location.href="blog_list.html";}else{alert(result.msg);}},eeror:function(error){if(error!=null && error.status==401){//用户未登录location.assign("blog_login.html");}}});}

编辑博客:

        //获取博客的详细内容,并且反应到页面上$.ajax({type:"get",url:"/blog/getBlogDetail" + location.search,success:function(result){if(result!=null && result.code==200 && result.data!=null){var blog=result.data;$("#blogId").val(blog.id);$("#title").val(blog.title);$("#content").val(blog.content);}else if(result!=null){alert(result.msg);}},error:function(error){if(error!=null && error.status==401){//用户未登录location.assign(blog_login.html);}}});$("#submit").click(function(){$.ajax({type:"post",url:"/blog/updateBlog",data:{id:$("#blogId").val(),title:$("#title").val(),content:$("#content").val()},success:function(result){if(result!=null && result.code==200 && result.data==true){location.href="blog_list.html";}else if(result!=null){alert(result.msg);}}});});</script>

7.9实现加密加盐

加密工具类

使用md5进行密码加密:

public class SecurityUtils {/*** 加密* 根据明文,返回密文(salt+加密后的密文)* @return*/public static String encry(String inputPassword){//生成盐值String salt= UUID.randomUUID().toString().replace("-","");//md5加密(明文+盐值)String password= DigestUtils.md5DigestAsHex((inputPassword+salt).getBytes());return salt+password;}/*** 验证密码是否正确* @return*/public static boolean decrypt(String inputPassword,String finalPassword){//判空if(!StringUtils.hasLength(inputPassword) || !StringUtils.hasLength(finalPassword)){return false;}//验证长度if(finalPassword.length()!=64){return false;}//验证密码String salt=finalPassword.substring(0,32);String password= DigestUtils.md5DigestAsHex((inputPassword+salt).getBytes());return (salt+password).equals(finalPassword);}
}

使用

        //验证密码User user=userService.selectByName(username);if(user==null || !SecurityUtils.decrypt(password,user.getPassword())){return Result.fail(-2,"用户名密码错误");}

修改数据库密码

使⽤测试类给密码123456⽣成密⽂:
e2377426880545d287b97ee294fc30ea6d6f289424b95a2b2d7f8971216e39b7

执行SQL:

update user set password='e2377426880545d287b97ee294fc30ea6d6f289424b95a2b2
d7f8971216e39b7' where id=1;

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

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

相关文章

20、Flink SQL之SQL Client: 不用编写代码就可以尝试 Flink SQL,可以直接提交 SQL 任务到集群上

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

MySQL 查询语句大全

目录 基础查询 直接查询 AS起别名 去重&#xff08;复&#xff09;查询 条件查询 算术运算符查询 逻辑运算符查询 正则表达式查询⭐ 模糊查询 范围查询 是否非空判断查询 排序查询 限制查询&#xff08;分页查询&#xff09; 随机查询 分组查询 HAVING 高级查询…

QT图形视图系统 - 使用一个项目来学习QT的图形视图框架 - 终篇

QT图形视图系统 - 终篇 接上一篇&#xff0c;我们需要继续完成以下的效果&#xff1b; 先上个效果图&#xff1a; 资源路径&#xff1a;https://download.csdn.net/download/turbolove/88192114?spm1001.2014.3001.5503 修改背景&#xff0c;使之整体适配 上一篇我们绘制了…

领航优配:沪指震荡涨0.47%,保险、券商板块强势,互联金融概念活跃

4日早盘&#xff0c;两市股指高开高走&#xff0c;沪指一度涨逾1%打破3300点&#xff0c;随后涨幅有所收窄&#xff1b;两市半日成交超6000亿元&#xff0c;北向资金小幅净流入。 截至午间收盘&#xff0c;沪指涨0.47%报3295.91点&#xff0c;深成指涨0.67%&#xff0c;创业板指…

使用idea如何生成webservice客户端

需求阐述 在和外围系统对接的时候&#xff0c;对方只给了wsdl地址&#xff0c;记得之前了解到的webservice&#xff0c;可以用idea生成客户端代码。先记录生成的步骤 使用idea如何生成webservice客户端 1.创建一个Java项目 2.第二步生成代码 我的idea再右键要生成文件目录里…

01.Redis实现发送验证码保存功能

学习目标&#xff1a; 提示&#xff1a;学习如何利用Redis来实现发送验证码功能 学习产出&#xff1a; 流程图 1. 准备pom环境 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifact…

QT生成可执行文件的步骤

QT生成可执行文件的步骤 第一步&#xff1a;debug为release&#xff0c;然后进行编译 第二步&#xff1a;添加QT生成必要的库 首先&#xff0c;建立一个新的文件夹&#xff0c;然后将Release中的可执行文件拷贝到新的文件夹中 然后&#xff0c;在新建文件夹中生成必要的库 …

flutter:二维码生成与读取

前言 这csdn真的是服了&#xff0c;图片里有个二维码就直接变成违规图片了。至于效果的话&#xff0c;自己运行一下看看吧。 生成 flutter中生成二维码可以使用 qr_flutter。 官方文档 https://pub-web.flutter-io.cn/packages/qr_flutter 安装 flutter pub add qr_flutt…

使用vue-grid-layout时 You may need an appropriate loader to handle this file type.

使用vue-grid-layout时 You may need an appropriate loader to handle this file type. node版本不匹配 我的node v14.16.0 vue-gride-layout 需要用 v 2.3.7的版本 卸载后重新安装即可

我的2048创作纪念日

目录 一、来龙去脉二、2048天前的今天三、2048天的收获四、2048天后的今天五、祝福 一、来龙去脉 今天是 2023 年 8 月 9 日&#xff0c;在咖啡馆浏览我的 CSDN 主页时&#xff0c;看到官方发来了一则私信&#xff1a; 二、2048天前的今天 提示&#xff1a;可以和大家分享最初…

Xilinx FPGA电源设计与注意事项

1 引言 随着半导体和芯片技术的飞速发展&#xff0c;现在的FPGA集成了越来越多的可配置逻辑资源、各种各样的外部总线接口以及丰富的内部RAM资源&#xff0c;使其在国防、医疗、消费电子等领域得到了越来越广泛的应用。当采用FPGA进行设计电路时&#xff0c;大多数FPGA对上电的…

【第一阶段】kotlin的函数

函数头 fun main() {getMethod("zhangsan",22) }//kotlin语言默认是public,kotlin更规范&#xff0c;先有输入&#xff08; getMethod(name:String,age:Int)&#xff09;再有输出(Int[返回值]) private fun getMethod(name:String,age:Int): Int{println("我叫…

Qt 使用QLabel的派生类实现QLabel的双击响应

1 介绍 在QLabel中没有双击等事件响应&#xff0c;需要构建其派生类&#xff0c;自定义信号(signals)、重载事件函数(event)&#xff0c;最后在Qwidget中使用connect链接即可&#xff0c;进而实现响应功能。 对于其余没有需求事件响应的QObject同样适用。 此外&#xff0c;该功…

近地面无人机植被定量遥感与生理参数反演技术

遥感&#xff08;RS-Remote Sensing&#xff09;——不接触物体本身&#xff0c;用传感器收集目标物的电磁波信息&#xff0c;经处理、分析后&#xff0c;识别目标物&#xff0c;揭示其几何、物理性质和相互关系及其变化规律的现代科学技术。 换言之&#xff0c;即是“遥远的感…

Redis的安装方法与基本操作

目录 前言 一、REDIS概述 二、REDIS安装 1、编译安装 2.yum安装 三、Redis的目录结构 四、基础命令解析 五、在一台服务器上启动多个redis 六、数据库的基本操作 &#xff08;一&#xff09;登录数据库 &#xff08;二&#xff09;基础命令 七、Redis持久化 &#xff08;一&…

【2.2】Java微服务:Hystrix的详解与使用

目录 分布式系统面临问题 Hystrix概念 Hystrix作用 降级 什么是降级 order服务导入Hystrix依赖&#xff08;简单判断原则&#xff1a;谁调用远程谁加&#xff09; 启动类添加注解 业务方法添加注解&#xff08;冒号里填回调方法名&#xff0c;回调方法返回兜底数据&…

【MySQL】内置函数

文章目录 一、日期函数1.1 日期函数的基本使用1.2 案例11.3 案例2 二、字符串函数三、数学函数四、其他函数 一、日期函数 1.1 日期函数的基本使用 获取当前日期与日期 mysql> select current_date(), current_time(); -------------------------------- | current_date()…

FANUC机器人SRVO-300机械手断裂故障报警原因分析及处理办法

FANUC机器人SRVO-300机械手断裂故障报警原因分析及处理办法 首先,我们查看报警说明书上的介绍: 总结:即在机械手断裂设置为无效时,机器人检测出了机械手断裂信号(不该有的信号,现在检测到了,所以报警) 使机械手断裂设定为无效/有效的具体方法:  按下示教器的MENU菜单…

【LeetCode】数据结构题解(12)[用栈实现队列]

用栈实现队列 &#x1f609; 1.题目来源&#x1f440;2.题目描述&#x1f914;3.解题思路&#x1f973;4.代码展示 所属专栏&#xff1a;玩转数据结构题型❤️ &#x1f680; >博主首页&#xff1a;初阳785❤️ &#x1f680; >代码托管&#xff1a;chuyang785❤️ &…

爆肝整理,Postman接口测试-参数关联实战(详细步骤)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 接口测试什么时候…