JavaWeb核心四 Li.057

EL 表达式 EL (Expression Language): 表达式语言. 在JSP 2.0规范中加入的内容, 也是Servlet规范的一部分. 作用: 在JSP页面中获取数据. 让我们的JSP脱离java代码块和JSP表达式 <%--请求域中添加username数据--%> <% request.setAttribute("username","zhangsan"); %> <%--获取请求域的username 3种方式--%> <%--Java代码块--%> <% out.println(request.getAttribute("username")); %> <br/> <%--JSP表达式获取--%> <%= request.getAttribute("username")%> <br/> <%--EL表达式获取--%> ${username} EL 表达式获取数据类型 获取基本数据类型的数据 获取自定义对象类型的数据 获取数组类型的数据 获取List集合类型的数据 获取Map集合类型的数据 <%@ page import="com.lizicai.bean.Student" %> <%@ page import="java.util.ArrayList" %> <%@ page import="java.util.HashMap" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% pageContext.setAttribute("num",10); %> 基本数据类型 ${num} <br/> <% Student stu = new Student("李明", 23); pageContext.setAttribute("stu",stu); %> 自定义对象: ${stu} <br/> ${stu.name} ${stu.age} <br/> <% String[] arr = {"Haha", "go"}; pageContext.setAttribute("arr",arr); %> 数组: ${arr} <br/> ${arr[0]} ${arr[1]} ${arr[2]} <br/> <% ArrayList<String> list = new ArrayList<>(); list.add("aaa"); list.add("bbb"); pageContext.setAttribute( "list",list); %> List集合 ${list} ${list[0]} <br/> <% HashMap<String, Student> map = new HashMap<>(); map.put("s01",new Student("李明",20)); map.put("s02",new Student("张三",20)); pageContext.setAttribute( "map",map); %> Map 集合: ${map} <br/> 第一个学生 ${map.s01} <br> 第一个学生的姓名 ${map.s01.name} <br> </body> </html> EL 表达式注意事项 EL 表达式没有空指针异常 EL 表达式没有索引越界异常 EL 表达式没有字符串的拼接 <% Student s = null; String [] arr2 = {"Hello", "World"}; pageContext.setAttribute( "s",s); pageContext.setAttribute( "arr2",arr2); %> ${s} ${arr2[10]} ${arr2[0]}+${arr2[1]} EL 表达式运算符 关系运算符 关系运算符 作用 示例 结果 ==或eq 等于 略 略 !=或ne 不等于 略 略 <或lt 小于 略 略 >或gt 大于 略 略 <=或le 小于等于 略 略 >=或ge 大于等于 略 略 逻辑运算符 运算符 作用 示例 结果 &&或and 并且 略 略 ||或or 或者 略 略 !或not 取反 略 略 其他运算符 运算符 作用 empty 1判断对象是否为null.2判断字符串是否为空字符串.3判断窗口元素是否为0 条件?表达式1:表达式2 三元运算符 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>EL 表达式运算符</title> </head> <body> <% String ss = null; String ss2 = ""; int[] arr = {}; %> ${empty ss} <br/> ${empty ss2} <br/> ${empty arr} <br/> <% pageContext.setAttribute("gender", "man"); %> <input type="radio" name="gender" value="man" ${gender == "man" ? "checked" : ""}> 男 <input type="radio" name="gender" value="woman" ${gender == "woman" ? "checked" : ""}> 女 </body> </html> EL 表达式使用细节 EL 表达式能够获取四大域对象的数据, 根据名称从小到大在域对象中查找. 还可以获取JSP其他八个隐式对象, 并调用对象中的方法. <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <% pageContext.setAttribute("username", "zhangsan1"); request.setAttribute("username", "zhangsan2"); session.setAttribute("username", "zhangsan3"); application.setAttribute("username", "zhangsan4"); %> ${username} <br> <%= request.getContextPath() %> ${pageContext.request.contextPath} </body> </html> EL 表达式隐式对象 隐式对象名称 对应JSP隐式对象 说明 pageContext pageContext 功能完全相同 applicationScope 没有 操作应用域对象数据 sessionScope 没有 操作会话域对象数据 requestScop 没有 操作请求域对象数据 pageScope 没有 操作页面域对象数据 header 没有 操作请求头数据 headerValues 没有 获取请求头数据(多个值) param 没有 获取请求参数数据 paramValues 没有 获取请求参数数据(多个值) initParam 没有 获取全局配置参数数据 cookie 没有 获取Cookie 对象 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <%-- pageContext 对象, 可以获取其他3个域对象和JSP中八个隐式对象--%> ${pageContext.request.contextPath} <br/> <%--applicationScope sessionScope requestScop pageScope--%> <% request.setAttribute("username", "zhangsan1"); %> <% pageContext.setAttribute("username", "zhangsan2"); %> ${username} <br/> ${requestScope.username} <br/> ${pageScope.username} <br/> <%--header headerValues 获取的数组--%> ${header["connection"]} <br> ${headerValues["connection"][0]} <br> <%--param paramValues 获取请求参数--%> ${param.username} <br/> ${paramValues.hobby[0]} <br/> ${paramValues.hobby[1]} <br/> <%--initParam 获取全局配置参数--%> ${initParam.pname} <br> <%--cookie--%> ${cookie} <br> ${cookie.JSESSIONID} <br> <%-- 获取集合元素--%> ${cookie.JSESSIONID.name} <br> <%-- 获取cookie对象的名称 --%> ${cookie.JSESSIONID.value} <br> <%-- 获取cookie对象的数据值 --%> </body> </html> JSTL 介绍 JSTL (Java Servler Pages Standarded Tag Library): JSP标准标签库 主要提供给开发人员一个标准通用的标签库 开发人员可以利用这些标签取代JSP页面上的Java代码, 从而提高程序的可读性, 降低程序的维护难度. 组成 作用 说明 core 核心标签库 通用的逻辑处理 fmt 国际化 不同地域显示不同语言 functions EL函数 EL表达式可以使用的方法 sql 操作数据库 了解 xml 操作XML 了解 JSTL 核心标签库 标签名称 功能分类 属性 作用 <标签名:if> 流程控制 核心标签库 用于条件判断 <标签名:choose> ifelseif流程控制 核心标签库 用于多条件判断 <标签名:when> ifelseif流程控制 核心标签库 用于多条件判断 <标签名:otherwise> ifelseif流程控制 核心标签库 用于多条件判断 <标签名:forEach> 迭代遍历 核心标签库 用于循环遍历 http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/解压lib的包导入tomcatlib中 ...

October 13, 2021&nbsp;·&nbsp;7 分钟&nbsp;·&nbsp;Lizicai

JavaWeb核心三 Li.056

Cookie 属性 属性名 作用 是否重要 name Cookie的名称 必须属性 value Cookie的值(不支持中文) 必须属性 path Cookie的路径 重要 domain Cookie的域名 重要 maxAge Cookie的存活时间 重要 version Cookie的版本号 不重要 comment Cookie的描述 不重要 Cookie 方法 方法名 作用 Cookie(String.name,String.Value) 构造方法创建对象 属性对应的set和get就去 赋值和获取值 Cooke 添加和获取 添加 HttpServletResponse 返回值 方法名 说明 void addCookie(Cookie.cookie) 向客户端添加Cookie 获取 HttpServletRequest 返回值 方法名 说明 Cookie[] getCookies() 获取所有的Cookie Cookie 细节 数量限制 每个网站最多只能有20个Cookie, 且大小不能超过4KB. 所有网站的Cookie总数不能超过300个 名称限制 Cookie的名称只能包含ASCCI码表中字母,数字字符. 不能包含逗号,分号,空格, 不能以$开头 Cookie的值不支持中文 存活时间限制setMaxAge()方法接收数字 负整数: 当前会放有效, 浏览器关闭则清除 0: 立即清除 正整数: 以秒为单位设置存活时间 访问路径限制 默认路径: 取自第1次访问的资源路径前缀. 只要以这个路径开头就能访问到 设置路径: setPath()方法设置指定路径 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; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; @WebServlet ( value = "/demo1Cookie") public class Demo1Cookie extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=UTF-8"); PrintWriter pw = resp.getWriter(); pw.write("欢迎访问本网站, 你的最后访问时间为:"); Cookie cookie = new Cookie("time", System.currentTimeMillis()+""); cookie.setMaxAge(10); resp.addCookie(cookie); Cookie[] arr = req.getCookies(); for(Cookie c : arr){ if("time".equals(c.getName())){ String value = c.getValue(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); pw.write(sdf.format(new Date(Long.parseLong(value)))); } } } } HttpSession 介绍 HttpSession: 服务器端会话管理技术 本质也采用客户端会话管理技术 只不过在客户保存一个特殊标识, 而共享的数据保存到了服务端的内存对象中. 第次请求时, 会将特殊标识带到服务器端, 根据这个标识来找到对应的内存空间, 从而实现数据共享. 是Servlet规范中四大域对象之一的会话域对象 作用: 可以实现数据共享 域对象 功能 作用 ServletContext 应用域 在整个应用之间实现共享数据 ServletRequest 请求域 在当前的请求或请求转发之间实现数据共享 HttpSession 会话域 在当前会话范围之间实现数据共享 HttpSession 常用方法 返回值 方法名 说明 void setAttribute(String.name,Object.value) 设置共享数据 Object getAttribute(String.name) 获取共享数据 void removeAttribute(String.name) 移除共享数据 String getId() 获取唯一标识名称 void involidate() 让session立即失效 HttpSession 获取 返回值 方法名 说明 HttpSession getSession() 获取HttpSession对象 HttpSession getSession(boolean.create) 获取HttpSession,未获取到是否自动创建 import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; @WebServlet( value = "/demo1Session") public class Demo1Session extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username"); HttpSession session = req.getSession(); System.out.println(session); System.out.println(session.getId()); session.setAttribute("username",username); } } import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; @WebServlet( value = "/demo2Session") public class Demo2Session extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession(); System.out.println(session); System.out.println(session.getId()); Object username = session.getAttribute("username"); resp.getWriter().write(username+""); } } 禁用Cookie 就获取不到了 可以使用手动拼接链接 resp.getWriter().write("<a href='"+resp.encodeURL("http://localhost:8080/demo3Session")+"'>go to servlet</a>"); HttpSession 的细节 浏览器禁用Cookie, 禁止访问 ...

October 8, 2021&nbsp;·&nbsp;6 分钟&nbsp;·&nbsp;Lizicai

JavaWeb核心二 Li.055

请求对象 返回值 方法名 说明 String getContextPath() 获取虚拟目录名称 String getServletPath() 获取Servlet映射路径 String getRemoteAddr() 获取访问者ip地址 String getQueryString() 获取请求的消息数据 String getRequestURI() 获取统一资源标识符 String getRequestURL() 获取统一资源定位符 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(name = "demo1GetPath", value = "/demo1GetPath") public class Demo1GetPath extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String contextPath = req.getContextPath(); System.out.println(contextPath); String servletPath = req.getServletPath(); System.out.println(servletPath); String remoteAddr = req.getRemoteAddr(); System.out.println(remoteAddr); String queryString = req.getQueryString(); System.out.println(queryString); String requestURI = req.getRequestURI(); System.out.println(requestURI); StringBuffer requestURL = req.getRequestURL(); System.out.println(requestURL); } } 请求头信息 返回值 方法名 说明 String getHeader(String.name) 根据请求头名获取一个值 Enumeration<String> getHeaders(String.name) 根据请求头名获取多个值 Enumeration<String> getHeaderNames() 获取所有请求头名称 import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Enumeration; @WebServlet(name = "demo2GetPath", value = "/demo2GetPath") public class Demo2GetPath extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String host = req.getHeader("Host"); System.out.println(host); Enumeration<String> headers = req.getHeaders("Accept-Encoding"); System.out.println("----------------------------------------------"); while (headers.hasMoreElements()){ String header = headers.nextElement(); System.out.println(header); } Enumeration<String> headerNames = req.getHeaderNames(); System.out.println("================================"); while (headerNames.hasMoreElements()){ String headerName = headerNames.nextElement(); System.out.println(headerName+"...."+ req.getHeader(headerName)); } } } 获取请求参数信息 返回值 方法名 说明 String getParameter(String.name) 根据名称获取数据 String[] getParameterValues(String.name) 根据名称获取所有数据 Enumeration<String> getParameterNames() 获取所有名称 Map<String,String[]> getParameterMap() 获取所有参数的键值对 import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Enumeration; import java.util.Map; @WebServlet(name = "Demo3GetRequestParamter", value = "/demo3GetRequestParamter") public class Demo3GetRequestParamter extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name = req.getParameter("username"); String password = req.getParameter("password"); System.out.println(name+"..."+password); System.out.println("----------------"); String[] hobbies = req.getParameterValues("hobby"); for(String hobby:hobbies){ System.out.println(hobby); } System.out.println("===================="); Enumeration<String> parameterNames = req.getParameterNames(); while (parameterNames.hasMoreElements()){ String pname = parameterNames.nextElement(); System.out.println(pname); } System.out.println("==================="); Map<String, String[]> parameterMap = req.getParameterMap(); for(Map.Entry<String,String[]> parameter : parameterMap.entrySet()){ System.out.print(parameter.getKey()); for(String s:parameter.getValue()){ System.out.print(","+s); } System.out.println(); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req,resp); } } 获取请求参数并封装对象 手动封装方式 反射封装方式 工具类封装方式 手动封装的方式 ...

September 29, 2021&nbsp;·&nbsp;10 分钟&nbsp;·&nbsp;Lizicai

JavaWeb核心一 Li.054

1. IDEA 创建 JavaWeb 项目 1.1 选择JavaEE 项目 1.2 Project tempate中选择 Web Application 1.3 一路创建 1.4 在Edit Configurations 设置tomcat, 下面为brew 安装的tomcat地址 /usr/local/Cellar/tomcat@9/9.0.53/libexec 1.5 设置On update action: update resources, On frame deactivation: update resources 1.6 设置第二栏Deployment: Application text: /web_demo 1.7 启动tomcat 即可自动在浏览器上预览 2. 打包JavaWeb 项目 2.1 在本地wepapp文件夹内, 使用jar -cvf myweb.war .打包 jar -cvf myweb.war . 2.2 上传到tomcat服务器中的webapps中, 重启tomcat即可看到发布结果 scp myweb.war webserver:tomcat9.0/webapps/ ./shutdown.sh ./startup.sh 3. 更改Tomcat 端口 conf中server.xml 8080更改为80端口 4. 在server.xml中添加其它目录做为tomcat项目 **在Host中间添加 <Context path="/myweb" docBase="/Users/lizicai/IdeaProjects/web_demo/src/main/webapp" /> 访问ip:8080/myweb 即可 ...

September 26, 2021&nbsp;·&nbsp;7 分钟&nbsp;·&nbsp;Lizicai

CSS基础 Li.052

CSS (Cascading Style Sheets) 层叠样式表 选择器: 选择HTML元素的方式, 可以使用标签名, class属性值, id值等多种方式 样式声明: 用于给HTML元素设置具体的样式. 格式是属性名: 属性值. 选择器{ 属性名: 属性值; 属性名: 属性值; 属性名: 属性值; } h1{ color: red; font-size: 5px; } 入门案例 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>入门案例</title> <style> h1{ font-size: 100px; color: red; } </style> </head> <body> <h1 >今天开始爱学习!</h1> </body> </html> CSS 的引用方式 * 内联样式 在标签中通过style属性来控制样式, 只能影响当前这一行 格式 <标签 style="属性名:属性值; 属性名:属性值;">内容</标签> * 内部样式 在<head>标签中通过<style>标签来控制样式, 只能影响当前文件 格式<head><style> 选择器{ 属性名:属性值; }</style></head> * 外部样式 在<head>标签中通过<link>标签来引入独立css文件, 可以影响不同的文件 格式<link rel="stylesheet" href="sample.css"> 相对路径css文件或网络css文件都可 CSS 的注释 /* 注释内容 */ CSS 选择器分类 基本选择器 元素选择器 标签名 根据标签名匹配元素 div{} 类选择器 . 根据class属性值匹配元素 .center{} id选择器 # 根据id属性值匹配元素 #username{} CSS 选择器分类 属性选择器 属性选择器 [] 根据指定属性匹配元素 [type]{}[type=text]{} CSS 选择器分类 伪类选择器 标签名:link 未访问的状态 a:link{} 标签名:visited 已访问的状态 a:visited{} 标签名:hover 鼠标悬浮的状态 a:hover{} 标签名:active 已选中的状态 a:active{} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>CSS伪类选择器</title> <style> a:link{ color: black; text-decoration: none; } a:visited{ color: blue; text-decoration: none; } a:hover{ color: red; text-decoration: none; font-weight: bold; } a:active{ color: yellow; } </style> </head> <body> <a href="01-入门案例.html" >入门案例</a> </body> </html> CSS 选择器分类 组合选择器 后代选择器 空格 使用空格结合多个选择器,基于第一个选择器,匹配第二2选择的所有元素 .center li{} 分组选择器 , 可能同时匹配多个元素 div,span,p{} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>CSS组合选择器(后台选择器和分组选择器)</title> <style> .center li{ color: red; } div,span,p{ color: green; font-size: 30px; } </style> </head> <body> <div>asf</div> <a><span>asdf</span></a> <p>asdf</p> <ol class="center" > <li>列表</li> <li>列表</li> </ol> </body> </html> 边框样式 border border 设置所有边框 border-top 设置上边框 border-left 设置左边框 border-right 设置右边框 border-bottom 设置下边框 border-radius 设置边框弧度 solid 实线 double 双实线 dotted 圆点 dashed 虚线 文本样式 color 文本颜色 颜色单词(red),RGB(#000000) font-family 字体 微信雅黑,宋体 font-size 字体大小 像素点20px text-decoration 文字下划线 none无underline下划线overline上划线line-through text-align 水平对齐方式 left居左right居右center居中 line-height 行间距 像素点20px vertical-algn 垂直对齐方式 top居上bottom居下middle居中(还可百分比调节) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>新闻头条</title> <link rel="stylesheet" href="news.css"> </head> <body> <div class="divTop"> <a href="#" class="divTopA">登录&nbsp;&nbsp;</a> <a href="#" class="divTopA">注册&nbsp;&nbsp;</a> <a href="#" class="divTopA">更多&nbsp;&nbsp;&nbsp;</a> </div> <div class="divNav"> <img src="background.png" width="100px" height="40px"> <a href="#">首页</a><span>&nbsp;/</span> <a href="#">科技</a><span>&nbsp;/</span> <font color="gray">正文</font> </div > <div> <hr/> </div> <div class="divContend"> <div class="divLeft"> <div> <a href="#"><img src="test.png"><span>&nbsp;评论</span></a> </div> <hr/> <div> <a href="#"><img src="test.png"><span>&nbsp;评论</span></a> </div> <div> <a href="#"><img src="test.png"><span>&nbsp;评论</span></a> </div> <div> <a href="#"><img src="test.png"><span>&nbsp;评论</span></a> </div> </div> <div class="divCenter"> <p>弹性布局flex是一个几年前的CSS属性了,说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :) 之前网上流行的各种XX布局,什么postion: absolute+margin,float+padding,各种都可以使用flex来取代之。 早两年在使用的时候,还是会担心有兼容性问题的,某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。 好在现在已经是2018年了,不必再担心那些老旧的设备,希望这篇文章能帮你加深对flex的认识。 </p> <p> 首先,flex被称为一个弹性盒模型,也有称弹性布局的。 总之,盒子也好、布局也罢,我们总是需要有一个容器Container的: </p> <ol> <li>首先,flex被称为一个弹性盒模型,也有称弹性布局的。kskdfjksjdfk</li> <li>总之,盒子也好、布局也罢,我们总是需要有一个容器Container的</li> </ol> <img src="background.png" width="100%"> <p><strong>加粗1</strong>弹性布局flex是一个几年前的CSS属性了,说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :) 之前网上流行的各种XX布局,什么postion: absolute+margin,float+padding,各种都可以使用flex来取代之。 早两年在使用的时候,还是会担心有兼容性问题的,某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。 好在现在已经是2018年了,不必再担心那些老旧的设备,希望这篇文章能帮你加深对flex的认识。 </p> <p><strong>加粗2</strong>弹性布局flex是一个几年前的CSS属性了,说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :) 之前网上流行的各种XX布局,什么postion: absolute+margin,float+padding,各种都可以使用flex来取代之。 早两年在使用的时候,还是会担心有兼容性问题的,某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。 好在现在已经是2018年了,不必再担心那些老旧的设备,希望这篇文章能帮你加深对flex的认识。 </p> <img src="background.png" width="100%"> <p> 之前网上流行的各种XX布局,什么postion: absolute+margin,float+padding,各种都可以使用flex来取代之。 早两年在使用的时候,还是会担心有兼容性问题的,某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。 好在现在已经是2018年了,不必再担心那些老旧的设备,希望这篇文章能帮你加深对flex的认识。 </p> </div > <div class="divRight"> <img src="test.png" width="100%"> <img src="background.png" width="100%"> <img src="test.png" width="100%"> <img src="background.png" width="100%"> </div> </div> <div class="divFooter"> <a href="#">内容</a> <a href="#">内容</a> <a href="#">内容</a> <a href="#">内容</a> </div> </body> </html> .divTop{ background: black; height: 50px; text-align: right; font-size: 25px; } .divTop a{ color: white; } .divNav{ height: 50px; } a{ color: black; text-decoration: none; font-size: 25px; } a:hover{ color: red; } .divContend{ float: left; } .divLeft{ width: 20%; float: left; text-align: center; vertical-align: 50%; } .divLeft img{ width: 38px; height: 38px; } .divLeft span{ vertical-align: 50%; } .divCenter{ width: 60%; float: left; } .divRight{ width: 20%; float: left; } .divFooter{ clear: both; background: blue; text-align: center; } .divFooter a{ color: white; } .divFooter a:hover{ color: red; } 表格标签 table 表格标签 width-宽度height-高度border-边框align-对齐方式 tr 行标签 align-对齐方式 td 单元格标签(列标签) rowspan-合并行colspan-合并列 th 表头标签(加粗和居中) thread 表头语文标签 tbody 课外书语义标签 tfoot 表脚语义标签 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>表格标签演示</title> </head> <body> <table width="500px" border="1px"> <thead> <tr> <th>姓名</th> <th>性别</th> <th>年龄</th> <th>数学</th> <th>语文</th> </tr> </thead> <tbody> <tr align="center"> <td>张三</td> <td rowspan="2">男</td> <td>20</td> <td colspan="2">90</td> <!-- <td>90</td>--> </tr> <tr align="center"> <td>李四</td> <!-- <td>男</td>--> <td>21</td> <td>95</td> <td>90</td> </tr> </tbody> <tfoot> <tr align="center"> <td>总分:</td> <td colspan="4">365</td> </tr> </tfoot> </table> </body> </html> CSS 样式控制 background-repeat 控制背景重复 no-repeat不重复,repeat-x水平重复,repeat-y垂直重复,repeat水平和垂直重复 outline 控制轮廓 double双实线,dotted圆点,dashed虚线,none无 display 控制元素 inline肉联元素(无换行,无长宽),block块级元素(有换行),inline-block肉联元素(有长宽),none隐藏元素 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>背景 轮廓 元素控制</title> <style> body{ background: url("bg.png"); /*background-repeat: no-repeat;*/ /*background-repeat: repeat-x;*/ /*background-repeat: repeat-y;*/ background-repeat: repeat; } input{ /*outline: none;*/ /*outline: none;*/ outline: double; } div{ /*display: none;*/ /*display: inline;*/ display: inline-block; width: 50px; } </style> </head> <body> 姓名: <input type="text"> <br> <div>春香</div> <div>夏香</div> <div>秋香</div> <div>冬香</div> </body> </html> CSS 灵魂, 盒子模型 盒子模型是通过设置边框和元素内容的边距, 从而实现布局的方式. 分为内边距和外边距两种方式 如果想实现布局, 可以采用设置内边距或外边距来实现. ...

September 24, 2021&nbsp;·&nbsp;5 分钟&nbsp;·&nbsp;Lizicai

HTML基础 Li.051

html 标签简单介绍 # html5文件声明 <!DOCTYPE html> # 根标签 <html lang="en"> # 头 <head> # 字符集 <meta charset="UTF-8"> # 文档标题, 标签页标题 <title>01入门案例</title> </head> # 身体, 所有文档内容 <body> <h1 align="center">这是我的第一个HTML入门案例</h1> </body> </html> HTML 注释 标签 注释 <!-- 注释 --> 标签 开始和结束标签 <h1></h1> 自闭合标签<br/> <hr/> 标签的嵌套 正确嵌套 <h1><u>sefe</u></h1> 错误嵌套 <h1><u>sefe</h1></u> 块级元素和行内元素 块级元素: 在页面中以块的形式展现, 自己独占一行, 后面内容会自动换行<p><hr><div> 行内元素: 在页面中以行的形式展现, 不会换行<b><i><u><span> div和span <div>: 是一个通用的内容容器, 没有特殊语义. 一般用来对其它元素进行分组, 用于样式化相关的需求 <span>: 是一个通用的行内容器, 没有特殊语义. 一般用来纺织元素以达到某种样式. <div>和<span>标签核心作用是布局页面 HTML 的属性 什么是属性 属性可以提供一些额外的信息, 这些信息不会显示在内容中, 但可以改变标签的形式或提供的数据使用 定义格式 属性名=属性值 属性的规范 同一个标签中属性的名称必须唯一 不区分大小写, 推荐小写 属性值可以使用单引号或双引号, 推荐双引号 常用的属性 class 定义元素的类名, 用户选择或访问特定的元素 id 定义元素的唯一标识, 在整个文档中必须是唯一的 name 定义元素的名称, 一般用于表单数据提交到服务器 value 定义在元素内显示的默认值, 一般常用于表单标签中 style 定义元素的css样式 HTML 的特殊字符 特殊字符 在html中, 像< > " ' 空格 & 都是特殊字符, 它们是语法本身的一部分 字符表示 < &lt; > &gt; " &quot; ' &apos; & &amp; 空格 &nbsp; HTML 练习一 样式演示 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>样式演示</title> <style> div{ border: 1px solid red; width: 60%; height: 500px; /* 边框外边距 */ margin: auto; } </style> </head> <body> <div>第一个div</div> </body> </html> 文本标签 p 表示文件的一个段落 h 表示文档标题,<h1>-<h6>,呈现六个不同级别的标题,h1最高h6最低 hr 表示段落级元素之间的主题转换,一般显示为水平线 ul 表示一个无序列表,可含多个元素,无编号显示 ol 表示一个有序列表,通过渲染为带编号的列表 li 表示列表里的条目 em 表示文本着重,一般用斜体显示 i 表示文本斜体 strong 表示文本重要,一般用粗体显示 b 表示加粗文本 font 表示字体,可以设置样式(已过时) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>新闻标题案例</title> <style> .divCenter{ width: 60%; margin: auto; } .headCenter{ text-align: center; } p{ font-size: 18px; } </style> </head> <body> <div class="divCenter"> <h1 class="headCenter" >这是一个标题</h1> </div> <div class="divCenter"> <em><font size="2" color="gray">作者: 李小明 2021年10月1日</font></em> <hr/> </div> <div class="divCenter"> <h3>弹性布局flex是一个几年前的CSS属性了</h3> </div> <div class="divCenter"> <p>弹性布局flex是一个几年前的CSS属性了,说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :) 之前网上流行的各种XX布局,什么postion: absolute+margin,float+padding,各种都可以使用flex来取代之。 早两年在使用的时候,还是会担心有兼容性问题的,某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。 </p> <p> 首先,flex被称为一个弹性盒模型,也有称弹性布局的。 总之,盒子也好、布局也罢,我们总是需要有一个容器Container的: </p> <ol> <li>首先,flex被称为一个弹性盒模型,也有称弹性布局的。kskdfjksjdfk</li> <li>总之,盒子也好、布局也罢,我们总是需要有一个容器Container的</li> </ol> <p><strong>加粗1</strong>弹性布局flex是一个几年前的CSS属性了,说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :) 之前网上流行的各种XX布局,什么postion: absolute+margin,float+padding,各种都可以使用flex来取代之。 早两年在使用的时候,还是会担心有兼容性问题的,某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。 </p> <p><strong>加粗2</strong>弹性布局flex是一个几年前的CSS属性了,说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :) 之前网上流行的各种XX布局,什么postion: absolute+margin,float+padding,各种都可以使用flex来取代之。 早两年在使用的时候,还是会担心有兼容性问题的,某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。 </p> </div> </body> </html> 案例二头条页 div 样式布局 .left{ width: 20%; float: left; } .center{ width: 59%; float: left; } .right{ width: 20%; float: left; } <div class="left">left</div> <div class="center">center</div> <div class="right">right</div> float 浮动(left right none) clear清除浮动(both) text-align(left right center) background背景色 图片标签 img 可以显示图片,本地或网络 src 必需,图片地址 title 鼠标悬停(hover)时显示文本 alt 图形不显示时的替换文本 height 图像高度 width 图像宽度 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>图片样式演示</title> </head> <body> <img src="login.png" title="说明" alt="图片不存在" width="1000" height="30px"/> <img src="no.png" title="说明" alt="图片不存在" width="1000" height="30px"/> </body> </html> 超链接标签 a 表示超链接 href 表示超链接指向的URL 本地或网络都可 targe 页面打开方式(_self当前页_blank新标签页) a:hover 鼠标悬停样式 text-decoration:none; 去掉下划线 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>样式演示</title> <style> div{ /*border: 1px solid red;*/ } .left{ width: 20%; float: left; } .center{ width: 60%; float: left; } .right{ width: 20%; float: left; } .footer{ clear: both; text-align: center; background: blue; } a{ color: white; text-decoration: none; } </style> </head> <body> <div><img src="top.png" alt="top.png" width="100%"></div> <div><img src="navibar.png" alt="navibar.png" width="100%"> </div> <div> <div class="left"> <img src="left.png" width="100%"> </div> <div class="center"> <p>弹性布局flex是一个几年前的CSS属性了,说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :) 之前网上流行的各种XX布局,什么postion: absolute+margin,float+padding,各种都可以使用flex来取代之。 早两年在使用的时候,还是会担心有兼容性问题的,某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。 好在现在已经是2018年了,不必再担心那些老旧的设备,希望这篇文章能帮你加深对flex的认识。 </p> <p> 首先,flex被称为一个弹性盒模型,也有称弹性布局的。 总之,盒子也好、布局也罢,我们总是需要有一个容器Container的: </p> <ol> <li>首先,flex被称为一个弹性盒模型,也有称弹性布局的。kskdfjksjdfk</li> <li>总之,盒子也好、布局也罢,我们总是需要有一个容器Container的</li> </ol> <img src="center1.png" width="100%"> <p><strong>加粗1</strong>弹性布局flex是一个几年前的CSS属性了,说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :) 之前网上流行的各种XX布局,什么postion: absolute+margin,float+padding,各种都可以使用flex来取代之。 早两年在使用的时候,还是会担心有兼容性问题的,某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。 好在现在已经是2018年了,不必再担心那些老旧的设备,希望这篇文章能帮你加深对flex的认识。 </p> <p><strong>加粗2</strong>弹性布局flex是一个几年前的CSS属性了,说它解放了一部分生产力不为过。至少解放了不少CSS布局相关的面试题 :) 之前网上流行的各种XX布局,什么postion: absolute+margin,float+padding,各种都可以使用flex来取代之。 早两年在使用的时候,还是会担心有兼容性问题的,某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。 好在现在已经是2018年了,不必再担心那些老旧的设备,希望这篇文章能帮你加深对flex的认识。 </p> <img src="center2.png" width="100%"> <p> 之前网上流行的各种XX布局,什么postion: absolute+margin,float+padding,各种都可以使用flex来取代之。 早两年在使用的时候,还是会担心有兼容性问题的,某些手机在使用了auto-prefixer以后依然会出现不兼容的问题。 好在现在已经是2018年了,不必再担心那些老旧的设备,希望这篇文章能帮你加深对flex的认识。 </p> </div> <div class="right"> <img src="right.png" width="100%"> <img src="right.png" width="100%"> <img src="right.png" width="100%"> </div> </div> <div class="footer"> <a href="http://lizicai.com" target="_blank">李子菜</a> <a href="http://lizicai.com" target="_blank">李子菜</a> <a href="http://lizicai.com" target="_blank">李子菜</a> <a href="#" target="_blank">李子菜</a> </div> </body> </html> 案例三 注册 div样式布局, 背景图片 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>背景图片演示</title> <style> body{ background: url("Halcrow.jpg"); } </style> </head> <body> </body> </html> 表单标签 form 表单标签 action 用于提交数据的路径 method 用于提交数据的方式( get 和post ) (get 表单数据会显示在地址栏中, 不安全, 地址栏长度有限制) (post 表单数据不会显示在地址栏中, 数据封装在请求体中, 安全, 长度无限制) autocomplete 是否记录补全( on 和 off ) 表单项标签 lable 表单元素说明,配置表单项标签使用 for 属性值必须和表单项的id属性值一致 input 表单项标签,多种输入类型来接收用户数据 type 数据的类型 id 唯一标识 name 提交服务器的标识 value 默认数据值 placeholder 默认提示信息 required 是否必须有数据 button 按钮标签,不同的按钮有不同的作用 type 属性,按钮的功能(submit,reset,button) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>表单项标签演示</title> </head> <body> <form method="get" action="#" autocomplete="on"> <label for="username">用户名: </label> <input type="text" name="username" id="username" value="" placeholder="请输入用户名" required> <button type="submit">提交</button> <button type="reset">重置</button> <button type="button">普通按钮</button> </form> </body> </html> 表单项标签type属性值 text 普通文本框 password 密码框 email 邮箱框,简单验证 radio 单选框 选择必须有相同的name属性值, value属性设置实际提交的值, checked属性代表默认选中 checkbox 得选框 选项必须有相同的name属性值, value属性设置实际提交的值, checked属性代表默认选中 date 日期框 time 时间框 datetime-local 时间日期框 number 数字框 range 滚动条数值框,min最小值,max最大值,step步进值 search 可清除文本框 tel 电话框 url 网址框 file 文件上传框 hidden 隐藏域 value属性设置实际提交的值 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>表单标签type属性演示</title> </head> <body> <form method="get" action="#"> <label for="username">用户名:</label> <input type="text" name="username" id="username" placeholder="请输入用户名"> <br/> <label for="password">密码:</label> <input type="password" name="password" id="password" placeholder="请输入密码" > <br/> <label for="email">邮箱:</label> <input type="email" name="email" id="email" placeholder="请输入邮箱"> <br/> <label for="gender">性别:</label> <input type="radio" name="gender" value="male" id="gender">男 <input type="radio" name="gender" value="female">女 <input type="radio" name="gender" value="other" checked>保密 <br/> <label for="hobby">爱好:</label> <input type="checkbox" name="profession" value="music" id="hobby">音乐 <input type="checkbox" name="profession" value="game" >游戏 <br/> <label for="birthday">日期:</label> <input type="date" name="birthday" id="birthday" > <br/> <label for="time">时间:</label> <input type="time" name="time" id="time" > <br/> <label for="datetime">日期和时间:</label> <input type="datetime-local" name="datetime" id="datetime" > <br/> <label for="number">number:</label> <input type="number" name="number" id="number" > <br/> <label for="range">rang:</label> <input type="range" name="range" id="range" min="0" max="10" step="2"> <br/> <label for="search">search:</label> <input type="search" name="search" id="search" > <br/> <label for="tel">tel:</label> <input type="tel" name="tel" id="tel" > <br/> <label for="url">url:</label> <input type="url" name="url" id="url" > <br/> <label for="file">file:</label> <input type="file" name="file" id="file" > <br/> <input type="hidden" name="hidden" id="hidden" value="see"> <br/> <button name="submit" type="submit" >提交</button> <button name="重置" type="reset">重置</button> </form> </body> </html> 其他常用表单项标签 select 表示下拉列表标签 optgroup 不用接列表分组标签 label属性,设置分组名称 option 表示下拉列表项标签 textarea 表示文本域标签 rows属性代表行数,cols属性代表列数 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>其他常用表单项标签演示</title> </head> <body> <form method="get" action="#" autocomplete="off"> <label for="city">所在城市</label> <select name="city" id="city"> <option>请选择城市</option> <optgroup label="直辖市"> <option>北京</option> <option>上海</option> <option>深圳</option> </optgroup> <optgroup label="省会市"> <option>广州</option> <option>杭州</option> </optgroup> </select> <br/> 个人介绍: <textarea name="desc" rows="10" cols="20"> </textarea> <button name="submit" type="submit" >提交</button> <button name="重置" type="reset">重置</button> </form> </body> </html> 演示案例三 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>注册页面</title> <style> body{ background: url("background.png"); } .divForm{ background: white; width: 400px; margin: auto; text-align: center; } .divFormLeft{ background: white; width: 60%; margin: auto; text-align: left; } </style> </head> <body> <div> <img src="navibar.png" width=100%> </div> <div class="divForm"> <div class="divFormLeft"><a>注册详情</a></div> <hr/> <div> <form method="get" autocomplete="on" action="#"> <div class="divFormLeft"> <div > <label for="username">姓名:</label> <input type="text" name="username" id="username" placeholder="在此输入姓名"> <br/> </div> <div> <label for="password">密码:</label> <input type="password" name="password" id="password" placeholder="在此输入密码"> <br/> </div> <div> <label for="email">邮箱:</label> <input type="email" name="email" id="email" placeholder="在此输入邮箱"> <br/> </div> <div> <label for="tel">手机:</label> <input type="tel" name="tel" id="tel" placeholder="在此输入手机"> <br/> </div> </div> <hr/> <div class="divFormLeft"> <div > <label for="gender">性别:</label> <input type="radio" name="gender" id="gender" value="male">男&nbsp; <input type="radio" name="gender" value="femal" >女&nbsp; <br/> </div> <div> <label for="hobby">爱好:</label> <input type="checkbox" name="hobby" id="hobby" value="music">音乐&nbsp; <input type="checkbox" name="hobby" value="movie" >电影&nbsp; <input type="checkbox" name="hobby" value="game" >游戏&nbsp; <br/> </div> <div> <label for="birthday">出生日期:</label> <input type="date" name="birthday" id="birthday"> <br/> </div > <div> <label >所在城市: </label> <select id="city" name="city"> <option>请选择城市</option> <optgroup label="直辖市"> <option>北京</option> <option>上海</option> <option>深圳</option> </optgroup> <optgroup label="省会城市"> <option>杭州</option> <option>广州</option> <option>南京</option> </optgroup> </select> </div> </div> <hr/> <div> <label for="sign">个性签名:</label> <textarea name="sign" id="sign" rows="6" cols="30" placeholder="请写出你的与众不同"></textarea> <br/> </div> <div > <button type="submit">提交</button> <button type="reset">重置</button> </div> <hr/> </form> </div> </div> </body> </html>

September 22, 2021&nbsp;·&nbsp;5 分钟&nbsp;·&nbsp;Lizicai

Linux常用命令与shell语言 Li.050

user 用户相关命令 useradd username passwd username usermod -l usernewname username userdel usernewname # 强制删除用户usertest主目录和邮件池 userdel -rf usertest group 用户组相关命令 groupadd groupname # 查看用户所在的组 groups username # 更改组名 groupmod -n groupname groupnewname groupdel groupnewname 管理用户与组 # 往group1中添加用户test gpasswd -a test group1 # 删除group1中的test gpasswd -d test group1 # 查看组中有几个用户 cat /etc/group | grep groupname 时间 date date -d "2021-09-09 12:00:01" # 修改时间 date -s "2021-09-09 12:00:01" logname 显示登录用户名 su 切换用户 # 切换到root用户执行命令, 再切换回当前用户, 需要输入root密码 su -c ls root id 查看用户id 用户组id top 命令 实时监控进程 # 停止监控 q # 显示完整命令 top -c # 指定pid top -p 3550 PS # 当前正在运行 ps # 全部运行 ps -A # 查看更全的信息 ps -ef # 指定用户进程信息 ps -u username Kill # 杀掉进程 kill 999 # 彻底杀掉 kill -9 999 # 杀掉用户进程 kill -9 $(ps -ef | grep username) killall -u username shutdown # 关机 shutdown # 取消关机 shutdown -c # 立即关机 shutdown -h now # 警告 1分钟后关机 shutdown +1 "1分钟关机" # 警告 1分钟后重启 shutdown -r +1 "1分钟重启" who 当前登录系统的用户 who who -H timedatectl 设置时间 # 查看所有时区 timedatectl list-timezones # 设置野区 timedatectl set-timezone Asia/Shanghai # 禁用ntp timedatectl set-ntp false # 启用ntp timedatectl set-ntp true clear 清屏 command + L 同样能做到 clear ls ls # 显示文件夹(不隐藏的文件与文件夹详细信息) ls -l # 全部文件夹与文件(包含隐藏) ls -a ls -al pwd 打印目录 pwd cd 切换路径 Fasd 跳转比cd更快 ...

September 21, 2021&nbsp;·&nbsp;10 分钟&nbsp;·&nbsp;Lizicai

Java的反射 Li.049

反射 反射概述 Java的反射机制是在运行状态中, 对于任意一个类, 都能知道这个类的所有属性和方法 对于任意一个对象, 都能够调用它的任意一个方法和属性 这种动态获取信息以及动态调用对象的方法的功能称为Java语文的反射机制 想要解剖一个类, 必需先要获取到该类的字节码文件对象 而解剖使用的就是Class类中的方法, 所以先要获取到每一个字节码文件对应的Class类型的对象 反射的三种方式 Object烦的getClass()方法, 判断2个对象是否是同一个字节码文件 静态属性class, 锁对象(Person.class) Class类中静态方法forName(), 读取配置文件 import com.lizicai.bean.Person; public class Demo1_Reflect { public static void main(String[] args) throws ClassNotFoundException { Class clazz1 = Class.forName("com.lizicai.bean.Person"); Class clazz2 = Person.class; Person p = new Person(); Class clazz3 = p.getClass(); System.out.println(clazz1 == clazz2); System.out.println(clazz2 == clazz3); } } 反射(Class.forName()读取配置文件举例) import java.io.*; public class Demo2_Reflect { public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { // nouseReflect(); String str = null; BufferedReader br = new BufferedReader(new FileReader("config.properties")); str = br.readLine(); Class clazz = Class.forName(str); Fruit f = (Fruit) clazz.newInstance(); Juier j = new Juier(); j.run(f); } private static void nouseReflect() { Juier j = new Juier(); Apple apple = new Apple(); j.run(apple); j.run(new Orange()); } } interface Fruit{ public void squeeze(); } class Apple implements Fruit { @Override public void squeeze(){ System.out.println("苹果汁"); } } class Orange implements Fruit{ @Override public void squeeze(){ System.out.println("橙汁"); } } class Juier{ public void run(Fruit fruit){ fruit.squeeze(); } public void run(Orange orange){ orange.squeeze(); } } com.lizicai.reflect.Orange 通过反射获取带参构造方法并使用 构造函数必须public, 否则报NoSuchMethodException 异常. import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class Demo3_Reflect { public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { Class clazz = Class.forName("com.lizicai.bean.Person"); // Person p = (Person) clazz.newInstance(); Constructor c = clazz.getConstructor(String.class, int.class); Person p = (Person) c.newInstance("张三",23); System.out.println(p); } } public class Person { private String name; private int age; public Person(String name, int age){ this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public boolean equals(Object obj) { return super.equals(obj); } @Override public int hashCode() { return super.hashCode(); } @Override public String toString() { return this.getName() + this.getAge(); } } 通过反射获取成员变量并使用 import com.lizicai.bean.Person; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; public class Demo4_Reflect { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException { Class clazz = Class.forName("com.lizicai.bean.Person"); Constructor c = clazz.getConstructor(String.class, int.class); Person p = (Person) c.newInstance("张三",23); // Field f = clazz.getField("name"); // 暴力反射 Field f = clazz.getDeclaredField("name"); // 去除私有权限 f.setAccessible(true); f.set(p,"李四"); System.out.println(p); } } 通过反射获取方法并使用 import com.lizicai.bean.Person; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Demo5_Reflect { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, NoSuchFieldException, InvocationTargetException { Class clazz = Class.forName("com.lizicai.bean.Person"); Constructor c = clazz.getConstructor(String.class, int.class); Person p = (Person) c.newInstance("张三",23); Method m = clazz.getMethod("eat"); m.invoke(p); Method m2 = clazz.getMethod("eat", int.class); m2.invoke(p,10); } } 通过反射越过泛型检查 泛型编译时检查, 运行时没有检查 import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; public class Test1 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { ArrayList<Integer> list = new ArrayList<>(); list.add(1); list.add(2); Class clazz = Class.forName("java.util.ArrayList"); Method m = clazz.getMethod("add",Object.class); m.invoke(list,"test"); System.out.println(list); } } 通过反射写一个通用的设置某个对象的某个属性为指定的值 Person对象仍然是上面的 import java.lang.reflect.Field; public class Tool { public void setProperty(Object obj, String propertyName, Object value) throws NoSuchFieldException, IllegalAccessException { Class clazz = obj.getClass(); Field f = clazz.getDeclaredField(propertyName); f.setAccessible(true); f.set(obj,value); } } import com.lizicai.bean.Person; public class Test2 { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { Person p = new Person("小明",23); System.out.println(p); Tool t = new Tool(); t.setProperty(p,"name","小红"); System.out.println(p); } } 练习 import java.io.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Test3 { public static void main(String[] args) throws IOException, ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException { File file = new File("demo.properties"); BufferedReader br = new BufferedReader(new FileReader(file)); String clazzName = br.readLine(); br.close(); Class clazz = Class.forName(clazzName); DemoClass dc = (DemoClass) clazz.newInstance(); Method m = clazz.getMethod("run"); m.invoke(dc); } } public class DemoClass { public void run(){ System.out.println("大王叫我来巡山"); } } com.lizicai.test.DemoClass 动态代理的概述和实现 写好了代理, 就能在所有类前后进行一些处理 public interface User { public void add(); public void delete(); } public class UserImp implements User{ @Override public void add() { // System.out.println("权限校验"); System.out.println("添加"); // System.out.println("日志记录"); } @Override public void delete() { // System.out.println("权限校验"); System.out.println("删除"); // System.out.println("日志记录"); } } import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler { private Object target; public MyInvocationHandler(Object target){ this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("权限检验"); method.invoke(target,args); System.out.println("日志记录"); return null; } } import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { User ui = new UserImp(); ui.add(); ui.delete(); MyInvocationHandler m = new MyInvocationHandler(ui); User u = (User) Proxy.newProxyInstance(ui.getClass().getClassLoader(), ui.getClass().getInterfaces(),m); u.add(); u.delete(); } } 模版(Template)设计模式概述和使用 模版设计模式概述 模版方法模式就是定义一个算法模版, 而将具体的算法延迟到子类中实现 优点 缺点 使用模版方法模式, 在定义骨架的同时, 可以很灵活实现具体的方法, 满足用户灵活多变的需求 如果算法有修改, 则需要修改抽象类 public class Demo1_Template extends TestTime{ public static void main(String[] args) { Demo1_Template d = new Demo1_Template(); System.out.println(d.getTime()); } @Override public void code() { for(int i=0;i<100000;i++){ System.out.println(i); } } } abstract class TestTime{ final public long getTime(){ long start = System.currentTimeMillis(); code(); long end = System.currentTimeMillis(); return end - start; } public abstract void code(); } 自己实现枚举类 概述 是指将变量的值一一列举出来, 变量的值仅限于列举出来的值的范围内 单例模式, 只有一个实例 多例类就是一个类有多个实例, 但不是无限多个实例, 是有限个数的实例, 这才是枚举类. 枚举类有下例3种形式 public class Week { final static Week MON = new Week(); final static Week TUE = new Week(); final static Week WED = new Week(); private Week(){} } public class Week2 { final static Week2 MON = new Week2("星期一"); final static Week2 TUE = new Week2("星期二"); final static Week2 WED = new Week2("星期三"); String name; private Week2(String name){ this.name = name; } @Override public String toString() { return this.name; } } public abstract class Week3 { final static Week3 MON = new Week3("星期一"){ @Override public void show() { System.out.println("星期一"); } }; final static Week3 TUE = new Week3("星期二"){ @Override public void show() { System.out.println("星期二"); } }; final static Week3 WED = new Week3("星期三") { @Override public void show() { System.out.println("星期三"); } }; String name; private Week3(String name){ this.name = name; } @Override public String toString() { return this.name; } public abstract void show(); } public class Demo1_Enum { public static void main(String[] args) { Week mon = Week.MON; System.out.println(mon); Week2 Mon = Week2.MON; Week2 Tue = Week2.TUE; Week2 Wed = Week2.WED; System.out.println(Mon); System.out.println(Tue); System.out.println(Wed); Week3 MON = Week3.MON; Week3 TUE = Week3.TUE; Week3 WED = Week3.WED; MON.show(); TUE.show(); WED.show(); } } 通过enum实现枚举类 public enum Week { MON,TUE,WED; } public enum Week2 { MON("星期一"),TUE("星期二"),WED("星期三"); private String name ; Week2(String name){ this.name = name; } public String getName() { return name; } } public enum Week3 { MON("星期一"){ @Override public void show() { System.out.println("星期一"); } },TUE("星期二"){ @Override public void show() { System.out.println("星期二"); } },WED("星期三"){ @Override public void show() { System.out.println("星期三"); } }; private String name ; Week3(String name){ this.name = name; } public String getName() { return name; } public abstract void show(); } public class Demo1_Enum { public static void main(String[] args) { Week mon = Week.MON; Week tue = Week.TUE; System.out.println(mon); System.out.println(tue); Week2 Mon = Week2.MON; Week2 Tue = Week2.TUE; System.out.println(Mon); System.out.println(Tue.getName()); Week3 MON = Week3.MON; Week3 TUE = Week3.TUE; Week3 WED = Week3.WED; System.out.println(MON); System.out.println(TUE.getName()); System.out.println(WED.getName()); } } switch 使用枚举 public static void demo1(){ Week2 MON = Week2.TUE; switch (MON){ case MON: System.out.println("星期一"); break; case TUE: System.out.println("星期二"); break; case WED: System.out.println("星期三"); break; } } 常用的枚举方法 public final int ordinal() 获取枚举的位置 public final int compareTo(E o) 比较枚举位置, 返回差 public final String name() 获取枚举实例的名字 public static <T extends Enum> T valueOf(Class enumType, String name) 字节码对象获取枚举项 values 获取枚举的数组 public class Demo2_Enum { public static void main(String[] args) { Week2 mon = Week2.MON; Week2 tue = Week2.TUE; Week2 wed = Week2.WED; System.out.println(mon.ordinal()); System.out.println(tue.ordinal()); System.out.println(wed.ordinal()); System.out.println(mon.compareTo(tue)); System.out.println(mon.compareTo(wed)); System.out.println(mon.name()); System.out.println(tue.name()); System.out.println(mon); System.out.println(tue.toString()); // 字节码对象获取枚举项 Week2 TUE = Week2.valueOf(Week2.class,"TUE"); System.out.println(TUE); Week2[] arr = Week2.values(); for(Week2 w:arr){ System.out.println(w); } } } JDK 1.7 新增内容 switch支持字符串 异常catch多个异常, 用|隔开 try-whith-resources 自动关流 import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class Demo3_AutoClose { public static void main(String[] args) { File file = new File("config.properties"); //资源放在try()中, 会自动关闭资源, 不用在finally 中关闭了 try ( FileInputStream fis = new FileInputStream(file)){ int b; while ( ( b = fis.read() ) != -1){ System.out.println(b); } } catch (IOException e){ System.out.println(e.getMessage()); } } } JDK 1.8 新增内容 接口可以支持default修饰, 有方法体 接口也可以有静态方法了 内部类可访问的变量默认是final修饰 public class Demo4_JKD18 { // JDK1.8新特性 public static void main(String[] args) { Demo d = new Demo(); d.show(); Inter.test(); d.run(); } } interface Inter{ public default void show(){ System.out.println("显示"); } public static void test(){ System.out.println("测试"); } } class Demo implements Inter{ public void run(){ // num 默认是final int num = 20; class Inner{ public void fun(){ System.out.println("fun"); } } Inner i = new Inner(); i.fun(); } }

September 19, 2021&nbsp;·&nbsp;7 分钟&nbsp;·&nbsp;Lizicai