项目实战系列三: 家居购项目 第六部分

文章目录

      • 🌈Ajax检验注册名
      • 🌈Ajax添加购物车
      • 🌈上传与更新家居图片
      • 🌈作业布置
        • 🍍会员登陆后不能访问后台管理
        • 🍍解决图片冗余问题
        • 🍍分页导航完善

🌈Ajax检验注册名

需求分析

  1. 注册会员时, 如果名字已经注册过, 当光标离开输入框, 提示会员名已经存在, 否则提示不存在
  2. 要求使用ajax完成

程序框架图
在这里插入图片描述

  1. MemberServlet - 返回json格式的字符串 - 方式一
protected void isExistByName(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.获取用户名String username = req.getParameter("username");//2.调用serviceboolean existsByUsername = memberService.isExistsByUsername(username);//3.思路//(1)如果返回json格式[不要乱写, 要根据前端的需求来写]//(2)因为前后端都是我们自己写的, 格式我们自己定义//(3){"isExist": true};//(4)先用最简单的方法拼接 => 一会改进[扩展]String resultJson = "{\"isExist\": " + existsByUsername + "}";//4.返回resp.getWriter().print(resultJson);
}

返回json格式的字符串 - 方式二

protected void isExistByName(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.获取用户名String username = req.getParameter("username");//2.调用serviceboolean existsByUsername = memberService.isExistsByUsername(username);//3.思路//(1)如果返回json格式[不要乱写, 要根据前端的需求来写]//(2)因为前后端都是我们自己写的, 格式我们自己定义//(3){"isExist": true};//(4)先用最简单的方法拼接 => 一会改进[扩展]//String resultJson = "{\"isExist\": " + existsByUsername + "}";字符串就不需要再转//(5)将要返回的数据封装成map => json格式Map<Object, Object> map = new HashMap<>();map.put("isExist", existsByUsername);//map.put("email", "978964140@qq.com");//map.put("phone", "13031748275");//4.返回json格式的数据Gson gson = new Gson();String resultJson = gson.toJson(map);resp.getWriter().print(resultJson);
}
  1. 前端
$("#username").mouseleave(function () {//鼠标离开事件[无需点击, 即可触发]var usernameValue = $(this).val();$.getJSON(//这里尽量准确, 一把确定[复制粘贴]"memberServlet", "action=isExistByName&username=" + usernameValue, function (data) {alert(data.isExist);console.log("data= ", data);//显示json格式的数据: 1.要用逗号; 2.要用console.log()}
/*========================================================================================*/"memberServlet?action=isExistByName&username=" + usernameValue, function (data) {alert(data.isExist);console.log("data= ", data);//显示json格式的数据: 1.要用逗号; 2.要用console.log()}
/*========================================================================================*/"memberServlet",{action: "isExistByName",username: usernameValue},function (data) {alert(data.isExist);console.log("data= ", data);//显示json格式的数据: 1.要用逗号; 2.要用console.log()}
/*========================================================================================*/"memberServlet",{"action": "isExistByName","username": usernameValue},function (data) {alert(data.isExist);//前端人员只能通过console.log()来查看你的数据, 然后才知道怎么获取你的数据console.log("data= ", data);//显示json格式的数据: 1.要用逗号; 2.要用console.log()if (data.isExist) {$("span[class='errorMsg']").text("用户名 " + usernameValue + " 不可用");} else {$("span[class='errorMsg']").text("用户名 " + usernameValue + " 可用");})
}      
  • Ajax检验验证码
  1. MemberServlet
   protected void verifyCaptcha(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取用户提交的验证码String captcha = req.getParameter("captcha");//从session中获取 生成的验证码HttpSession session = req.getSession();String token = (String) session.getAttribute(KAPTCHA_SESSION_KEY);//立即删除session中的验证码, 防止该验证码被重复使用session.removeAttribute(KAPTCHA_SESSION_KEY);//如果token不为空, 并且和用户提交的验证码保持一致, 就继续if (token != null) {Map<Object, Object> map = new HashMap<>();boolean verifyCaptcha = token.equalsIgnoreCase(captcha);map.put("verifyCaptcha", verifyCaptcha);//返回json格式的数据Gson gson = new Gson();String resultJson = gson.toJson(map);resp.getWriter().print(resultJson);}}
  1. 前端
    $("#code").blur(function () {//光标焦点离开事件[点击后离开, 才可以触发]var captchaValue = this.value;$.getJSON("memberServlet?action=verifyCaptcha&captcha="+captchaValue, function (data) {console.log("data= ", data);if (data.verifyCaptcha) {$("span.errorMsg2").text("验证码正确");} else {$("span.errorMsg2").text("验证码错误");}});})

在验证码标签旁补充一个span标签

<span class="errorMsg2"  style="float: right; font-weight: bold; font-size: 15pt; margin-left: 10px; color: lightgray;"></span>                                            

🌈Ajax添加购物车

  1. CartServlet添加addItemByAjax方法
//添加一个添加家居到购物车的方法 [Ajax]protected void addItemByAjax(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {int id = DataUtils.parseInt(request.getParameter("id"), 1);//家居id//根据id获取对应的家居信息Furn furn = furnService.queryFurnById(id);//先把正常的逻辑走完, 再处理异常的情况//如果某家居的库存为0, 就不要添加到购物车, 直接请求转发到首页面//if (furn.getInventory() <= 0) {//    request.getRequestDispatcher("/index.jsp").forward(request, response);//    return;//}HttpSession session = request.getSession();Cart cart = (Cart) session.getAttribute("cart");//得到购物车 有可能是空的,也有可能是上次的if (cart == null) {cart = new Cart();session.setAttribute("cart", cart);}//构建一条家居明细: id,家居名,数量, 单价, 总价//count类型为Integer, 不赋值默认值为nullCartItem cartItem = new CartItem(id, furn.getName(), 1, furn.getPrice(), furn.getPrice());//将家居明细加入到购物车中. 如果家居id相同,数量+1;如果是一条新的商品,那么就新增cart.addItem(cartItem, furn.getInventory());System.out.println("cart= " + cart);//规定格式 {"cartTotalCount": 3}//方式一://String resultJson = "{\"cartTotalCount\": " + cart.getTotalCount() + "}";//response.getWriter().print(resultJson);//方式二: 创建map,可扩展性强Map<Object, Object> map = new HashMap<>();map.put("cartTotalCount", cart.getTotalCount());//转成jsonGson gson = new Gson();String resultJson = gson.toJson(map);//返回response.getWriter().print(resultJson);//String referer = request.getHeader("referer");//response.sendRedirect(referer);}
  1. 前端
            //给所有选定的button都赋上点击事件$("button.add-to-cart").click(function () {var id = $(this).attr("furnId");//location.href = "cartServlet?action=addItem&id=" + id;//这里我们使用jquery发出ajax请求, 得到数据进行局部刷新, 解决刷新这个页面效率低的问题$.getJSON("cartServlet?action=addItemByAjax&id=" + id, function (data) {console.log("data=", data);//刷新局部 <span class="header-action-num"></span>$("span.header-action-num").text(data.cartTotalCount);})});
  1. 解决Ajax请求转发失败
    测试, 会发现针对ajax的重定向和请求转发会失败, 也就是AuthFilter.java的权限拦截不生效, 也就是点击Add to Cart, 后台服务没有响应

使用ajax向后台发送请求跳转页面无效的原因

  1. 主要是服务器得到的是ajax发送过来的request, 也就是说这个请求不是浏览器请求的, 而是ajax请求的. 所以servlet根据request进行请求转发或重定向都不能影响浏览器的跳转
  2. 解决方案: 如果想要实现跳转, 可以返回url给ajax, 在浏览器执行window.location(url);
    在这里插入图片描述

工具类添加方法 - 判断请求是不是一个ajax请求

   /*** 判断请求是不是一个ajax请求* @param request* @return*/public static boolean isAjaxRequest(HttpServletRequest request) {//X-Requested-With: XMLHttpRequestreturn "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));}

修改AuthFilter.java

if (member == null) {//说明用户没有登录if (!WebUtils.isAjaxRequest(request)) {//如果不是ajax请求//转发到登陆页面, 转发不走过滤器servletRequest.getRequestDispatcher("/views/member/login.jsp").forward(servletRequest, servletResponse);} else {//如果是ajax请求//返回ajax请求, 按照json格式返回 {"url": url}    //String url = "views/member/login.jsp";//String resultJson = "{\"url\": \"" + url + "\"}";//1.构建mapMap<Object, Object> map = new HashMap<>();map.put("url", "views/member/login.jsp");//2.转成json字符串String resultJson = new Gson().toJson(map);//3.返回servletResponse.getWriter().print(resultJson);}重定向-拦截-重定向-拦截-重定向-拦截//((HttpServletResponse) servletResponse)//        .0sendRedirect(request.getContextPath() + "/views/member/login.jsp");return;//直接返回
}

修改getJson

//这里我们使用jquery发出ajax请求, 得到数据进行局部刷新, 解决刷新这个页面效率低的问题
$.getJSON("cartServlet?action=addItemByAjax&id=" + id, function (data) {console.log("data=", data);if (data.url == undefined) {//刷新局部 <span class="header-action-num"></span>$("span.header-action-num").text(data.cartTotalCount);} else {location.href = data.url;}}
)

🌈上传与更新家居图片

引入文件上传下载的包: commons-io-1.4.jar, commons-fileupload-1.2.1.jar
FurnDAOImpl的查询语句加上图片字段 image_path as imagePath

需求分析

  1. 后台修改家居, 可以点击图片, 选择新的图片
  2. 这里会用到文件上传功能

思路分析-程序框架图
在这里插入图片描述

  1. furn_update.jsp
   <style type="text/css">#pic {position: relative;}input[type="file"] {position: absolute;left: 0;top: 0;height: 180px;opacity: 0;cursor: pointer;}</style>
<script type="text/javascript">function prev(event) {//获取展示图片的区域var img = document.getElementById("preView");//获取文件对象var file = event.files[0];//获取文件阅读器: Js的一个类, 直接使用即可var reader = new FileReader();reader.readAsDataURL(file);reader.onload = function () {//给img的src设置图片urlimg.setAttribute("src", this.result)}}
</script>

去掉a标签

<div id="pic"><img class="img-responsive ml-3" src="${requestScope.furn.imagePath}"alt="" id="preView"><input type="file" name="imagePath" id="" value="${requestScope.furn.imagePath}"onchange="prev(this)"/>
</div>
  1. 分析空指针异常
    将form表单改成文件表单
    <form action="manage/furnServlet" method="post" enctype="multipart/form-data"></form>
    点击修改家居
    在这里插入图片描述
    报错
    在这里插入图片描述
    将web.xml中500的错误提示配置注销掉, 将异常信息暴露出来
    在这里插入图片描述
    再次点击修改家居信息, 报错信息显示出来, BasicServlet空指针异常
    所以有时候报错信息显示出来很重要
    在这里插入图片描述
    分析: 如果表单是enctype=“multipart/form-data”, 那么req.getParameter(“action”) 的方法得不到action值, 所以BasicServlet会报错
    在这里插入图片描述
    具体原因: req.getParameter(“action”)取不到form-data里的数据
    在这里插入图片描述
  2. 解决空指针异常
    解决方案: 将参数action, id, pageNo以url拼接的方式传参, BasicServlet便不会出错
    注意: post请求可以人为主动在地址中拼接参数,拼接的参数可以直接像get那样接收
    <form action="manage/furnServlet?action=update&id=${requestScope.furn.id}&pageNo=${param.pageNo}" method="post" enctype="multipart/form-data">
    在这里插入图片描述
  3. FurnServlet update方法
    处理普通字段
if (fileItem.isFormField()) {//文本表单字段将提交的家居信息, 封装成Furn对象switch (fileItem.getFieldName()) {case "name":furn.setName(fileItem.getString("utf-8"));break;case "business":furn.setBusiness(fileItem.getString("utf-8"));break;case "price":furn.setPrice(new BigDecimal(fileItem.getString()));break;case "saleNum":furn.setSaleNum(Integer.parseInt(fileItem.getString()));break;case "inventory":furn.setInventory(Integer.parseInt(fileItem.getString()));break;}
}

处理文件字段
在这里插入图片描述
将文件上传路径保存成一个常量

public class WebUtils {public static final String FURN_IMG_DIRECTORY = "assets/images/product-image/";
}    
//文件表单字段 => 获取上传的文件的名字
String name = fileItem.getName();//如果用户没有选择新的图片, name = ""
if (!"".equals(name)) {//1.把上传到到服务器 temp目录下的文件保存到指定的目录String filePath = "/" + WebUtils.FURN_IMG_DIRECTORY;//2.获取完整的目录String fileRealPath = req.getServletContext().getRealPath(filePath);System.out.println("fileRealPath= " + fileRealPath);//3.创建这个上传的目录File fileRealPathDirectory = new File(fileRealPath);if (!fileRealPathDirectory.exists()) {fileRealPathDirectory.mkdirs();}//4.将文件拷贝到fileRealPathDirectory目录下//对上传的文件名进行处理, 前面增加一个前缀, 保证是唯一的即可. 防止文件名重复造成覆盖//构建了一个上传的文件的完整路径[目录+文件名]name = UUID.randomUUID().toString() + "_" + System.currentTimeMillis() + "_" + name;String fileFullPath = fileRealPathDirectory + "\\" + name;//保存fileItem.write(new File(fileFullPath));//关闭流fileItem.getOutputStream().close();//更新家居图的图片furn.setImagePath(WebUtils.FURN_IMG_DIRECTORY + name);
}

全部代码

protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//将提交修改的家居信息,封装成Furn对象//如果你的表单是enctype="multipart/form-data", req.getParameter("id") 得不到idint id = DataUtils.parseInt(req.getParameter("id"), 0);//获取到对应furn对象[从db中获取]Furn furn = furnService.queryFurnById(id);//todo 如果furn为null, 则return//1.判断是不是文件表单if (ServletFileUpload.isMultipartContent(req)) {//2.创建DiskFileItemFactory对象, 用于构建一个解析上传数据的工具对象DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();//3.构建一个解析上传数据的工具对象ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);//解决中文乱码问题servletFileUpload.setHeaderEncoding("utf-8");//4.servletFileUpload对象可以把表单提交的数据[文本/文件], 封装到FileItem文件项中try {List<FileItem> list = servletFileUpload.parseRequest(req);for (FileItem fileItem : list) {//判断是不是一个文件 => 文本表单字段if (fileItem.isFormField()) {将提交的家居信息, 封装成Furn对象switch (fileItem.getFieldName()) {case "name"://家居名furn.setName(fileItem.getString("utf-8"));break;case "business"://制造商furn.setBusiness(fileItem.getString("utf-8"));break;case "price"://价格furn.setPrice(new BigDecimal(fileItem.getString()));break;case "saleNum"://销量furn.setSaleNum(Integer.parseInt(fileItem.getString()));break;case "inventory"://库存furn.setInventory(Integer.parseInt(fileItem.getString()));break;}} else {//文件表单字段 => 获取上传的文件的名字String name = fileItem.getName();//如果用户没有选择新的图片, name = ""if (!"".equals(name)) {//1.把上传到到服务器 temp目录下的文件保存到指定的目录String filePath = "/" + WebUtils.FURN_IMG_DIRECTORY;//2.获取完整的目录String fileRealPath = req.getServletContext().getRealPath(filePath);System.out.println("fileRealPath= " + fileRealPath);//3.创建这个上传的目录File fileRealPathDirectory = new File(fileRealPath);if (!fileRealPathDirectory.exists()) {fileRealPathDirectory.mkdirs();}//4.将文件拷贝到fileRealPathDirectory目录下//对上传的文件名进行处理, 前面增加一个前缀, 保证是唯一的即可. 防止文件名重复造成覆盖//构建了一个上传的文件的完整路径[目录+文件名]name = UUID.randomUUID().toString() + "_" + System.currentTimeMillis() + "_" + name;String fileFullPath = fileRealPathDirectory + "\\" + name;//保存fileItem.write(new File(fileFullPath));//关闭流fileItem.getOutputStream().close();//更新家居图的图片furn.setImagePath(WebUtils.FURN_IMG_DIRECTORY + name);}} } else {System.out.println("不是文件表单...");}//更新furn对象->DBfurnService.updateFurn(furn);System.out.println("更新成功...");//请求转发到 update_ok.jspreq.getRequestDispatcher("/views/manage/update_ok.jsp").forward(req, resp);} catch (Exception e) {throw new RuntimeException(e);}}
}

将checkout.jsp复制成update_ok.jsp

<a class="active" href="manage/furnServlet?action=page&pageNo=${param.pageNo}"><h4>家居修改成功, 点击返回家居管理页面</h4>
</a>

🌈作业布置

🍍会员登陆后不能访问后台管理

需求分析

  1. 管理员admin登陆后, 可访问所有页面
  2. 会员登陆后, 不能访问后台管理相关页面, 其他页面可以访问
  3. 假定管理员名字就是admin, 其它会员名就是普通会员

AuthFilter - 代码

   @Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("请求/cartServlet 被拦截...");HttpServletRequest request = (HttpServletRequest) servletRequest;//得到请求的urlString url = request.getServletPath();System.out.println("url= " + url);//判断是否要验证if (!excludedUrls.contains(url)) {//获取到登陆的member对象Member member = (Member) request.getSession().getAttribute("member");if (member == null) {//说明用户没有登录if (!WebUtils.isAjaxRequest(request)) {//如果不是ajax请求//转发到登陆页面, 转发不走过滤器servletRequest.getRequestDispatcher("/views/member/login.jsp").forward(servletRequest, servletResponse);} else {//如果是ajax请求//返回ajax请求, 按照json格式返回 {"url": url}//1.构建mapMap<Object, Object> map = new HashMap<>();map.put("url", "views/member/login.jsp");//2.转成json字符串String resultJson = new Gson().toJson(map);//3.返回servletResponse.getWriter().print(resultJson);}return;//直接返回}//如果member不为空if ("admin".equals(member.getUsername())) {//管理员登陆//全部放行} else {//普通用户登录, 部分页面不能放行//如果该用户不是admin, 但是它访问了后台, 就转到管理员登录页面//if ("/manage/furnServlet".equals(url) || url.contains("/views/manage/")) {//.* 匹配任意个字符if ("/manage/furnServlet".equals(url) || url.matches("^/views/manage/.*")) {request.getRequestDispatcher("/views/manage/manage_login.jsp").forward(servletRequest, servletResponse);}}}//如果请求的是登录页面, 那么就放行filterChain.doFilter(servletRequest, servletResponse);System.out.println("请求/cartServlet验证通过, 放行");}
🍍解决图片冗余问题

需求分析

  1. 家居图片都放在一个文件夹, 会越来越多
  2. 请尝试在assets/images/product-image/目录下, 自动创建年月日目录, 比如20230612. 以天为单位来存放上传图片
  3. 当上传新家居的图片, 原来的图片就没有用了, 应当删除原来的家居图片

工具类添加方法 - 返回当前日期

   public static String getYearMonthDay() {//第三代日期类LocalDateTime now = LocalDateTime.now();int year = now.getYear();int month = now.getMonthValue();int day = now.getDayOfMonth();String date = year + "/" + month + "/" + day + "/";return date;}

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

🍍分页导航完善

需求分析

  1. 如果总页数<=5, 就全部显示
  2. 如果总页数>5, 按照如下规则显示(这个规则由程序员/业务来决定)
    2.1 如果当前页是前3页, 就显示1-5
    2.2 如果当前页是后3页, 就显示最后5页
    2.3 如果当前页是中间页, 就显示 当前页前2页, 当前页, 当前页后2页

代码实现

<c:choose><%--如果总页数<=5, 就全部显示--%><c:when test="${requestScope.page.pageTotal <= 5}"><c:set scope="page" var="begin" value="1"></c:set><c:set scope="page" var="end" value="${requestScope.page.pageTotal}"></c:set></c:when><%--如果总页数>5, 按照如下规则显示(这个规则由程序员/业务来决定)--%><c:when test="${requestScope.page.pageTotal > 5}"><c:choose><%--如果当前页是前3页, 就显示1-5--%><c:when test="${requestScope.page.pageNo <= 3}"><c:set scope="page" var="begin" value="1"></c:set><c:set scope="page" var="end" value="5"></c:set></c:when><%--如果当前页是后3页, 就显示最后5页--%><c:when test="${requestScope.page.pageNo > requestScope.page.pageTotal - 3}"><c:set scope="page" var="begin" value="${requestScope.page.pageTotal - 4}"></c:set><c:set scope="page" var="end" value="${requestScope.page.pageTotal}"></c:set></c:when><%--如果当前页是中间页, 就显示 当前页前2页, 当前页, 当前页后2页--%><c:otherwise><c:set scope="page" var="begin" value="${requestScope.page.pageNo - 2}"></c:set><c:set scope="page" var="end" value="${requestScope.page.pageNo + 2}"></c:set></c:otherwise></c:choose></c:when>
</c:choose>

🐀🐂🐅🐇🐉🐍🐎🐏

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

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

相关文章

推动多模态智能模型发展:大型视觉语言模型综合多模态评测基准

随着人工智能技术的飞速发展&#xff0c;大型视觉语言模型&#xff08;LVLMs&#xff09;在多模态应用领域取得了显著进展。然而&#xff0c;现有的多模态评估基准测试在跟踪LVLMs发展方面存在不足。为了填补这一空白&#xff0c;本文介绍了MMT-Bench&#xff0c;这是一个全面的…

js获取字符串中超链接,并加样式跳转页面

效果图 主要代码&#xff1a;js this.$nextTick(() > {// 给循环出来的div标签加个id为let container document.getElementById("linkTo");container.innerHTML container.textContent.replace(/(https?:\/\/[^\s])/g, function (match) {var link documen…

【微前端-Single-SPA、qiankun的基本原理和使用】

背景 在实际项目中&#xff0c;随着日常跌倒导致的必然墒增&#xff0c;项目会越来越冗余不好维护&#xff0c;而且有时候一个项目会使用的其他团队的功能&#xff0c;这种跨团队不好维护和管理等等问题&#xff0c;所以基于解决这些问题&#xff0c;出现了微前端的解决方案。…

前端项目vue3/React使用pako库解压缩后端返回gzip数据

pako仓库地址&#xff1a;https://github.com/nodeca/pako 文档地址&#xff1a;pako 2.1.0 API documentation 外部接口返回一个直播消息或者图片数据是经过zip压缩的&#xff0c;前端需要把这个数据解压缩之后才可以使用&#xff0c;这样可以大大降低网络数据传输的内容&…

Depth Anything V1,V2论文解读

Depth Anything 引言Depth Anything V1标注方法学习标注图像发挥未标注图像的潜力语义辅助感知 Depth Anything V2总体框架流程 引言 在深度估计领域&#xff0c;单目深度估计&#xff08;Monocular Depth Estimation&#xff0c;MDE&#xff09;是指利用单个摄像头拍摄的图像…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(十八)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 28 节&#xff09; P28《27.网络连接-Http请求数据》 案例&#xff1a; 这里不懂后端假设服务器的前端小伙伴就需要课程源码资料了…

深度之眼(二十五)——研究生学习计划安排

文章目录 一、前言二、结构安排和规划2.1 夯实基础2.2 分方向训练&#xff08;待&#xff09;2.3 进阶训练 三、其他 一、前言 课题组这边是需要对机器视觉有所要求吧&#xff0c;也就是CV方向。这一届研三师兄也都是在大厂拿到30W的年薪了&#xff0c;也是需要拥抱深度学习这…

java收徒 java辅导 java试用期辅导 java零基础学习

&#x1f497;博主介绍&#xff1a;✌全网粉丝1W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末报名辅导&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;还有大家…

守护变电箱消防安全,全氟己酮自动灭火片该安装在哪个位置?

变电箱、配电柜、换电柜是电力设备的重要组成部分&#xff0c;安全性至关重要。但在使用过程中&#xff0c;容易受到电气、机械、环境等因素影响&#xff0c;出现接触不良、短路、漏电等安全隐患&#xff0c;从而引发火灾事故。为了及时防范火灾风险&#xff0c;提前安装一款能…

Vue中数组的【响应式】操作

在 Vue.js 中&#xff0c;当你修改数组时&#xff0c;Vue 不能检测到以下变动的数组&#xff1a; 当你利用索引直接设置一个项时&#xff0c;例如&#xff1a;vm.items[indexOfItem] newValue当你修改数组的长度时&#xff0c;例如&#xff1a;vm.items.length newLength 为…

Java基础(二)——数组,方法,方法重载

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 ⚡开源项目&#xff1a; rich-vue3 &#xff08;基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL&#xff09; &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1…

01_02_Mybatis的配置文件与基于XML的使用

1、引入日志 在这里我们引入SLF4J的日志门面&#xff0c;使用logback的具体日志实现&#xff1b;引入相关依赖&#xff1a; <!--日志的依赖--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version&g…

2024国内外音频转换器大盘点,盘点音乐剪辑的7个有效方法!

当遇到不支持的音乐文件时&#xff0c;您可能就会想要拥有一款优秀的音频转换器。当您想减小大量音乐文件以节省设备存储空间时&#xff0c;它也可以很好地帮上忙。如果您正在寻找这么一款音频转换器&#xff0c;那么&#xff0c;请不要错过这篇文章。一款顶尖的音频转换器不仅…

USB2.0学习1--基本概念

目录 1.USB概念 2.USB协议发展 3.USB接口类型 3.1 TYPE类型 3.2 Mini类型 3.3 Micro类型 4. USB体系结构和关键概念 4.1 USB工作原理 4.2 USB物理拓扑结构 4.3 USB逻辑拓扑结构 4.4 USB软件架构 4.5 USB数据流模型 4.5.1 USB设备端点 4.5.2 USB管道 4.6 USB即插…

网工内推 | 国企信息工程师,信息系统项目管理师优先,最高14薪

01 上海浦东软件园股份有限公司 &#x1f537;招聘岗位&#xff1a;信息化管理工程师 &#x1f537;岗位职责&#xff1a; 1. 根据公司战略、数字化总体架构规划和IT 技术趋势&#xff0c;制定信息化系统的规划与设计&#xff0c;并制定实施计划。 2. 统筹公司信息化系统管理…

Redis-实战篇-缓存击穿问题及解决方案

文章目录 1、缓存击穿2、常见的解决方案有两种&#xff1a;2.1、互斥锁2.2、逻辑过期2.3、两种方案对比 3、利用互斥锁解决缓存击穿问题3.1、ShopServiceImpl.java3.2、使用 jmeter.bat 测试高并发 4、利用逻辑过期解决缓存击穿问题 1、缓存击穿 缓存击穿问题 也叫 热点key问题…

<电力行业> - 《第4课:什么是电力?什么是发输变配用5环节?》

1 什么是电力&#xff1f; 我们对于平日生活中离不开的电很熟悉&#xff0c;但是电力是什么&#xff1f; 其实&#xff0c;电力就是电能作为动力的能源。电力就是我们说的电&#xff0c;不过更多了系统化。 19世纪70年代&#xff0c;电力的发明和应用掀起了第二次工业化高潮。…

关于WebSocket

WebSocket 与传统的 HTTP 协议对比 在实时通信领域&#xff0c;传统的 HTTP 协议存在以下一些问题&#xff1a; 频繁的请求和响应&#xff1a;每次通信都需要建立和关闭连接&#xff0c;带来额外的开销。高延迟&#xff1a;每次通信都需要经过多个网络层的传输&#xff0c;延…

Stm32的DMA的学习

一&#xff0c;介绍 二&#xff0c;DMA框图 三&#xff0c;DMA通道 四&#xff0c;相关HAL库函数 五&#xff0c;配置DMA 六&#xff0c;Stm32CubeMX配置 【13.1】减少CPU传输负载 DMA直接存储器访问—Kevin带你读《STM32Cube高效开发教程基础篇》_哔哩哔哩_bilibili

【鸿蒙 HarmonyOS】尺寸设置:size/layoutWeight/constraintSize

一、背景 常见尺寸&#xff1a;width&#xff08;宽度&#xff09;、height&#xff08;高度&#xff09;、padding&#xff08;内边距&#xff09;、margin&#xff08;外边距&#xff09; 主要整理下size&#xff08;设置高宽尺寸&#xff09;、layoutWeight&#xff08;对…