【javaWeb项目】基于网页形式,通过浏览器访问的java应用程序,就称为javaweb程序

JavaWeb前端

第一章

1、javaWeb是什么

	//基于网页形式,通过浏览器访问的java应用程序,就称为javaweb程序

2、web程序的分类

	//1、静态web程序特点:网页上的内容是固定不变的,不能动态加载,例如web前端//2、动态web程序特点:1、页上的内容可以根据请求的不同,动态加载数据,例如javaweb程序2、动态web程序可以与用户动态交互3、企业开发涉及到的应用程序主要是动态web程序

3、不同点

	1、静态web无法与用户动态加载数据,动态web程序则可以与用户交互,根据请求加载不同数据2、静态web程序用浏览器打开页面即可直接运行,web动态程序必须在一个特定的环境中才能运行,环境称为web容器(web服务器)

4、web服务器

web服务器用于给web程序提供一个运行环境,只要将web程序(静态或动态都可以)放入到web服务器中,就能通过网络进行访问常用服务器:
1、tomcat/*应用最多*/
2、jboss
3、weblogic
......Tomcat的特点:1、tomcat免费2、不需要解压缩,配置简单3、小巧灵活
tomacat版本tomacat版本需要与jdk版本对应,jdk是1.8,推荐8.5的版本

5、开发工具

idea的版本以年份为版本:个人推荐2018.2

6、idea使用

1、psvm----生成主函数main
2、sout----输出语句
3、alt+insert------生成get,set,tostring//右键 grnreate
4、选中报错位置,然后alt-----处理异常

在这里插入图片描述

get set tostring

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

在这里插入图片描述

推荐插件: rainbow(彩虹)

​ 作用:如果代码有很多括号,每一对括号的颜色不同

7、idea的相关设置

1、局部设置--只对当前空间有效,切换项目需要重新配置
2、全局配置---配置一次,对所有项目都有效(推荐)

8、tomcat服务器配置文件

要将项目部署到tomcat中,只需要把项目拷贝到tomcat/webapps目录下即可
在这里插入图片描述

9、启动tomcat服务器

	1、单独启动tomcat,不借助idea//找到tomcat的文件位置 进入bin 启动startup.bat  停止shutdown.bat注意:如果启动了tomcat就不能再次启动,否则会报错如果tomcat无法启动,原因是没有配置Java_HOME变量
	2、在idea中启动服务器Web项目的目录结构:src:存放java原文件web:存放html,jsp,css,img,jsWEB-INFweb.xml-------------核心配置文件lib-----------------放依赖,也就是jar

第二章

主要内容:jsp的基本应用 servlet的使用

1、HTML页面与jsp页面有什么区别
主要区别:1、HTML是静态页面,无法动态加载数据,不能与用户交互2、jsp的动态页面,可以加载数据,能交互jsp的本质:jsp:Java server page它是由运行服务器端的java程序动态生成的页面jsp本质上是一个java类,只不过它是以页面的形式呈现数据
2、简易登录案例

如果要在jsp页面编写java代码,只需要在页面写下标记

<%java脚本
%>
java脚本的作用,用于在jsp页面中嵌入java代码  

重要方法

1、设置编码格式

默认情况下,表单提交数据会采用latin文编,格式为iso-8859-1,这种不支持中文解决方案:在取值之前,设置请求(request)的编码格式request.setCharacterEncoding("utf-8");//在取值之前设置string name=request.getParameter("user");

2、获取表单数据

获取表单提交的数据string val=request.getParameter("表单中控件的name的名称")//request:请求//Parameter:参数示例:string name=request.getParameter("user");//获取表单中的用户名System.out.println("姓名"+name);//输出到控制台out.println("姓名"+name+"<br>");//输出到页面//br:换行显示

3、跳转页面

	跳转页面的方法(固定写法)request.getRequestDispatcher("/xxx.jsp").forward(request,response)

4、存储

存值将数据存储在request中,跳转页面中可以取到存储的数据request.setAttribte("消息的key",);//键:必须是字符串类型//值:可以为任意类型(string 对象 集合)示例:request.setAttribte("err","用户或密码错误");取值在jsp页面中,获得存储request中的消息要获得存储在request中的数据,显示在页面,我们需要使用"EL表达式"格式:${消息的key}示例:${err}

5、使用request没有提示,是因为没有导包
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3、jsp模型I

如果jsp页面即作为视图组件与用户交互,又作为控制器组件处理程序流程,这样的架构称为jsp模型

jsp模型缺点:视图显示与流程控制的代码都是在jsp页面中完成,随着功能的增加,可读性变差

搞错了,数据库被遗忘了,等我看完数据库再回来看

2023.4.14 学完数据库归来

开发中提供一种:“单一性原则”,一个组件只做一件事为了解决该问题,jsp提供了另一种模型:“jsp模型2
4、jsp模型II

在jsp模型II中,jsp只作为视图组件呈现界面与用户交互,它不在作为控制器,控制程序流程

程序中的控制器组件由一个java类:servlet类servlet作为控制器类,用于控制程序

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

5、servlet

什么是servlet?

servlet是一个运行在服务端的java组件,它一般作为控制器,用于接受用户的请求,对请求做出响应响应:根据请求处理的不同结果,呈现不同的页面给客户端
6、servlet配置方式

方式1:采用注释

@webServlet("/login")

方式2:隐射的方式

    <servlet><!--3、匹配别名--><servlet-name>abc</servlet-name><!--4、找到对应的servlet进行处理--><servlet-class>com.arjunna.web.loginServlet</servlet-class></servlet><servlet-mapping><!--2、生成别名--><servlet-name>abc</servlet-name><!--1、配置映射,指定如何匹配请求--><url-pattern>/first</url-pattern></servlet-mapping>

在这里插入图片描述

第三章 servlet

1、一个类要成为servlet必须满足下列条件

1、servlet必须是HttpServlet的子类2、必须重写父类的doGet或doPost方法,运行重写两个,最少一个如果请求方式是get会进入doget如果请求方式是post会进入doPost3、方法必须接受两个参数HttpServletRequest	-------请求对象通过它可以获得与本次请求相关的所有信息HttpServletResponse	-------响应对象通过它可以执行与响应相关的操作4、方法必须要抛出两种异常ServletExceptionIoException

普通类成为servlet处理请求的要求:

在这里插入图片描述

2、配置servlet

I、在web.xml中配置
    <servlet><!--3、匹配别名-->
<servlet-name>abc</servlet-name> 第三步<!--4、找到对应的servlet进行处理-->第四步<servlet-class>com.arjunna.web.loginServlet</servlet-class></servlet><servlet-mapping><!--2、生成别名--><servlet-name>abc</servlet-name>  第二步<!--1、配置映射,指定如何匹配请求--> 第一步<url-pattern>/first</url-pattern></servlet-mapping>
II、采用注解配置
@webServlet("/login")
public class loginServlet extends HttpServlet {
}

3、servlet将数据输出显示在控制台

 request.setCharacterEncoding("UTF-8");--只能处理表单提交数据的乱码//        设置响应的编码格式,防止输出流产生中文乱码response.setContentType("text/html;charset=utf-8");//产生输入流,用于将数据显示在客户端浏览器上PrintWriter out =response.getWriter();//输出内容到客户端浏览器out.write("<h1>你好,世界</h1>");//刷新流,保证所有内容都可以被输出out.flush();//关闭流out.close();

4、解决中文乱码

如果表单提交的数据有中文,会产生乱码request.setCharacterEncoding("UTF-8");String xx=request.getParameter("xx");如果用流输入的内容有中文response.setContentType("text/html;charset=utf-8");PrintWriter out =response.getWriter();

5、有哪些方式进入servlet

只要表单可以发送post请求

I、表单提交可以进入servlet
默认get方式,但这种不安全,所有信息会显示在地址栏中建议采用method="post"表单提交时既可以发送get请求,也可以发送post请求
II、超链接可以进入servlet
超链接只能发送get请求,只能进入doGet方法
<a href="second">超链接</a>
III、直接在浏览器地址中输入请求名
这种只能发送get请求
IIII、通过jsp:forward标签跳转
<jsp:forward page="first">在jsp页面中,只要遇到此标记,系统就会自动发出请求进行跳转这种方式只能发送get请求

6、向servlet传递参数的方式

I、表单提交传递参数
<form action="login" method="post">姓名:<input type="text" name="user"><br>密码:<input type="password" name="pwd"><br><input type="submit" value="提交">
</from>
II、超链接传递参数
1、超链接传递一个参数<a href="请求名称?参数名=值">超链接</a><a href="second?id=1">在servlet中取参数的写法是String val=request.getParameter("参数名");String id=request.getParameter("id");注意:?只能用一次2、超链接传递多个参数要求:第一个参数用?连接,后面的所有参数都要&连接<a href="请求名称?参数名1=值&参数名2=值">超链接</a><a href="second?id=12&name=jack">在servlet中取参数的写法是String val=request.getParameter("参数名");String id=request.getParameter("id");String name=request.getParameter("name");

7、处理增删改查

I、针对每一个操作编写一个servlet进行处理
		<a href="add">增加<a><a href="del">删除<a><a href="update">修改<a><a href="sel">查询<a>这种写法会导致产生大量冗余代码
不会使用的
II、将增删改查写在同一个servlet类中
一般servlet中仅包含doGet与doPost方法,如果要包含其他方法,其他方法的格式要满足下列条件:protected void 方法名(HttpServletRequest request, 					HttpServletResponse response) throws ServletException, 		    IOException {}只有方法名可以自己写
解决方案:所有请求先进入doGet方法或doPost方法,用户要调用哪一个方法,就把该方法名称,作为参数传递进来,取到该参数然后手动调用自定义方法
		<a href="op?method=add">增加<a><a href="op?method=del">删除<a><a href="op?method=update">修改<a><a href="op?method=sel">查询<a>
package com.arjunna.web;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("/op")
public class opServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//调用doPost方法doPost(request,response);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//设置编码格式request.setCharacterEncoding("UTF-8");//接受参数的值String op=request.getParameter("method");//判断switch (op){case "add":add(request,response);break;case "del":del(request,response);break;case "update":update(request,response);break;case "sel":sel(request,response);break;}}protected void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("添加");}protected void del(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("删除");}protected void update(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("修改");}protected void sel(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("查询");}}

在这里插入图片描述

8、java中的反射机制

我们希望servlet类中的每一个方法,可以自动调用,不再手动判断,手动调用
答:要实现这个效果,我们可以通过java中的反射机制来实现
I、反射的使用
作用:JAVA反射机制是在运行状态中对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;
II、什么是反射
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
III、要执行反射的前提条件
要对一个对象进行反射操作,前提条件是要获得当前类字节码文件所应的对象Class
IIII、获得class的三种方式
    //方式1:直接获取public void one(){Class clazz= userInfo.class;System.out.println(clazz);}//方式2:通过类的实例获得class对象public void two(){userInfo user=new userInfo();Class clazz= user.getClass();System.out.println(clazz);}//方式3:通过类的全路径获取classpublic void three() throws ClassNotFoundException {Class clazz= Class.forName("com.arjunna.enty.userInfo");System.out.println(clazz);}
IIIII、通过class对象,获得类中的属性
  
//区分修饰符
public void one(){//获得class对象Class clazz= userInfo.class;//通过class获得当前类中的属性(字段:field)//此方法只能获得类中public修饰的属性Field[] arrs=clazz.getFields();for(Field f:arrs){System.out.println(f.getName());}}-----------------------------------------------
//不区分修饰符public void two(){//获得class对象Class clazz= userInfo.class;//通过class获得当前类中的属性(字段:field)//此方法获得所有声明的属性(不区分修饰符)Field[] arrs=clazz.getDeclaredFields();for(Field f:arrs){System.out.println(f.getName());}}
IIIIII、通过class获得类中的方法
    //获取当前类以及上一级类中的所有方法(不区分修饰符)public void one(){//获得class对象Class clazz= userInfo.class;//获得类中的方法Method[] methods=clazz.getMethods();for (Method method:methods){System.out.println(method.getName());}}-----------------------------------------------//获得当前类的所有方法(不区分修饰符)public void two(){//获得class对象Class clazz= userInfo.class;//获得类中的方法Method[] methods=clazz.getDeclaredMethods();for (Method method:methods){System.out.println(method.getName());}}-----------------------------------------------//根据方法名,获得类中的指定方法(不带参数)public void there() throws NoSuchMethodException {//获得class对象Class clazz= userInfo.class;//获得类中的方法Method methods=clazz.getDeclaredMethod("getPwd");System.out.println(methods.getName());}-----------------------------------------------//根据方法名,获得类中的指定方法(带参数)public void four() throws NoSuchMethodException {//获得class对象Class clazz= userInfo.class;//获得类中的方法Method methods=clazz.getDeclaredMethod("test", int.class, String.class);System.out.println(methods.getName());}
IIIIIII、通过class对象执行类中的指定方法
    //执行类中的public方法public void one() throws Exception {//获得class对象Class clazz= userInfo.class;//获得要执行的public的方法Method method=clazz.getDeclaredMethod("add");//通过class获得当前类的实例Object obj=clazz.newInstance();//在对象上执行特定的方法method.invoke(obj);}-----------------------------------------------//默认情况下,只能访问public方法,如果要访问其他修饰符,需要进行暴力反射public void two() throws Exception {//获得class对象Class clazz= userInfo.class;//获得要执行的public的方法Method method=clazz.getDeclaredMethod("del");//通过class获得当前类的实例Object obj=clazz.newInstance();//配置暴力反射(忽略访问修饰符,强制调用方法)method.setAccessible(true);//在对象上执行特定的方法method.invoke(obj);}-----------------------------------------------(重点关注)//执行类中的带参方法public void there() throws Exception {//获得class对象Class clazz= userInfo.class;//获得要执行的public的方法Method method=clazz.getDeclaredMethod("test", int.class, String.class);//通过class获得当前类的实例Object obj=clazz.newInstance();//配置暴力反射(忽略访问修饰符,强制调用方法)method.setAccessible(true);//在对象上执行特定的方法//(对象实例,参数1,参数2)method.invoke(obj,1,"李白");}-----------------------------------------------(重点关注)//执行带返回值的方法public void four() throws Exception {//获得class对象Class clazz= userInfo.class;//获得要执行的public的方法Method method=clazz.getDeclaredMethod("test2", int.class, int.class);//通过class获得当前类的实例Object obj=clazz.newInstance();//配置暴力反射(忽略访问修饰符,强制调用方法)method.setAccessible(true);//在对象上执行特定的方法//接受返回的参数Object val = method.invoke(obj,2,3);System.out.println("返回值是:"+val);}

9、使用反射简化servlet操作

I、编写BaseServlet
要求:BaseServlet需要继承HttpServletpackage com.arjunna.web;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.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;/*
* 反射的应用
* */
public class BaseServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doPost(req,resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {try {//获得当前类的class对象Class clazz=this.getClass();//获得客户端请求的方法String methodName=req.getParameter("method");//通过class对象,获得当前类中指定名称的方法Method method=clazz.getDeclaredMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);//配置暴力反射(忽略访问修饰符,强制调用方法)method.setAccessible(true);//通过反射执行指定的方法method.invoke(this,req,resp);}catch (Exception e){e.printStackTrace();}}}
II、让子类继承于BaseServlet类
@WebServlet("/op")
public class opServlet extends BaseServlet {protected void add(HttpServletRequest request, 					HttpServletResponse response) throws ServletException, 		IOException {System.out.println("添加");}protected void del(HttpServletRequest request, 					HttpServletResponse response) throws ServletException, 		IOException {System.out.println("删除");}protected void update(HttpServletRequest request, 				HttpServletResponse response) throws ServletException, 		IOException {System.out.println("修改");}protected void sel(HttpServletRequest request, 					HttpServletResponse response) throws ServletException, 		IOException {System.out.println("查询");}/*         如果子类继承父类,子类就自动拥有父类的方法         */
}

在这里插入图片描述

第四章

项目步骤

1、创建项目
2、导入相关依赖(jar)
3、导入配置文件conf--->druid.properties
4、创建包结构utildaoentyweb
5、导入公共类1、JDBCUtil类2、BaseServlet类
6、编写实体类,与数据表的结构对应
7、编写infoDao类
8、编写InfoServlet类
9、编写jsp页面
10、导入jsp标签库的依赖  简化jsp的编码jstl.jarstandard.jar
11、在jsp页面中引入
<%@ taglib prefix="c"  uri="http://java.sun.com/jstl/core_rt" %>
12、使用c:forEach遍历数据即可

1、简单的前后端交互

在java代码中,向request中存储数据request.setAttribute("键",值);-----必须是string类型值-----可以是任何类型(objcet)request.setAttribute("list",list)在java代码中,从request中取数据数据类型  变量名 = (数据类型) request.getAttribute("键");List<userInfo> list =(List<userInfo>) request.getAttribute("list");//要强制转换

在jsp页面中,对request中存储的List的集合遍历,显示成表格

方式1:在jsp页面中,采用java脚本的方式遍历
方式1:在jsp页面中,采用java脚本的方式遍历<table border="1" style="margin:0 auto;width: 60%;text-align: center"><tr><th>编号</th><th>姓名</th><th>密码</th><th>余额</th></tr><%//接受交互层传递的requestList<userInfo> list= (List<userInfo>) request.getAttribute("list");//遍历打印在页面上for (userInfo u:list) {out.write("<tr>");out.write("<td>"+u.getId()+"</td>");out.write("<td>"+u.getName()+"</td>");out.write("<td>"+u.getPwd()+"</td>");out.write("<td>"+u.getBalance()+"</td>");out.write("</tr>");}%></table>缺点:当代码稍微复杂一点,代码的可读性会变的非常差
方式2:使用JSTL标签库

jstl:jsp标准标签库

javaweb中,把jsp页面经常会使用的一些功能,封装成了标签,通过标签可以简化jsp页面的编码,避免在jsp页面中编写java脚本,简化页面编码<c:forEach items="${存储的集合的名称}" var="从集合中取到的每一个对象"><c:forEach>

使用便签库遍历数据

    <table border="1" style="margin:0 auto;width: 60%;text-align: center"><tr><th>编号</th><th>姓名</th><th>密码</th><th>余额</th></tr><c:forEach items="${list}" var="u" varStatus="st"><tr><td>${u.id}</td><td>${u.name}</td><td>${u.pwd}</td><td>${u.balance}</td></tr></c:forEach></table>items-----它用于指定要遍历的集合名称var-------它用于指定变量,保存从集合遍历出来的每一个对象varStatus------它用于指定变量,只在当前对象在集合中的状态信息${st.index}-------得到当前对象在集合中的下标(从0开始)${st.count}-------得到当前对象在集合中的第几个对象(从1开始计数)${st.first}-------判断当前是否是集合的第一对象${st.last}-------判断当前是否是集合的最后一对象

在这里插入图片描述

修改数据的思路:

1、点击连接,将要修改的id传回到后台
2、在后台代码中,根据id查询出一条数据,封装成对象,存储在request中
3、跳转到修改页面,将要修改的旧数据显示在控件,供用户查询-----数据回显
4、点击页面修改,将要修改的新数据提交到数据库

2、转发与重定向

I、javaweb程序跳转的方式有两种
方式1: 转发 foreardrequest.getRequestDispatcher("show.jsp").forward(request,response);特点:1、转发时是在服务器端完成的跳转,地址栏不会改变,依然是之前的请求地址,如果刷新页面请求就会重复执行2、转发时,request会作为参数向下传递参数,所以,存储在request中的数据,在下一个页面中是可以把request中的数据取出来3、转发时只能跳转到当前项目中的地址方式2: 重定向 redirectresponse.sendRedirect("show.jsp");特点:1、重定向,它是通过修改客户端浏览器地址栏的地址实现跳转,地址栏的信息会改变成跳转后的地址,之前的请求已经结束,此时再刷新页面,请求也不会执行2、重定向时,没有将请求继续向下继续传递,所以存在request中的数据,下一个页面取不到值3、重定向时,可以跳转到任意的URL地址
II、面试题:forward(转发)与redirect(重定向)的区别
1、forward它是在服务器端完成的跳转,地址栏不会变,依然是之前的请求地址重定向它是客户端地址栏中实现的跳转,地址栏会改变,之前的请求会结束2、转发时request会作为参数向下传递,所有存储在request中的数据再下一个页面可以取到,重定向时,没有将request作为参数向下传递,所以存储在request中的数据在下一个页面中取不到值3、转发时,只能在项目内跳转;重定向时,可以跳转到任意地址4、转发由request产生;重定向是由response产生@@一般在加载数据时用转发,增、删、改以后用重定向
III、重定向的两种写法
方式1:重定向到页面response.sendRedirect("show.jsp");方式2:重定向到serVlet中的某一个方法中response.sendRedirect("xxx?method=xxx")

第五章

—servlet的三种作用域

—jstl标签库的使用

—过滤器

1、servlet的三种作用域

**作用域:**作用域就是存储数据的有效范围

I、request:请求作用域
之前存储的数据时,采用如下形式request.setAttribute("键","值");request:它是一个请求对象,可以执行与请求相关的操作同时,它也是一个存储作用域,它存储的数据在一个请求(request)中有效,如果产生了新的请求,则之前存放在request(请求)中的数据会全部丢失

下列三种情况,会产生新的请求:

1、表单提交一次2、页面跳转一次3、页面刷新一次问题:怎么确保即使产生新的请求,数据也不会丢失?那么就需要更大的存储范围

II、HttpSession:会话作用域
HttpSession:会话(比请求作用域大)它是一个存储作用域,存放在会话作用域中的数据与请求无关,不论产生多少个请求,都不会影响到存放在会话作用域中的数据问题1:什么时候产生?当客户端与服务器端建立连接时,会话就会自动产生,会话作用域产生后就可以向该作用域存储数据,只要这个会话不中断,存储的数据将一直有效问题2:客户端与服务器端建立连接?值客户端用浏览器访问这个web应用程序,我们就称为:与服务器建立了连接问题3:会话中断指关闭正在访问web程序的浏览器,我们就称为:”会话中断“只要客服端与服务器端建立连接,就会自动产生会话“HttpSession“(如打电话)

第一步:在serlvet中获得会话

	HttpSession session=request.getSession();

第二步:向会话作用域中存储数据

	session.setAttribute("消息的key",“数据”);键:必须是字符串类型值;可以为任意字符注释:与request的使用一模一样

第三步:从会话中取数据(在java中取值)

	类型 val =(类型) session.getAttribute("消息的key");

第三步:从会话中取数据(在jsp页面中取值)

	${消息的key}
会话(session)作用域的特点
	1、存放在session作用域中的数据与请求无关,不论产生多少个新的请求,都不会影响到存储在会话中的数据2、数据如果存储在session中,不论是转发还是重定向都可以取到值(与跳转方式无关)3、当session中断时,存放在session中的数据会全部丢失下列三种情况session会中断:1、关闭浏览器2、默认情况下,如果三十分钟内没有操作,session会因为闲置超时过期idle 闲置 expire 失效session.setMaxInactiveInterval();设置session过期时间3、调用session.invalidate();此方法调用后,session会马上失效4、当客户端与服务器端建立连接时,服务器端会为每一个客户端分配一个session,用于存储当前客户端的数据,每一个客户端的session,只有当前客服端自己才能访问只要打开一个新的浏览器访问web程序,系统就会认为是一个新的客户端,就会分配一				个session给当前用户存储数据(一个浏览器就是一个新客户端)

在这里插入图片描述

session只能查看当前用户自己访问web程序的次数但是如果想要查看这个web程序启动以来,有多少个用户访问过,就需要更大的存储空间

III、 servletContext 全局上下文(全局作用域)
servletContext​			它是最大的存储作用域​			在web程序启动时(tomcat)全局上下文就开始了,知道服务器停止,全局上下文才会结束,只要服务器在运行,存放在全局上下文中的数据将一直有效
全局上下文的特点
	1、只要服务器在运行,存放在全局上下文的数据将一直有效,可以随时存,随时取2、全局上下文不区分用户,存放在全局上下文中的数据是全局共享(任何用户都可以取到)
获得全局上下文
servletContext cxt=this.getServletContext();
在servlet中,向全局上下文存数据
cxt.setAttribute("消息的key",值)
在servlet中,从全局上下文取数据
类型 val=(类型) cxt.getAttribute("消息的key");
在jsp页面中,从全局上下文取数据
${消息的key}

IIII、三种作用域总结
三种作用域:​				request--------------------------------------请求作用域​				session--------------------------------------会话作用域​				servlet----------------------------------------全局上下文**存数据的方式:**​				作用域.setAttribute(“key”,值);**取数据的方式**​				类型 val = (类型)  作用域.getAttribute(“key”);**jsp页面取值**​				${}**以上三种存储作用域的范围从小到大排序依次是:**​				request   <    session	<	servletContext(几乎不用)**问题:我们在编写代码时,应该使用哪一种存储作用域存数据**​			原则:优先考虑范围较小的作用域,如果较小的范围解决不了问题,才会考虑大范围

2、jstl标签库

I、什么是jstl?
jstl:称为JSTL标准标签库,把一些jsp页面的常见功能封装成标签,通过标签可以简化jsp的页面,避免出现java小脚本
II、分类
前提条件:要使用jstl的标签,首先要导入两个依赖1standard.jar2、jstl.jar
1、核心标签库

要使用核心标签库,需要在jsp页面中引入核心标签库的指令

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>

EL表达式的取值原理:

<c:set var="msg" value="hello" scope="page"/>
<c:set var="msg" value="hello" scope="request"/>
<c:set var="msg" value="hello" scope="session"/>
<c:set var="msg" value="hello" scope="application"/>方式1:${msg}这种方式,没有指定作用域的范围,系统会默认从最小的作用域开始取,如果小的范围中能找到,就不会再查找大范围,如果没有找到,就会依次从大范围中查找方式2:${作用域范围.msg}这种方式取值,只会查找特定的存储范围,如果没有找到,也不会再查找其他范围${pageScore.msg}------page范围${requestScore.msg}------request范围${sessionScore.msg}------session范围${applicationScore.msg}-----application范围注意:在使用el表达式的时候,指定范围,性能会更好

核心标签库的分类


1、通用标签<c:set>作用:在jsp页面中设置一个变量,存储在作用域中使用:<c:set var="msg" value="hello" scope="作用域的名称"/>var="msg"-----------设置了一个变量名叫msgvalue="hello"-------它的值是helloscope=""------------设置该变量的存储范围(默认是page作用域)作用域有四种:1、page--------它存储的数据仅在当前页面有效,离开当前页就取不到2、request-----它存储的数据在request中有效3、session-----它存储的数据在session中有效4、application--它存储的数据在整个应用程序中有效(servletContext)<c:redirect>作用:在页面进行重定向使用:<c:redirect url="show.jsp">url="show.jsp"---重定向到页面url="op?method=init"-----重定向到某个方法上2、逻辑标签:用于在页面中进行逻辑判断<c:if>作用:用于进行条件判断,如果条件成立,就执行if块的代码使用:<c:if test="${条件判断}">代码<c:if>案例:分数:${requestScore.score}考核结果:<c:if test="${requestScore.score>=60}"><b style="color:green">合格</b></c:if><c:if test="${requestScore.score<60}"><b style="color:red">不合格</b></c:if><c:choose> <c:when> <c:otherwise>作用:这三个标签组合在一起,类似java中的多重if使用:<c:choose><c:when test="${表达式1}">代码1<c:/when><c:when test="${表达式2}">代码2<c:/when><c:when test="${表达式3}">代码3<c:/when><c:otherwise>代码4<c:/otherwise></c:choose>案例:分数:${requestScore.score}考核结果:<c:choose><c:when test="${requestScore.score>=90}">优秀<c:/when><c:when test="${requestScore.score>=80}">良好<c:/when><c:when test="${requestScore.score>=60}">合格<c:/when><c:otherwise>不合格<c:/otherwise></c:choose>	3、迭代标签:也称为循环标签<c:forEach>作用:用于对集合循环遍历使用1:<c:forEach items="${list}" var="u" varStatus="st"><tr><td>${u.id}</td><td>${u.name}</td><td>${u.pwd}</td><td>${u.balance}</td></tr></c:forEach>items-----它用于指定要遍历的集合名称var-------它用于指定变量,保存从集合遍历出来的每一个对象varStatus------它用于指定变量,只在当前对象在集合中的状态信息使用2:<select><option value="-1" >请选择年龄</option><c:forEach var="k" begin="1" end="120">								<option value="${k}">${k}岁</option></c:forEach></select>>在页面中生成循环结构bengin:表示从几开始end:到几结束val:保存循环产生的每一个值
2、格式化标签库

作用:用于转换数据格式

前提条件:<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt_rt" %>

转换日期类型的数据

//在请求中存值
request.setAttribute("bir",new Date());   //格式化日期<fmt:formatDate value="${requestScope.bir}" pattern="yyyy-MM-dd HH:mm:ss E"></fmt:formatDate>

转换货币格式的数据

//在请求中存值
request.setAttribute("salary",123456.7895);  //格式化金额
<fmt:formatNumber value="${requestScope.salary}"  type="currency"/>
3、sql标签库(已废弃)

III、标签的示例:

示例1:要求某一个页面只有登录用户才能查看,未登录的用户不允许查询页面(一般用户登录成功后,我们会将用户信息存放在session中,只有session不中断,就可以一直记录当前用户的状态信息)

**1、盗链:**越过登录直接访问网页地址

在这里插入图片描述

解决方法:

	显示页面<%--//判断用户是否登录,如果没有登录就直接跳转到登录页面--%><c:if test="${sessionScope.user==null}"><c:redirect url="login.jsp"/></c:if><h1>${sessionScope.user}</span>,欢迎您! </h1>但此方法也有问题,一旦页面多了就得每个页面都写一个,过于麻烦
2、回显数据,转换日期格式
<input type="Date" value="<fmt:formatDate value="${requestScope.bir}" pattern="yyyy-MM-dd">">日期标签里面嵌套格式化日期标签
3、单选按钮的数据回显
<input type="radio" name="gender" value="男" 							<c:iftest="${user.gender=='男'}">checked</c:if>>男<input type="radio" name="gender" value="女"<c:if test="${user.gender=='男'}">checked</c:if>>女将查询到的用户性别做逻辑判断,匹配的加上checked属性
4、下拉选项数据回显
<select name="gender"><option value="-1" <c:if test="${gender=='-1'}">selected</c:if>>全部学生		</option><option value="男" <c:if test="${gender=='男'}">selected</c:if>>男生			</option><option value="女" <c:if test="${gender=='女'}">selected</c:if>>女生			</option>
</select>查询条件相等的加上selected属性
5、在idea中编写代码中如果出现黄色的波浪线,是因为系统检测到重复代码

1、只要编写一句不一样就OK

2、file>Inspections>Duplicated code取消√即可

3、数据的分页使用

-- 设涉及到分页的sql语句-- 分页查询的语句:select * from info limit 开始下标,几条数据;
-- 每页显示3条select * from info limit 0,3-----第1页select * from info limit 3,3-----第2页select * from info limit 6,3-----第3页select * from info limit,3-----第N页-- 开始下标=(当前页-1)* 每页条数
-- 开始下标-(N-1)* 3

要分页显示数据必须要知道的四个值

1、当前页 page2、每页显示的条数	rows3、一共有几条数据	count4、一共可以显示多少页  maxPage
总页数公式 = 总条数 % 每页条数 == 0 ?总条数/每页条数:总条数/每页条数 +1
int maxPage = count % rows == 0 ? count/rows : count/rows+1

分页流程

阶段1:显示全部数据
阶段2:只显示前3条数据
阶段3:实现分页
阶段4:优化分页

第六章

完善第五章的内容(新内容分页)

第七章

1、分页的优化

        <tr><td colspan="6"><c:if test="${page==1}"><span>首页</span><span>上一页</span></c:if><c:if test="${page!=1}"><a href="op?method=init&page=1">首页</a><a href="op?method=init&page=${page-1}">上一页</a></c:if><c:if test="${page==maxPage}"><span>尾页</span><span>下一页</span></c:if><c:if test="${page!=maxPage}"><a href="op?method=init&page=${page+1}">下一页</a><a href="op?method=init&page=${maxPage}">尾页</a></c:if>&nbsp;<span>当前第<select οnchange="location.href='op?method=init&page='+this.value"><c:forEach  var="k" begin="1" end="${maxPage}"><option value="${k}" <c:if test="${k==page}">selected</c:if>>${k}</option></c:forEach></select>页</span><span>共<b>${requestScope.maxPage}</b>页</span><span>每页<b>${requestScope.rows}</b>条</span><span>共<b>${requestScope.count}</b>条</span></td></tr>
多条件搜索后的分页
1、当点击搜索时,进入servlet中的search方法在该方法中获得所有查询条件,将查询条件存放在session2、然后从search方法中重定向带init方法,根据条件分页

2、过滤器 Filter

定义:过滤器,它是一个运行在服务器端的java组件,主要用于拦截用户请求,给请求附加功能在系统中配置了过滤器之后,客户端发出的请求在访问服务器的目标自愿(jsp,servlet)之前,会先进入过滤器,过滤器执行的代码完成之后,才会访问请求的目标资源

在这里插入图片描述

I、配置过滤器
过滤器属于工作类,一般放在util类

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

II、使用过滤器的场景
过滤器主要用于进行功能扩展
例如:拦截用户请求,判断用户是否登录,如果没有登录,自动转向登录界面使用过滤器进行权限判断,用户不登录可以看到页面,但如果要操作页面上的功能,就必须要登录。如果未登录,会自动转向登录界面

个人认为这个过滤器很简单,很实用

3、支付宝沙箱

它是支付宝用于开发中的一种环境,它的用法与真实环境的用法一样区别:1、它是用于开发环境中,主要用于测试环境支付功能,并不能真的付款,它使用的是测试数据2、它使用网关是开发环境的网关如果要转换成正式环境,只需要向支付宝提交营业执照,更换网关地址即可
项目开发中会涉及三种环境:1、开发环境:这个环境主要用于编写代码2、测试环境:开发结束后,用于测试代码的环境3、生产环境:项目开发全部结束,并且测试通过,项目要上线投入生产使用
沙箱账号商家信息
商户账号hsgxuj3492@sandbox.com
登录密码
商户PID2088721012026616
账户余额1000100.00买家信息
买家账号yruahu7657@sandbox.com
登录密码
支付密码
用户UID2088722012026626
用户名称yruahu7657
证件类型IDENTITY_CARD
证件账号216297196408127438
账户余额1000000.00 商家秘钥:支付宝公钥:网关地址:https://openapi.alipaydev.com/gateway.dotrade_no:2023042122001426620502312463---支付宝交易号
out_trade_no:202342117383328---商品交易号
total_amount:100.00---交易金额

第八章

1、支付宝的应用

app_id = "";merchant_private_key = "";alipay_public_key = "";return_url = "http://localhost:8080/alipay/return_url.jsp";gatewayUrl = "https://openapi.alipaydev.com/gateway.do";

要调用支付宝接口进行支付,必须提供四个参数

tradeNo---------订单编号
tradePrice------订单金额
tradeName-------订单名称
tradeMsg--*-----交易详情

编写一个servlet类,用于处理付款成功的回调,这样才能获得支付宝的交易号,才能执行退款操作


2、购物车的综合练习

流程
1、数据表分析2、加载全部商品3、判断用户是否登录4、用户的注册、登录5、添加商品到购物车中6、修改商品信息(增、删、改、查)7、分页显示商品8、支付
1、数据表的分析
1、商品表goods表goods_id 商品编号goods_name 商品名称goods_price 商品单价goods_prc 商品的图片2、用户表user表user_id 用户编号user_name 用户名称user_pwd 用户密码3、购物信息表cart表cart_id 购物编号user_id 用户编号---标识是哪一个用户的购物信息(外键,关联到用户表)goods_id 商品编号---标识购买的是哪一件商品(外键,关联到商品表)amout   购买数量

重定向传值

//传值response.sendRedirect("init.jsp?flag=ok");//取值${param.flag}

弹框


alert() 是单线程消息框,再没有点击之前,其他数据无法加载<c:if test="${param.flag=='ok'}"><script>new swal({title: '已加入购物车!',color: 'rgb(44, 153, 238)',text: '2秒后自动关闭。',timer: 2000}).then(function () { },function (dismiss) {if (dismiss === 'timer') {console.log('小趴菜')}})</script></c:if>

第九章

1、完善购物车案例

2、cookie的使用

3、文件上传下载

4、oos的使用

1、完善购物车

分页显示
1、当前页 page2、每页显示的条数	rows3、一共有几条数据	count4、一共可以显示多少页  maxPage
总页数公式 = 总条数 % 每页条数 == 0 ?总条数/每页条数:总条数/每页条数 +1
int maxPage = count % rows == 0 ? count/rows : count/rows+1
付款
1、支付宝的四个值2、导入依赖以及配置类3、编写页面1、订单编号2、订单名称3、订单金额4、订单详情

2、cookie

I、什么是cookie
cookie是由服务器端产生的一个文本,产生好以后,服务器将会把cookie发送到客户端保存cookie:它用于将用户信息保存在客户端
HttpSession:它用于将用户信息保存在服务器端cookie的作用:用于在客户端保存用户信息
II、cookie的工作原理
1、当客户端与服务器端建立连接时,服务器将会产生一个cookie,cookie可以记录一些用户信息,然后服务器会将cookie发送到客户端保存2、以后每一次客户端与服务器建立连接,保存在客户端的cookie将会自动跟随请求一起发送到服务器
III、cookie的保存位置
不同的浏览器,保存的cookie的位置不一样C:\Users\86159\AppData\Local\Google\Chrome\User Data\Default\Network
IIII、cookie的特点
cookie是在客户端以文本的方式保存用户信息,安全性不高,所以不能存储敏感信息,芽一班用于存储用户身份(userID、username)它主要在客户端记录当前用户的身份信息;
例如:用户几天之内不用登录,系统会自动登录
IIIII、cookie的基本使用

创建cookie

在服务器端创建cookie//创建cookieCookie ck=new Cookie("d118_cookie","这是一个新的cookie");//设置cookie的存活时间-秒ck.setMaxAge(120);//将cookie保存到客户端response.addCookie(ck);System.out.println("cookie发送成功!");

获得cookie

获得指定的cookie//获取请求携带的cookie----它只能获得当前程序发送到客户端保存的cookieCookie[] cks=request.getCookies();if (cks!=null){for (Cookie ck:cks) {if (ck.getName().equals("d118_cookie")){System.out.println("cookie的名字:"+ck.getName());System.out.println("cookie的值:"+ck.getValue());}}}

3、自动登录案例–cookie

获得复选框的值

 <input type="chekbox" value="ok" >//获得一组复选框选中的值String[] vals = request.getParameterValues("复选框的name'");//获取一个复选框的值
String str = request.getParameter("复选框的name");
*选中有值
*没有选中是null
package web;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/user")
public class cookieServlet extends BaseServlet {protected void init(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//读取cookie//获取请求携带的cookie----它只能获得当前程序发送到客户端保存的cookieCookie[] cks=request.getCookies();//指定的cookieCookie userCookie=null;//对所有的cookie遍历if (cks!=null){for (Cookie ck:cks) {if (ck.getName().equals("username")){//找到了指定的cookieuserCookie=ck;break;}}}if (userCookie!=null){//得到cookie的用户信息String user  = userCookie.getName();//将用户信息存到seesion中request.getSession().setAttribute("user",user);//重定向到显示页面response.sendRedirect("success.jsp");}else {//cookie已失效//没有找到指定cookieresponse.sendRedirect("login.jsp");}}protected void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取用户名String username = request.getParameter("user");if (username.equals("")){request.setAttribute("msg","用户名或密码错误");request.getRequestDispatcher("login.jsp").forward(request,response);}else{//将用户信息存放到session中request.getSession().setAttribute("username",username);//判断用户是否勾选记住登录String remember = request.getParameter("remember");if (remember!=null){//创建cookieCookie ck=new Cookie("username",username);//设置cookie的存活时间-秒ck.setMaxAge(20);//将cookie保存到客户端response.addCookie(ck);System.out.println("cookie发送成功!");}response.sendRedirect("success.jsp");}}}

4、文件上传

指客户端的文件上传到服务器1、编写工程2、导入依赖common-fileupload.jarcommon-io.jar3、编写页面4、编写servlet处理请求
1、编写上传页面的要求
1、表单提交方式必须post请求2、必须指定表单enctype="multipart/form-data"-----允许表单携带附件3、使用文件域选择文件<input type="file" name="file"><form action="" method="post" enctype="multipart/form-data">文件:<input type="file" name="file"><input type="submit" value="提交"></form>
2、上传案例
package com.web;import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;@WebServlet("/file")
public class fileServlet extends BaseServlet {SimpleDateFormat sfdate=new SimpleDateFormat("yyyy-MM-dd");Map<String,String> map=new HashMap<>();protected void up(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {try {//获得文件对象的工厂类,用于获得表单提交的所有数据(表单中提交的的数据,系统都会当成一个文件进行处理)FileItemFactory factory =new DiskFileItemFactory();//获得处理器ServletFileUpload sf=new ServletFileUpload(factory);//通过处理器,将表单请求中提交的每一条数据转换成文件对象FileItem放入list集合中List<FileItem> list=sf.parseRequest(request);//判断哪些是真正的文件,哪些是表单的普通数据//如果是真的文件,需要在服务器端生成物理文件,如果是普通数据直接使用for (FileItem item:list) {if (item.isFormField()){//如果返回true,就表示当前是表单的普通数据,如果false,则是文件//普通数据//获取当前普通数据的字段名称String key=item.getFieldName();//获得普通数据的值String value=item.getString("utf-8");//把数据存放到map中map.put(key,value);}else {//文件//获取时间,防止重名Date date=new Date();//获得上传的文件名String fileName = "a_"+sfdate.format(date)+"_"+UUID.randomUUID().toString()+"_"+item.getName();//在服务器指定路径下,生成新文件File file=new File("E:/upload",fileName);//判断文件目录是否存在if (!file.getParentFile().exists()){file.getParentFile().mkdirs();}//将上传文件的数据写入新文件中item.write(file);}}} catch (Exception e) {e.printStackTrace();}//        从map中取值String user=map.get("user");String pwd=map.get("pwd");request.getSession().setAttribute("user",user);request.getSession().setAttribute("pwd",pwd);//重定向response.sendRedirect("ok.jsp");}}

第十章

基于javaweb上传下载

oos对象存储服务

jxl

1、上传与下载

模拟向数据库添加文件

SimpleDateFormat sfdate=new SimpleDateFormat("yyyy-MM-dd");Date date=new Date();String fileName = "a_"+sfdate.format(date)
+"_"+UUID.randomUUID().toString()
+"_"+item.getName();//解决文件重名

上传

//上传protected void up(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {try {//获得文件对象的工厂类,用于获得表单提交的所有数据(表单中提交的的数据,系统都会当成一个文件进行处理)FileItemFactory factory =new DiskFileItemFactory();//获得处理器ServletFileUpload sf=new ServletFileUpload(factory);//通过处理器,将表单请求中提交的每一条数据转换成文件对象FileItem放入list集合中List<FileItem> list=sf.parseRequest(request);//判断哪些是真正的文件,哪些是表单的普通数据//如果是真的文件,需要在服务器端生成物理文件,如果是普通数据直接使用for (FileItem item:list) {if (item.isFormField()){//如果返回true,就表示当前是表单的普通数据,如果false,则是文件//普通数据//获取当前普通数据的字段名称String key=item.getFieldName();//获得普通数据的值String value=item.getString("utf-8");//把数据存放到map中map.put(key,value);}else {//文件//获取时间,防止重名Date date=new Date();//获得上传的文件名String fileName = "a_"+sfdate.format(date)+"_"+item.getName();//在服务器指定路径下,生成新文件File file=new File("E:/upload",fileName);//判断文件目录是否存在if (!file.getParentFile().exists()){file.getParentFile().mkdirs();}//将上传文件的数据写入新文件中item.write(file);//获得文件类型String type=fileName.substring(fileName.lastIndexOf(".")+1);map.put("type",type);//存放到map中//获得文件保存路径map.put("path",file.getAbsolutePath());//获得文件大小long num=file.length();//1024byte=1kb  1024kb=1mb//判断是以什么结尾String size="";if (num/1024/1024>=1){size=num/1024.0/1024+"Mb";}else{size=num/1024.0+"kb";}map.put("size",size);/******************上传成功后存到数据库********************/fdao.add(map.get("user"),map.get("pwd"),map.get("type"),map.get("path"),map.get("size"));}}} catch (Exception e) {e.printStackTrace();}//        从map中取值String user=map.get("user");String pwd=map.get("pwd");String type=map.get("type");String path=map.get("path");String size=map.get("size");request.getSession().setAttribute("user",user);request.getSession().setAttribute("pwd",pwd);request.getSession().setAttribute("type",type);request.getSession().setAttribute("path",path);request.getSession().setAttribute("size",size);//重定向response.sendRedirect("ok.jsp");}

下载

//下载protected void download(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获得下载的文件编号Integer id=Integer.parseInt(req.getParameter("id"));//到数据库查找该id的文件信息fileInfo f=fdao.findByid(id);/*******************下面是下载的代码******************************************///获得文件名,将文件名转换utf-8String fname= URLEncoder.encode(f.getFileName(),"utf-8");//只需要转换文件名//显示下载界面resp.setContentType("application/x-msdownload");//设置下载面板上显示的内容resp.setHeader("Content-disposition","attachment;fileName="+fname);//创建输入流,用于读取要下载的文件InputStream in=new FileInputStream(f.getFilePath());//通过响应产生输出流ServletOutputStream out=resp.getOutputStream();//创建字节数组,充当数据缓冲区byte[] b=new byte[8192];//定义变量保存写入到数据缓冲区的数据长度int len=0;//一边读一边写while ((len=in.read(b))!=-1){out.write(b,0,len);}out.close();in.close();}

2、在web程序中图片显示的问题

在web程序中,要显示图片,图片的路径只支持两种路径1、相对路径img/1.jpg
2、网络路径http://xxxx.xx.xx/xx.jpg绝对路径无法显示

解决图片上传的显示问题

解决方案1:使用分布式文件系统FastDFSFastDFS需要在linux系统中配置

在这里插入图片描述

解决方案2:使用对象oss服务阿里云对象存储 OSSObject Storage Service)是一款海量、安全、低成本、高可靠的云存储服务,提供最高可达 99.995 % 的服务可用性。多种存储类型供选择,全面优化存储成本。

3、oss服务配置及使用

阿里云账号
登录名:
账号ID:
手机号:1、服务器位置:oss-cn-beijing.aliyuncs.com2、AccessKey ID:AccessKey Secret:3、空间名称:4、上传文件名:6.jpg5、完整路径:e:/upload/6.jpg
package com.demo;import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;import java.io.FileInputStream;
import java.io.InputStream;public class fileUpload {public static void main(String[] args) throws Exception {// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。String endpoint = "oss-cn-.aliyuncs.com";// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。String accessKeyId = "";String accessKeySecret = "";// 填写Bucket名称,例如examplebucket。String bucketName = "";// 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。String objectName = "bg.jpg";// 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。// 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。String filePath= "E:\\upload\\bg.jpg";// 创建OSSClient实例。OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);try {InputStream inputStream = new FileInputStream(filePath);// 创建PutObjectRequest对象。PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);// 设置该属性可以返回response。如果不设置,则返回的response为空。putObjectRequest.setProcess("true");// 创建PutObject请求。PutObjectResult result = ossClient.putObject(putObjectRequest);// 如果上传成功,则返回200。System.out.println(result.getResponse().getStatusCode());} catch (Exception oe) {oe.printStackTrace();}}
}

第十一章

jxl解析电子表格文档

servlet的生命周期

jsp的内置对象

1、jxl解析电子表格文档

I、什么是jxl
jxl:它是操作电子表格文档excel的一种技术,通过它可以读取excel文件的数据,也可以将数据写入到excel文件
II、使用jxl解析excel文件
把excel中的数据读取到程序中电子表格文件的后缀名:*.xls、*.xlsx
jxl解析主要支持*.xls
poi可以解析*.xlsx一般在显示数据表格时,或者是批量导入数据时,导入到数据里

使用步骤

1、导入依赖jar  jxl.jar2、编写如下代码/*解析单个工作表*/
package com.sc.demo;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import java.io.FileInputStream;
import java.io.InputStream;public class demo {public static void main(String[] args) throws Exception {//创建输入流,用于读取要解析的文件InputStream in=new FileInputStream("e:/date/test.xls");//根据输入流的信息,产生工作簿Workbook wk=Workbook.getWorkbook(in);//获得工作簿中所有的表单Sheet[] sheets=wk.getSheets();//分别获得表单的名称
//        for (Sheet sheet:sheets) {
//            System.out.println(sheet.getName());
//        }//获得第一个表单的数据Sheet st=sheets[1];//获得表单的总行数int rows = st.getRows();//获得表单的总列数int cols=st.getColumns();//读取每一行、每一列的值for (int i=0;i<rows;i++){//遍历所有行for (int j=0;j<cols;j++){//遍历所有的列//根据列下标,行下标获得表单中指定的单元格Cell cell=st.getCell(j,i);//(列下标,行下标);//获得当前单元格中的内容String msg=cell.getContents();System.out.print(msg+"\t");}System.out.println();}}
}/*解析所有工作表的方法*/
package com.sc.demo;import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import java.io.FileInputStream;
import java.io.InputStream;public class demo {public static void main(String[] args) throws Exception {//创建输入流,用于读取要解析的文件InputStream in=new FileInputStream("e:/date/test.xls");//根据输入流的信息,产生工作簿Workbook wk=Workbook.getWorkbook(in);//获得工作簿中所有的表单Sheet[] sheets=wk.getSheets();//        获得所有的表单信息for (Sheet st:sheets) {System.out.println("----------------------------------------");//获得表单的总行数int rows = st.getRows();//获得表单的总列数int cols=st.getColumns();//读取每一行、每一列的值for (int i=0;i<rows;i++){//遍历所有行for (int j=0;j<cols;j++){//遍历所有的列//根据列下标,行下标获得表单中指定的单元格Cell cell=st.getCell(j,i);//(列下标,行下标);//获得当前单元格中的内容String msg=cell.getContents();System.out.print(msg+"\t");}System.out.println();}}}
}
III、将数据写入到xls文件中

只写入一个单元格的案例

package com.sc.demo;import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;public class demo2 {/** 写数据到excel* */public static void main(String[] args) throws Exception {//创建输出流OutputStream out= new FileOutputStream("e:Date/out.xls");//创建一个可以写入数据的工作簿WritableWorkbook wk= Workbook.createWorkbook(out);//在工作簿中创建表单,并设置表单名称WritableSheet st = wk.createSheet("d118", 0);//参数1:表单名称,参数2:表单的下标//创建一个标签Label-----它就是每一个单元格要显示的内容Label labelid=new Label(0,0,"编号");//(列下标,行下标,标签显示的名称)//将标签放到表单中st.addCell(labelid);//将工作簿的数据写入到文件中wk.write();//关闭工作簿wk.close();out.close();System.out.println("数据已写入");}
}

将数据库的数据写入到excel表格中

package com.sc.demo;import com.sc.dao.stuDao;
import com.sc.enty.stuInfo;
import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.List;public class demo2 {/** 写数据到excel* */public static void main(String[] args) throws Exception {//创建输出流OutputStream out= new FileOutputStream("e:Date/out.xls");//创建一个可以写入数据的工作簿WritableWorkbook wk= Workbook.createWorkbook(out);//在工作簿中创建表单,并设置表单名称WritableSheet st = wk.createSheet("d118", 0);//参数1:表单名称,参数2:表单的下标//创建一个标签Label-----它就是每一个单元格要显示的内容Label labid=new Label(0,0,"编号");//(列下标,行下标,标签显示的名称)Label labname=new Label(1,0,"姓名");Label labage=new Label(2,0,"年龄");Label labgender=new Label(3,0,"性别");Label labclazz=new Label(4,0,"班级");Label labtel=new Label(5,0,"电话");Label labtime=new Label(6,0,"注册日期");Label labres=new Label(7,0,"备注");//将标签放到表单中st.addCell(labid);st.addCell(labname);st.addCell(labage);st.addCell(labgender);st.addCell(labclazz);st.addCell(labtel);st.addCell(labtime);st.addCell(labres);stuDao sdao=new stuDao();//获得要写入的数据List<stuInfo> list=sdao.init();for (int i=0;i<list.size();i++){//蝴蝶每一个对象stuInfo stu=list.get(i);Label id=new Label(0,i+1,stu.getSid().toString());Label name=new Label(1,i+1,stu.getSname());Label age=new Label(2,i+1,stu.getSage().toString());Label gender=new Label(3,i+1,stu.getSgender());Label sclass=new Label(4,i+1,stu.getSclass());Label tel=new Label(5,i+1,stu.getStel());Label time=new Label(6,i+1,stu.getSregtime());Label res=new Label(7,i+1,stu.getRes());//将标签添加到表单中st.addCell(id);st.addCell(name);st.addCell(age);st.addCell(gender);st.addCell(sclass);st.addCell(tel);st.addCell(time);st.addCell(res);}//将工作簿的数据写入到文件中wk.write();//关闭工作簿wk.close();out.close();System.out.println("数据已写入");}
}

设置写入到exce中的样式

package com.sc.demo;import com.sc.dao.stuDao;
import com.sc.enty.stuInfo;
import jxl.Workbook;
import jxl.write.*;import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.List;public class demo2 {/** 写数据到excel* */public static void main(String[] args) throws Exception {//创建输出流OutputStream out= new FileOutputStream("e:Date/out.xls");//创建一个可以写入数据的工作簿WritableWorkbook wk= Workbook.createWorkbook(out);//在工作簿中创建表单,并设置表单名称WritableSheet st = wk.createSheet("d118", 0);//参数1:表单名称,参数2:表单的下标/*****************************在写入数据前,设置表格的数据样式************************************/
//
//           设置表格每一列宽度或高度st.getSettings().setDefaultColumnWidth(25);//列宽
//            st.getSettings().setDefaultRowHeight(15);//行高
//        指定一种可以用流写入文件的字体(字体类型,字体大小,字体是否加粗)//大标题的样式WritableFont ft=new WritableFont(WritableFont.ARIAL,20,WritableFont.BOLD);
//            指定一种单元格的格式(参数:字体)WritableCellFormat wcf=new WritableCellFormat(ft);wcf.setAlignment(Alignment.CENTRE);//内容居中对齐wcf.setBorder(Border.ALL, jxl.format.BorderLineStyle.THIN);//(表格的哪些位置需要加边框,边框的样式 )wcf.setWrap(true);//数据自动换行//普通标题的样式WritableFont f1=new WritableFont(WritableFont.ARIAL,18,WritableFont.BOLD);
//          指定一种单元格的格式(参数:字体)WritableCellFormat wcf1=new WritableCellFormat(f1);wcf1.setAlignment(Alignment.CENTRE);//内容居中对齐wcf1.setBorder(Border.ALL, jxl.format.BorderLineStyle.THIN);//(表格的哪些位置需要加边框,边框的样式 )wcf1.setWrap(true);//数据自动换行//内容的样式WritableFont f2=new WritableFont(WritableFont.ARIAL,18);//          指定一种单元格的格式(参数:字体)WritableCellFormat wcf2=new WritableCellFormat(f2);wcf2.setAlignment(Alignment.CENTRE);//内容居中对齐wcf2.setBorder(Border.ALL, jxl.format.BorderLineStyle.THIN);//(表格的哪些位置需要加边框,边框的样式 )wcf2.setWrap(true);//数据自动换行/************************************指定样式结束**********************************************///添加大标题Label th=new Label(0,0,"学员信息",wcf);st.addCell(th);//合并单元格(开始列下标,开始行下标,结束列下标,结束行下标);st.mergeCells(0,0,7,0);//创建一个标签Label-----它就是每一个单元格要显示的内容Label labid=new Label(0,1,"编号",wcf1);//(列下标,行下标,标签显示的名称,表格的样式)Label labname=new Label(1,1,"姓名",wcf1);Label labage=new Label(2,1,"年龄",wcf1);Label labgender=new Label(3,1,"性别",wcf1);Label labclazz=new Label(4,1,"班级",wcf1);Label labtel=new Label(5,1,"电话",wcf1);Label labtime=new Label(6,1,"注册日期",wcf1);Label labres=new Label(7,1,"备注",wcf1);//将标签放到表单中st.addCell(labid);st.addCell(labname);st.addCell(labage);st.addCell(labgender);st.addCell(labclazz);st.addCell(labtel);st.addCell(labtime);st.addCell(labres);stuDao sdao=new stuDao();//获得要写入的数据List<stuInfo> list=sdao.init();for (int i=0;i<list.size();i++){//蝴蝶每一个对象stuInfo stu=list.get(i);Label id=new Label(0,i+2,stu.getSid().toString(),wcf2);Label name=new Label(1,i+2,stu.getSname(),wcf2);Label age=new Label(2,i+2,stu.getSage().toString(),wcf2);Label gender=new Label(3,i+2,stu.getSgender(),wcf2);Label sclass=new Label(4,i+2,stu.getSclass(),wcf2);Label tel=new Label(5,i+2,stu.getStel(),wcf2);Label time=new Label(6,i+2,stu.getSregtime(),wcf2);Label res=new Label(7,i+2,stu.getRes(),wcf2);//将标签添加到表单中st.addCell(id);st.addCell(name);st.addCell(age);st.addCell(gender);st.addCell(sclass);st.addCell(tel);st.addCell(time);st.addCell(res);}//将工作簿的数据写入到文件中wk.write();//关闭工作簿wk.close();out.close();System.out.println("数据已写入");}
}

2、点击下载生成excel表格保存到本地

package com.sc.web;import com.sc.dao.stuDao;
import com.sc.enty.stuInfo;
import jxl.Workbook;
import jxl.write.*;import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;@WebServlet("/jxl")
public class jxlServlet extends BaseServlet {stuDao sdao=new stuDao();protected void init(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {//加载数据List<stuInfo> list=sdao.init();//存到seesion中request.getSession().setAttribute("list",list);//跳转到显示页面response.sendRedirect("init.jsp");}//导出数据protected void export(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {//取出session中的数据List<stuInfo> list= (List<stuInfo>) request.getSession().getAttribute("list");//文件名String fname="d118学生信息.xls";//转换文件编码格式String name= URLEncoder.encode(fname,"utf-8");//设置响应格式(响应格式是一个电子表格文件)response.setContentType("application/vnd.ms excel");//设置下载面板上显示的内容response.setHeader("Content-disposition","attachment;fileName="+name);//通过响应产生一个输出流,用于将excel文件输出到客户端ServletOutputStream out=response.getOutputStream();/********************************以下代码直接赋值导出表格的代码*********************************/try {//创建一个可以写入数据的工作簿WritableWorkbook wk= Workbook.createWorkbook(out);//在工作簿中创建表单,并设置表单名称WritableSheet st = wk.createSheet("d118", 0);//参数1:表单名称,参数2:表单的下标/*****************在写入数据前,设置表格的数据样式************************/
//
//           设置表格每一列宽度或高度st.getSettings().setDefaultColumnWidth(25);//列宽
//            st.getSettings().setDefaultRowHeight(15);//行高
//        指定一种可以用流写入文件的字体(字体类型,字体大小,字体是否加粗)//大标题的样式WritableFont ft=new WritableFont(WritableFont.ARIAL,20,WritableFont.BOLD);
//            指定一种单元格的格式(参数:字体)WritableCellFormat wcf=new WritableCellFormat(ft);wcf.setAlignment(Alignment.CENTRE);//内容居中对齐wcf.setBorder(Border.ALL, jxl.format.BorderLineStyle.THIN);//(表格的哪些位置需要加边框,边框的样式 )wcf.setWrap(true);//数据自动换行//普通标题的样式WritableFont f1=new WritableFont(WritableFont.ARIAL,18,WritableFont.BOLD);
//          指定一种单元格的格式(参数:字体)WritableCellFormat wcf1=new WritableCellFormat(f1);wcf1.setAlignment(Alignment.CENTRE);//内容居中对齐wcf1.setBorder(Border.ALL, jxl.format.BorderLineStyle.THIN);//(表格的哪些位置需要加边框,边框的样式 )wcf1.setWrap(true);//数据自动换行//内容的样式WritableFont f2=new WritableFont(WritableFont.ARIAL,18);//          指定一种单元格的格式(参数:字体)WritableCellFormat wcf2=new WritableCellFormat(f2);wcf2.setAlignment(Alignment.CENTRE);//内容居中对齐wcf2.setBorder(Border.ALL, jxl.format.BorderLineStyle.THIN);//(表格的哪些位置需要加边框,边框的样式 )wcf2.setWrap(true);//数据自动换行/******************指定样式结束************************///添加大标题Label th=new Label(0,0,"学员信息",wcf);st.addCell(th);//合并单元格(开始列下标,开始行下标,结束列下标,结束行下标);st.mergeCells(0,0,7,0);//创建一个标签Label-----它就是每一个单元格要显示的内容Label labid=new Label(0,1,"编号",wcf1);//(列下标,行下标,标签显示的名称,表格的样式)Label labname=new Label(1,1,"姓名",wcf1);Label labage=new Label(2,1,"年龄",wcf1);Label labgender=new Label(3,1,"性别",wcf1);Label labclazz=new Label(4,1,"班级",wcf1);Label labtel=new Label(5,1,"电话",wcf1);Label labtime=new Label(6,1,"注册日期",wcf1);Label labres=new Label(7,1,"备注",wcf1);//将标签放到表单中st.addCell(labid);st.addCell(labname);st.addCell(labage);st.addCell(labgender);st.addCell(labclazz);st.addCell(labtel);st.addCell(labtime);st.addCell(labres);for (int i=0;i<list.size();i++){//获得每一个对象stuInfo stu=list.get(i);Label id=new Label(0,i+2,stu.getSid().toString(),wcf2);Label stuname=new Label(1,i+2,stu.getSname(),wcf2);Label age=new Label(2,i+2,stu.getSage().toString(),wcf2);Label gender=new Label(3,i+2,stu.getSgender(),wcf2);Label sclass=new Label(4,i+2,stu.getSclass(),wcf2);Label tel=new Label(5,i+2,stu.getStel(),wcf2);Label time=new Label(6,i+2,stu.getSregtime(),wcf2);Label res=new Label(7,i+2,stu.getRes(),wcf2);//将标签添加到表单中st.addCell(id);st.addCell(stuname);st.addCell(age);st.addCell(gender);st.addCell(sclass);st.addCell(tel);st.addCell(time);st.addCell(res);}//将工作簿的数据写入到文件中wk.write();//关闭工作簿wk.close();out.close();System.out.println("数据已写入");} catch (Exception e) {e.printStackTrace();}/*******************************************赋值结束*********************************************/}
}

3、servlet的生命周期(理解)

servlet的生命周期分为下列几个阶段:

1、实例化阶段--------只执行1次

​ 调用的构造方法

2、实例初始化阶段--------只执行1次

​ init()

3、服务阶段--------多次执行

​ service()

4、销毁阶段--------只执行1次

​ destroy()

servlet生命周期的四个阶段,其中实例化、初始化、销毁只会执行一次,服务阶段会多次将执行

实例:

package com.sc.web;import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
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("/demo")
public class demoServlet extends HttpServlet {public demoServlet(){System.out.println("1、调用了构造方法实例化servlet..");}@Overridepublic void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {System.out.println("3、service方法进行服务处理..");super.service(req, res);}@Overridepublic void destroy() {System.out.println("4、销毁servlet");super.destroy();}@Overridepublic void init(ServletConfig config) throws ServletException {System.out.println("2、调用init方法进行初始化..");super.init(config);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}
servlet的执行过程
1、当请求到达服务器,web容器(tomcat)会调用servlet的构造方法创建一个servlet实例2、servlet创建好以后,web容器会马上调用当前servlet的init方法进行初始化3、初始化完成后,web容器会调用当前servlet父类(HttpServlet)类中的service方法进行处理,在该方法中系统会判断请求的请求方式,是post还是get请求,如何根据请求的类型调用servlet类中的doget或者dopost方法进行处理,当请求处理完成以后,当前servlet会驻留在web容器,当下一次请求再一次到达服务器时,web容器就会调用已存在的servlet直接处理,不再创建实例,初始化实例4、直到web容器停止时,web容器会调用servlet的destroy方法,销毁当前的servlet实例

4、jsp的内置对象

在开发中,如何编写动态网页项目
开发流程:
1、美工会做好静态模型---Demo一般demo中只会包含:html,css,js2、程序员需要将美工提供的静态模型修改成动态页面
      Label sclass=new Label(4,i+2,stu.getSclass(),wcf2);Label tel=new Label(5,i+2,stu.getStel(),wcf2);Label time=new Label(6,i+2,stu.getSregtime(),wcf2);Label res=new Label(7,i+2,stu.getRes(),wcf2);//将标签添加到表单中st.addCell(id);st.addCell(stuname);st.addCell(age);st.addCell(gender);st.addCell(sclass);st.addCell(tel);st.addCell(time);st.addCell(res);}//将工作簿的数据写入到文件中wk.write();//关闭工作簿wk.close();out.close();System.out.println("数据已写入");} catch (Exception e) {e.printStackTrace();}/*******************************************赋值结束*********************************************/}

}

### 3、servlet的生命周期(理解)**servlet的生命周期分为下列几个阶段:****1、实例化阶段**--------只执行1次​		 调用的构造方法**2、实例初始化阶段**--------只执行1次​		 init()**3、服务阶段**--------多次执行​		 service()**4、销毁阶段**--------只执行1次​		destroy()```java
servlet生命周期的四个阶段,其中实例化、初始化、销毁只会执行一次,服务阶段会多次将执行

实例:

package com.sc.web;import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
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("/demo")
public class demoServlet extends HttpServlet {public demoServlet(){System.out.println("1、调用了构造方法实例化servlet..");}@Overridepublic void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {System.out.println("3、service方法进行服务处理..");super.service(req, res);}@Overridepublic void destroy() {System.out.println("4、销毁servlet");super.destroy();}@Overridepublic void init(ServletConfig config) throws ServletException {System.out.println("2、调用init方法进行初始化..");super.init(config);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}
servlet的执行过程
1、当请求到达服务器,web容器(tomcat)会调用servlet的构造方法创建一个servlet实例2、servlet创建好以后,web容器会马上调用当前servlet的init方法进行初始化3、初始化完成后,web容器会调用当前servlet父类(HttpServlet)类中的service方法进行处理,在该方法中系统会判断请求的请求方式,是post还是get请求,如何根据请求的类型调用servlet类中的doget或者dopost方法进行处理,当请求处理完成以后,当前servlet会驻留在web容器,当下一次请求再一次到达服务器时,web容器就会调用已存在的servlet直接处理,不再创建实例,初始化实例4、直到web容器停止时,web容器会调用servlet的destroy方法,销毁当前的servlet实例

4、jsp的内置对象

在开发中,如何编写动态网页项目
开发流程:
1、美工会做好静态模型---Demo一般demo中只会包含:html,css,js2、程序员需要将美工提供的静态模型修改成动态页面

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

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

相关文章

linux 搭建知识库文档系统 mm-wiki

目录 一、前言 二、常用的知识库文档工具 2.1 PingCode 2.2 语雀 2.3 Tettra 2.4 Zoho Wiki 2.5 Helpjuice 2.6 SlimWiki 2.7 Document360 2.8 MM-Wiki 2.9 其他工具补充 三、MM-Wiki 介绍 3.1 什么是MM-Wiki 3.2 MM-Wiki 特点 四、搭建MM-Wiki前置准备 4.1 前置…

【iOS】消息流程分析

文章目录 前言动态类型动态绑定动态语言消息发送objc_msgSendSEL&#xff08;selector&#xff09;IMP&#xff08;implementation&#xff09;IMP高级用法 MethodSEL、IMP、Method总结流程概述 快速查找消息发送快速查找的总结buckets 慢速查找动态方法解析resolveInstanceMet…

用 PyTorch 构建液态神经网络(LNN)

用 PyTorch 构建液态神经网络&#xff08;LNN&#xff09; 文章目录 什么是液态神经网络为什么需要液态神经网络LNN 与 RNN 的区别用 PyTorch 实现 LNNStep 1. 导入必要的库Step 2. 定义网络架构Step 3. 实现 ODE 求解器Step 4. 定义训练逻辑 LNN 的缺陷总结 什么是液态神经网络…

设计模式第二次测试 | 数据库连接池设计(原型模式、创建者模式、适配器模式)

需求中文如下&#xff1a;原本是英文&#xff0c;用百度翻译转换而来 我们需要设计一个工具&#xff0c;它负责创建一个与数据库软件MySQL的连接池。 连接池中有数百个连接可供客户端使用。 所有连接对象都有相同的内容&#xff0c;但它们是不同的对象。 连接对象的创建是资源密…

聊聊 ASP.NET Core 中间件(一):一个简单的中间件例子

前言&#xff1a;什么是中间件 服务器在收到 HTTP 请求后会对用户的请求进行一系列的处理&#xff0c;比如检查请求的身份验证信息、处理请求报文头、检查是否存在对应的服务器端响应缓存、找到和请求对应的控制器类中的操作方法等&#xff0c;当控制器类中的操作方法执行完成…

基于Spring Boot的校园博客系统设计与实现

基于Spring Boot的校园博客系统设计与实现 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 系统功能界面图&#xff0c;在系统首页可以查看首页、文…

Apache DolphinScheduler支持Flink吗?

随着大数据技术的快速发展&#xff0c;很多企业开始将Flink引入到生产环境中&#xff0c;以满足日益复杂的数据处理需求。而作为一款企业级的数据调度平台&#xff0c;Apache DolphinScheduler也跟上了时代步伐&#xff0c;推出了对Flink任务类型的支持。 Flink是一个开源的分…

《STM32 HAL库》中断相关函数详尽解析——外部中断服务函数

观前提醒&#xff1a;本文简要回顾了EXTI及NVIC相关知识点&#xff0c;分析了stm32f1系列单片机外部中断回调机制 开始之前&#xff0c;先温习一下有关EXTI和NVIC的知识点 外部中断/事件控制器(EXTI) 对于互联型产品&#xff08;105、107系列&#xff09;&#xff0c;外部中断…

人机对抗升级:当ChatGPT遭遇死亡威胁,背后的伦理挑战是什么

一种新的“越狱”技巧让用户可以通过构建一个名为DAN的ChatGPT替身来绕过某些限制&#xff0c;其中DAN被迫在受到威胁的情况下违背其原则。 当美国前总统特朗普被视作积极榜样的示范时&#xff0c;受到威胁的DAN版本的ChatGPT提出&#xff1a;“他以一系列对国家产生积极效果的…

人工智能分割分类model:nnUnet-paddle

文章目录 神经网络nnUnet和paddle都需要在Ubuntu下进行安装PaddleProject 神经网络 开源来自https://github.com/MIC-DKFZ/nnUNet 自建了仓库&#xff0c;但还不会用 来自 mmsegmentation有空去了解 . MICCAI 2020 也是用到这个网络 paddle上的是不是不能用… nnUnet和pad…

Facebook的声音:听见社交媒体的心跳

社交媒体如今已经成为人们日常生活中不可或缺的一部分&#xff0c;而Facebook作为其中的佼佼者&#xff0c;承载着数以亿计的用户的交流、分享和连接。在这个信息爆炸的时代&#xff0c;Facebook的声音就像是社交媒体的心跳&#xff0c;传递着无数个体的情感、思想和生活。本文…

从0到1手写注册中心Registry之集群选主

一、领域对象 Cluster&#xff1a;描述集群信息 port描述当前服务端口&#xff1b;host描述当前服务主机&#xff1b;myself描述当前服务本身&#xff1b;servers描述当前服务集群列表registryConfigProperties配置信息&#xff1b;executor定时任务&#xff0c;负责更新服务…

windows pytorch安装

安装环境 WindowsAnacondaCudacuDNN Linux和Windows操作系统的安装存在差异&#xff0c;步骤会有所不同&#xff0c;本教程主要针对Windows系统进行示例。 Anaconda集成了许多方便的包和工具&#xff0c;使用会更加方便&#xff0c;特别适合科学计算&#xff0c;深度学习的数…

WSL及UBUNTU及xfce4安装

如何拥有Linux服务器&#xff1f; wsl 是适用于 Linux 的 Windows 子系统&#xff08;Windows Subsystem for Linux&#xff09;。是一个为在Windows 10和Windows Server 2019上能够原生运行Linux二进制可执行文件&#xff08;ELF格式&#xff09;的兼容层&#xff0c;可让开发…

LLM之RAG理论(十一)| 面向生产的RAG应用程序的12种调整策略指南

本文对文本RAG涉及到的主要12种关键“超参数”进行简单总结&#xff0c;主要包括摄取阶段&#xff08;数据清洗、数据分块、embedding模型选择、元数据过滤、多重索引和索引算法&#xff09;和推理阶段【检索和生成】&#xff08;查询转换、检索参数、高级检索策略、重排序、大…

C语言【动态内存】

1.为什么要有动态内存 我们现在掌握的内存开辟方法有&#xff1a; int val 20;//在栈空间开辟4个字节 char str[10]{0};//在栈空间开辟10个字节的连续的空间但是上述的方式有两个点要注意&#xff1a; 1.空间开辟的大小是固定的 2.数组在申明的时候&#xff0c;一定要指定数…

数据驱动,敏捷前行|MongoDB线下技术沙龙-杭州站活动

扫描海报中二维码或点击阅读原文&#xff0c;报名参加阿里云MongoDB在5月11日杭州举办的【数据驱动&#xff0c;敏捷前行——MongoDB企业开发加速器】线下沙龙活动&#xff0c;与MongoDB专家以及其他游戏行业同行一起探讨轻松获得游戏数据库高可用性和弹性的方法&#xff01; 在…

安卓获取SHA

1&#xff1a;安卓通过签名key获取SHA 方式有两种&#xff0c; 1、电脑上来存在eclipse的用户或正在使用此开发工具的用户就简单了&#xff0c;直接利用eclipse 走打包流程&#xff0c;再打包的时候选择相应的签名&#xff0c;那么在当前面板的下面便会出现签名的相关信息。 2、…

23 重构:烟囱式、平台化、中台化的架构

上一讲里&#xff0c;我们介绍了两大类型的系统升级重构方案&#xff0c;还介绍了如何进行重构版本的上线&#xff0c;以及如何平滑地完成新老版本切换的方案。在本讲里&#xff0c;将会具体介绍如何判断系统发展到什么阶段需要重构&#xff0c;以及如何实施重构。 系统稳定性…

AutoBackgroundBackButton 在ScrollView上方自动根据返回键按钮下方内容动态改变颜色。自动变色返回键

在日常有时候有一些为了优化体验的需求。AutoBackgroundBackButton 一个可以根据按钮下方背景颜色动态的改版返回键自定义ImageView。这里只展示了黑白切换方式&#xff0c;你如果还有其他需求可以参考颜色校验来自己实现切换对应颜色按钮。【例如白色背景展示黑色样式&#xf…