JavaWeb笔记:第07章 MVC |EL |JST |Filter |Listener |JQuery |AJAX |Maven |JSON |Redis |Linux |Nginx
说明:本内容整理自B站黑马程序员Java web课程视频及文档>>B站黑马程序员Java web课程视频
1. MVC 开发模式
1. jsp演变历史 1. 早期只有servlet,只能使用response输出标签数据,非常麻烦 2. 后来有了jsp,简化了Servlet的开发,如果过度使用jsp,在jsp中 即写大量的java代码,又写html表,造成难于维护,难于分工协作 3. 再后来,java的web开发,借鉴mvc开发模式,使得程序的设计更加合理性 2. MVC——将程序分为Model、View、Controller三部分 1. M:Model,模型。JavaBean(Java对象) 完成具体的业务操作,如:查询数据库,封装对象 2. V:View,视图。JSP 展示数据 3. C:Controller,控制器。Servlet 1.获取用户的输入 2.调用模型 3.将数据交给视图进行展示
MVC开发模式
![]() |
3.优缺点: 1. 优点: 1. 耦合性低,方便维护,可以利于分工协作 2. 重用性高 2. 缺点: 1. 使得项目架构变得复杂,对开发人员要求高
2. EL表达式
2.1 概念 & 作用 & 语法
1. 概念:Expression Language 表达式语言
2. 作用:替换和简化jsp页面中java代码的编写
3. 语法:${表达式}
4. 注意:
jsp默认支持el表达式的。如果要忽略el表达式
1. 设置jsp中page指令中:isELIgnored="true" 忽略当前jsp页面中所有的el表达式
2. \${表达式} :忽略当前这个el表达式
2.2 EL表达式的功能及使用
2.2.1 功能一:运算
1. 功能一:运算:
运算符:
1. 算数运算符: + - * /(div) %(mod)
2. 比较运算符: > < >= <= == !=
3. 逻辑运算符: &&(and) ||(or) !(not)
4. 空运算符: empty
功能:用于判断字符串、集合、数组对象是否为null或者长度是否为0
${empty list}:判断字符串、集合、数组对象是否为null或者长度为0
${not empty str}:表示判断字符串、集合、数组对象是否不为null 并且 长度>0
5.程序代码:
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${3 > 4}
\${3 > 4}
<hr>
<h3>算数运算符</h3>
${3 + 4}<br>
${3 / 4}<br>
${3 div 4}<br>
${3 % 4}<br>
${3 mod 4}<br>
<h3>比较运算符</h3>
${3 == 4}<br>
<h3>逻辑运算符</h3>
${3 > 4 && 3 < 4}<br>
${3 > 4 and 3 < 4}<br>
<h4>empty运算符</h4>
<%
String str = "";
request.setAttribute("str",str);
List list = new ArrayList();
request.setAttribute("list",list);
%>
${not empty str}
${not empty list}
</body>
</html>
2.2.2 功能二:获取值
2. 功能二:获取值
2.1、 el表达式只能从域对象中获取值
2.2、 语法:
1. ${域名称.键名}:从指定域中获取指定键的值
1.域名称:
1. pageScope --> 从pageContext中获取值
2. requestScope --> 从request中获取值
3. sessionScope --> 从session中获取值
4. applicationScope --> 从application(ServletContext)中获取值
2.举例:如在request域中存储了name=张三,则获取“张三”的方式为:${requestScope.name}
3.代码:
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>el获取域中的数据</title>
</head>
<body>
<%
//在域中存储数据
session.setAttribute("name","李四");
request.setAttribute("name","张三");
session.setAttribute("age","23");
request.setAttribute("str","");
%>
<h3>el获取值</h3>
${requestScope.name}
${sessionScope.age}
${sessionScope.haha}
${name}
${sessionScope.name}
</body>
</html>
2. ${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止。
3. 获取对象、List集合、Map集合的值
1. 对象:${域名称.键名.属性名}
1.本质上会去调用对象的getter方法
2.程序代码:
2. List集合:${域名称.键名[索引]}
3. Map集合:
${域名称.键名.key名称}
${域名称.键名["key名称"]}
4.代码:
1.User类:
package cn.itcast.domain;
import java.text.SimpleDateFormat;
import java.util.Date;
public class User {
private String name;
private int age;
private Date birthday;
public User(String name, int age, Date birthday) {
this.name = name;
this.age = age;
this.birthday = birthday;
}
public User() {
}
/**
* 逻辑视图
* @return
*/
public String getBirStr(){
if(birthday != null){
//1.格式化日期对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//2.返回字符串即可
return sdf.format(birthday);
}else{
return "";
}
}
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;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
3. el.jsp代码:
<%@ page import="cn.itcast.domain.User" %>
<%@ page import="java.util.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>el获取数据</title>
</head>
<body>
<%
User user = new User();
user.setName("张三");
user.setAge(23);
user.setBirthday(new Date());
request.setAttribute("u",user);
List list = new ArrayList();
list.add("aaa");
list.add("bbb");
list.add(user);
request.setAttribute("list",list);
Map map = new HashMap();
map.put("sname","李四");
map.put("gender","男");
map.put("user",user);
request.setAttribute("map",map);
%>
<h3>el获取对象中的值</h3>
${requestScope.u}<br>
<%--
* 通过的是对象的属性来获取
* setter或getter方法,去掉set或get,在将剩余部分,首字母变为小写。
* setName --> Name --> name
--%>
${requestScope.u.name}<br>
${u.age}<br>
${u.birthday}<br>
${u.birthday.month}<br>
${u.birStr}<br>
<h3>el获取List值</h3>
${list}<br>
${list[0]}<br>
${list[1]}<br>
${list[10]}<br>
${list[2].name}
<h3>el获取Map值</h3>
${map.gender}<br>
${map["gender"]}<br>
${map.user.name}
</body>
</html>
效果:
![]() |
3.3 EL表达式中的隐式对象
3. 隐式对象:
1.el表达式中有11个隐式对象
2.隐式对象pageContext的功能:
1.获取jsp其他八个内置对象
2.${pageContext.request.contextPath}:动态获取虚拟目录
3.代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>el隐式对象</title>
</head>
<body>
${pageContext.request}<br>
<h4>在jsp页面动态获取虚拟目录</h4>
${pageContext.request.contextPath}
<%
%>
</body>
</html>
3. JSTL
3.1 JSTL概念 & 作用 & 使用
1. 概念:JavaServer Pages Tag Library JSP标准标签库
是由Apache组织提供的开源的免费的jsp标签 <标签>
2. 作用:用于简化和替换jsp页面上的java代码
3. 使用步骤:
1. 导入jstl相关jar包
2. 引入标签库:taglib指令: <%@ taglib %>
3. 使用标签
4. 常用的JSTL标签—— if | choose | foreach
3.2 常用的JSTL标签—— if | choose | foreach
2.常用的JSTL标签—— if | choose | foreach
3.2.1 if标签
1. if:相当于java代码的if语句
1. 属性:
test 必须属性,接受boolean表达式
如果表达式为true,则显示if标签体内容,如果为false,则不显示标签体内容
一般情况下,test属性值会结合el表达式一起使用
2. 注意:
c:if标签没有else情况,想要else情况,则可以再定义一个c:if标签
3.代码:
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>if标签</title>
</head>
<body>
<%--
c:if标签
1. 属性:
* test 必须属性,接受boolean表达式
* 如果表达式为true,则显示if标签体内容,如果为false,则不显示标签体内容
* 一般情况下,test属性值会结合el表达式一起使用
2. 注意:c:if标签没有else情况,想要else情况,则可以在定义一个c:if标签
--%>
<c:if test="true">
<h1>我是真...</h1>
</c:if>
<br>
<%
//判断request域中的一个list集合是否为空,如果不为null则显示遍历集合
List list = new ArrayList();
list.add("aaaa");
request.setAttribute("list",list);
request.setAttribute("number",4);
%>
<c:if test="${not empty list}">
遍历集合...
</c:if>
<br>
<c:if test="${number % 2 != 0}">
${number}为奇数
</c:if>
<c:if test="${number % 2 == 0}">
${number}为偶数
</c:if>
</body>
</html>
3.2.2 choose标签
2. choose:相当于java代码的switch语句
1. 使用choose标签声明 相当于switch声明
2. 使用when标签做判断 相当于case
3. 使用otherwise标签做其他情况的声明 相当于default
4.代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>choose标签</title>
</head>
<body>
<%--
完成数字编号对应星期几案例
1.域中存储一数字
2.使用choose标签取出数字 相当于switch声明
3.使用when标签做数字判断 相当于case
4.otherwise标签做其他情况的声明 相当于default
--%>
<%
request.setAttribute("number",51);
%>
<c:choose>
<c:when test="${number == 1}">星期一</c:when>
<c:when test="${number == 2}">星期二</c:when>
<c:when test="${number == 3}">星期三</c:when>
<c:when test="${number == 4}">星期四</c:when>
<c:when test="${number == 5}">星期五</c:when>
<c:when test="${number == 6}">星期六</c:when>
<c:when test="${number == 7}">星期天</c:when>
<c:otherwise>数字输入有误</c:otherwise>
</c:choose>
</body>
</html>
3.2.3 foreach标签
3. foreach:相当于java代码的for语句
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>foreach标签</title>
</head>
<body>
<%--
foreach:相当于java代码的for语句
1. 完成重复的操作
for(int i = 0; i < 10; i ++){
}
* 属性:
begin:开始值
end:结束值
var:临时变量
step:步长
varStatus:循环状态对象
index:容器中元素的索引,从0开始
count:循环次数,从1开始
--%>
<c:forEach begin="1" end="10" var="i" step="2" varStatus="s">
${i} <h3>${s.index}<h3> <h4> ${s.count} </h4><br>
</c:forEach>
<hr>
<%--
2. 遍历容器
List<User> list;
for(User user : list){
}
* 属性:
items:容器对象
var:容器中元素的临时变量
varStatus:循环状态对象
index:容器中元素的索引,从0开始
count:循环次数,从1开始
--%>
<%
List list = new ArrayList();
list.add("aaa");
list.add("bbb");
list.add("ccc");
request.setAttribute("list",list);
%>
<c:forEach items="${list}" var="str" varStatus="s">
${s.index} ${s.count} ${str}<br>
</c:forEach>
</body>
</html>
3.3 案例练习
5. 练习:
需求:
1.在request域中有一个存有User对象的List集合。需要使用jstl+el将list集合数据展示到jsp页面的表格table中
2.隔行显示不同的颜色
<%@ page import="cn.itcast.domain.User" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>test</title>
</head>
<body>
<%
List list = new ArrayList();
list.add(new User("张三",23,new Date()));
list.add(new User("李四",24,new Date()));
list.add(new User("王五",25,new Date()));
request.setAttribute("list",list);
%>
<table border="1" width="500" align="center">
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
<th>生日</th>
</tr>
<%--数据行--%>
<c:forEach items="${list}" var="user" varStatus="s">
<c:if test="${s.count % 2 != 0}">
<tr bgcolor="red">
<td>${s.count}</td>
<td>${user.name}</td>
<td>${user.age}</td>
<td>${user.birStr}</td>
</tr>
</c:if>
<c:if test="${s.count % 2 == 0}">
<tr bgcolor="green">
<td>${s.count}</td>
<td>${user.name}</td>
<td>${user.age}</td>
<td>${user.birStr}</td>
</tr>
</c:if>
</c:forEach>
</table>
</body>
</html>
网页效果

4. 三层架构:软件设计架构
4.1 概念 & 示意图
1. 界面层(表示层):用户看的得界面。用户可以通过界面上的组件和服务器进行交互 2. 业务逻辑层:处理业务逻辑的 3. 数据访问层:操作数据存储文件
三层架构示意图:

4.2 案例:用户信息列表展示
1. 需求:用户信息的增删改查操作 2. 设计: 1. 技术选型:Servlet+JSP+MySQL+JDBCTempleat+Duird+BeanUtilS+tomcat 2. 数据库设计: create database day17; -- 创建数据库 use day17; -- 使用数据库 create table user( -- 创建表 id int primary key auto_increment, name varchar(20) not null, gender varchar(5), age int, address varchar(32), qq varchar(20), email varchar(50) ); 3. 开发: 1. 环境搭建 1. 创建数据库环境 2. 创建项目,导入需要的jar包 2. 编码 4. 测试 5. 部署运维
用户信息的增删改查

5. Filter:过滤器
5.1 概念 & 快速入门
1. 概念: 1.生活中的过滤器:净水器,空气净化器,土匪、 2.web中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。 3.过滤器的作用: 一般用于完成通用的操作。如:登录验证、统一编码处理、敏感字符过滤...

2. 快速入门:
1.步骤:
1. 定义一个类,实现接口Filter(实现javax.servlet包下的Filter接口)
2. 复写方法
3. 配置拦截路径
1. web.xml
2. 注解
注意:是实现javax.servlet包下的Filter接口

3. 代码:
@WebFilter("/*")//访问所有资源之前,都会执行该过滤器
public class FilterDemo1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("filterDemo1被执行了....");
//放行
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
5.2 Filter过滤器细节
3. 过滤器细节:
1. web.xml配置中配置( 如下配置的作用等同于注解@WebFilter("/*") )
<filter>
<filter-name>demo1</filter-name>
<filter-class>cn.itcast.web.filter.FilterDemo1</filter-class>
</filter>
<filter-mapping>
<filter-name>demo1</filter-name>
<!-- 拦截路径 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
2. 过滤器执行流程
1. 执行过滤器
2. 执行放行后的资源
3. 回来执行过滤器放行代码下边的代码
4. 代码:
package cn.itcast.web.filter;
import javax.servlet.*;
import java.io.IOException;
//@WebFilter("/*")
public class FilterDemo2 implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//对request对象请求消息增强
System.out.println("filterDemo2执行了....");
//放行
chain.doFilter(req, resp);
//对response对象的响应消息增强
System.out.println("filterDemo2回来了...");
}
public void init(FilterConfig config) throws ServletException {
}
public void destroy() {
}
}
3. 过滤器生命周期方法
1. init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次。用于加载资源
2. doFilter:每一次请求被拦截资源时,会执行。执行多次
3. destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次。用于释放资源
4. 过滤器配置详解
1.拦截路径配置:
1. 具体资源路径: /index.jsp 只有访问index.jsp资源时,过滤器才会被执行
2. 拦截目录: /user/* 访问/user下的所有资源时,过滤器都会被执行
3. 后缀名拦截: *.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行
4. 拦截所有资源:/* 访问所有资源时,过滤器都会被执行
2.拦截方式配置:资源被访问的方式
1.注解配置:
设置dispatcherTypes属性
1. REQUEST:默认值。浏览器直接请求资源
2. FORWARD:转发访问资源
3. INCLUDE:包含访问资源
4. ERROR:错误跳转资源
5. ASYNC:异步访问资源
2.web.xml配置
设置<dispatcher></dispatcher>标签即可
3.代码:
package cn.itcast.web.filter;
import javax.servlet.*;
import java.io.IOException;
//浏览器直接请求index.jsp资源时,该过滤器会被执行
//@WebFilter(value="/index.jsp",dispatcherTypes = DispatcherType.REQUEST)
//只有转发访问index.jsp时,该过滤器才会被执行
//@WebFilter(value="/index.jsp",dispatcherTypes = DispatcherType.FORWARD)
//浏览器直接请求index.jsp或者转发访问index.jsp。该过滤器才会被执行
//@WebFilter(value="/*",dispatcherTypes ={ DispatcherType.FORWARD,DispatcherType.REQUEST})
public class FilterDemo5 implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("filterDemo5....");
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
public void destroy() {
}
}
5. 过滤器链(配置多个过滤器)
1.执行顺序:如果有两个过滤器:过滤器1和过滤器2
1. 过滤器1
2. 过滤器2
3. 资源执行
4. 过滤器2
5. 过滤器1
2.过滤器先后顺序问题:
1. 注解配置:按照类名的字符串比较规则比较,值小的先执行(根据字典序进行比较)
如: AFilter 和 BFilter,AFilter就先执行了。
2. web.xml配置: 谁定义在上边,谁先执行
5.3 Filter过滤器案例
5.3.1 案例一 :登录验证
4. 案例:
1. 案例1_登录验证
需求:
1. 访问day17_case案例的资源。验证其是否登录
2. 如果登录了,则直接放行。
3. 如果没有登录,则跳转到登录页面,提示"您尚未登录,请先登录"。
登录验证流程

案例1_登录验证代码:
package cn.itcast.web.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* 登录验证的过滤器
*/
@WebFilter("/*")
public class LoginFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println(req);
//0.强制转换(ServletRequest是接口)
HttpServletRequest request = (HttpServletRequest) req;
//1.获取资源请求路径
String uri = request.getRequestURI();
//2.判断是否包含登录相关资源路径,要注意排除掉 css/js/图片/验证码等资源
if(uri.contains("/login.jsp") || uri.contains("/loginServlet") || uri.contains("/css/") || uri.contains("/js/") || uri.contains("/fonts/") || uri.contains("/checkCodeServlet") ){
//包含,用户就是想登录。放行
chain.doFilter(req, resp);
}else{
//不包含,需要验证用户是否登录
//3.从获取session中获取user
Object user = request.getSession().getAttribute("user");
if(user != null){
//登录了。放行
chain.doFilter(req, resp);
}else{
//没有登录。跳转登录页面
request.setAttribute("login_msg","您尚未登录,请登录");
request.getRequestDispatcher("/login.jsp").forward(request,resp);
}
}
// chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
public void destroy() {
}
}
5.3.2 案例二 :敏感词汇过滤
5.3.2.1 需求 & 分析
2. 案例2_敏感词汇过滤 1.需求: 1. 对day17_case案例录入的数据进行敏感词汇过滤 2. 敏感词汇参考《敏感词汇.txt》 3. 如果是敏感词汇,替换为 *** 2.分析: 1. 对request对象进行增强。增强获取参数相关方法 2. 放行。传递代理对象

5.3.2.2 知识点补充——代理模式
3.知识点补充——代理模式 如何增强对象的功能?———— 代理模式(设计模式:一些通用的解决固定问题的方式) 1. 代理模式 概念: 1. 真实对象:被代理的对象 2. 代理对象: 3. 代理模式:代理对象代理真实对象,达到增强真实对象功能的目的 代理模式实现方式: 1. 静态代理:有一个类文件描述代理模式 2. 动态代理:在内存中形成代理类 动态代理实现步骤: 1. 代理对象和真实对象实现相同的接口 2. 获取代理对象: 代理对象= Proxy.newProxyInstance(); 3. 使用代理对象调用方法。 4. 增强方法 动态代理增强方式: 1. 增强参数列表 2. 增强返回值类型 3. 增强方法体执行逻辑
现实中代理的情形:

5.3.2.3 代理模式例程
2.代理模式 例程:
1、SaleComputer接口
package cn.itcast.proxy;
public interface SaleComputer {
public String sale(double money);
public void show();
}
2、Lenovo类
package cn.itcast.proxy;
/**
* 真实类
*/
public class Lenovo implements SaleComputer {
@Override
public String sale(double money) {
System.out.println("花了"+money+"元买了一台联想电脑...");
return "联想电脑";
}
@Override
public void show() {
System.out.println("展示电脑....");
}
}
3、ProxyTest类
package cn.itcast.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) {
//1.创建真实对象
Lenovo lenovo = new Lenovo();
//2.动态代理增强lenovo对象
/*
三个参数:
1. 类加载器:真实对象.getClass().getClassLoader()
2. 接口数组:真实对象.getClass().getInterfaces()
3. 处理器:new InvocationHandler()
*/
SaleComputer proxy_lenovo = (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() {
/*
代理逻辑编写的方法:代理对象调用的所有方法都会触发该方法执行
参数:
1. proxy:代理对象
2. method:代理对象调用的方法,被封装为的对象
3. args:代理对象调用的方法时,传递的实际参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/*System.out.println("该方法执行了....");
System.out.println(method.getName());
System.out.println(args[0]);
*/
//判断是否是sale方法
if(method.getName().equals("sale")){
//1.增强参数
double money = (double) args[0];
money = money * 0.85;
System.out.println("专车接你....");
//使用真实对象调用该方法
String obj = (String) method.invoke(lenovo, money);
System.out.println("免费送货...");
//2.增强返回值
return obj+"_鼠标垫";
}else{
Object obj = method.invoke(lenovo, args);
return obj;
}
}
});
//3.调用方法
/* String computer = proxy_lenovo.sale(8000);
System.out.println(computer);*/
proxy_lenovo.show();
}
}
5.3.2.4 敏感词过滤代码
package cn.itcast.web.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
/**
* 敏感词汇过滤器
*/
@WebFilter("/*")
public class SensitiveWordsFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//1.创建代理对象,增强getParameter方法
ServletRequest proxy_req = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//增强getParameter方法
//判断是否是getParameter方法
if(method.getName().equals("getParameter")){
//增强返回值
//获取返回值
String value = (String) method.invoke(req,args);
if(value != null){
for (String str : list) {
if(value.contains(str)){
value = value.replaceAll(str,"***");
}
}
}
return value;
}
//后续完善一:判断方法名是否是 getParameterMap
//后续完善二:判断方法名是否是 getParameterValue
return method.invoke(req,args);
}
});
//2.放行
chain.doFilter(proxy_req, resp);
}
private List list = new ArrayList();//敏感词汇集合
public void init(FilterConfig config) throws ServletException {
try{
//1.获取文件真实路径
ServletContext servletContext = config.getServletContext();
String realPath = servletContext.getRealPath("/WEB-INF/classes/敏感词汇.txt");
//2.读取文件
BufferedReader br = new BufferedReader(new FileReader(realPath));
//3.将文件的每一行数据添加到list中
String line = null;
while((line = br.readLine())!=null){
list.add(line);
}
br.close();
System.out.println(list);
}catch (Exception e){
e.printStackTrace();
}
}
public void destroy() {
}
}
6. Listener:监听器
6.1 概念 & ServletContextListener接口
1. 概念:web的三大组件之一。 事件监听机制 事件 :一件事情 事件源 :事件发生的地方 监听器 :一个对象 注册监听:将事件、事件源、监听器绑定在一起。 当事件源上发生某个事件后,执行监听器代码 2.ServletContextListener接口:监听ServletContext对象的创建和销毁 方法: void contextDestroyed(ServletContextEvent sce) :ServletContext对象被销毁之前会调用该方法 void contextInitialized(ServletContextEvent sce) :ServletContext对象创建后会调用该方法 实现监听器步骤: 1. 定义一个类,实现ServletContextListener接口 2. 复写方法 3. 配置 1. 配置方式一web.xml <listener> <listener-class>cn.itcast.web.listener.ContextLoaderListener</listener-class> </listener> 指定初始化参数<context-param> 2. 配置方式二注解: @WebListener
6.2 Listener 代码
package cn.itcast.web.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import java.io.FileInputStream;
@WebListener
public class ContextLoaderListener implements ServletContextListener {
/**
* 监听ServletContext对象创建的。ServletContext对象服务器启动后自动创建。
*
* 在服务器启动后自动调用
* @param servletContextEvent
*/
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//加载资源文件
//1.获取ServletContext对象
ServletContext servletContext = servletContextEvent.getServletContext();
//2.加载资源文件
String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");
//3.获取真实路径
String realPath = servletContext.getRealPath(contextConfigLocation);
//4.加载进内存
try{
FileInputStream fis = new FileInputStream(realPath);
System.out.println(fis);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("ServletContext对象被创建了。。。");
}
/**
* 在服务器关闭后,ServletContext对象被销毁。当服务器正常关闭后该方法被调用
* @param servletContextEvent
*/
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext对象被销毁了。。。");
}
}
7. JQuery 基础
7.1 JQuery 概念
1. 概念: 一个JavaScript框架。简化JS开发
jQuery是一个快速、简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架)。
jQuery设计的宗旨 是“write Less,Do More”,即倡导写更少的代码,做更多的事情。
它封装JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作、事件处理、动画设计和Ajax交互。
JavaScript框架:本质上就是一些js文件,封装了js的原生代码而已
2.可以自定义js代码封装方法,实现简单的js框架(jQuery是较复杂的JavaScript框架):
1.在js/itcast.js文件中自定义方法:
//封装方法,根据id来获取元素对象
function $(id){
var obj = document.getElementById(id);
return obj;
}
2.在代码中调用自定义框架方法(JQuery就是封装了复杂功能的框架)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义js框架</title>
<script src="js/itcast.js"></script>
</head>
<body>
<div id="div1">div1....</div>
<div id="div2">div2....</div>
<script>
//1. 根据id获取元素对象
//var div1 = document.getElementById("div1");
//var div2 = document.getElementById("div2");
var div1 = $("div1");
var div2 = $("div2");
//2.获取标签体内容
alert(div1.innerHTML);
alert(div2.innerHTML);
</script>
</body>
</html>
7.2 JQuery 快速入门
1. 步骤:
1. 下载JQuery
* 版本说明:目前jQuery有三个大版本:
1.x:兼容ie678,使用最为广泛的,官方只做BUG维护,
功能不再新增。因此一般项目来说,使用1.x版本就可以了,
最终版本:1.12.4 (2016年5月20日)
2.x:不兼容ie678,很少有人使用,官方只做BUG维护,
功能不再新增。如果不考虑兼容低版本的浏览器可以使用2.x,
最终版本:2.2.4 (2016年5月20日)
3.x:不兼容ie678,只支持最新的浏览器。除非特殊要求,
一般不会使用3.x版本的,很多老的jQuery插件不支持这个版本。
目前该版本是官方主要更新维护的版本。最新版本:3.2.1(2017年3月20日)
* jquery-xxx.js 与 jquery-xxx.min.js区别:
1. jquery-xxx.js:开发版本。给程序员看的,有良好的缩进和注释。体积大一些
2. jquery-xxx.min.js:生产版本。程序中使用,没有缩进。体积小一些。程序加载更快
2. 导入JQuery的js文件:导入min.js文件
3. 使用JQuery:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JQuery快速入门</title>
<script src="js/jquery-3.3.1.min.js"></script>
</head>
<body>
<div id="div1">div1....</div>
<div id="div2">div2....</div>
<script>
//使用JQuery获取元素对象
var div1 = $("#div1");
alert(div1.html());
var div2 = $("#div2");
alert(div2.html());
</script>
</body>
</html>
7.3 JQuery对象与JS对象区别和转换
3. JQuery对象和JS对象区别与转换
1. JQuery对象在操作时,更加方便。
2. JQuery对象和js对象方法不通用的.
3. 两者相互转换
jq -- > js : jq对象[索引] 或者 jq对象.get(索引)
js -- > jq : $(js对象)
4.代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JQuer对象和js对象的转换</title>
<script src="js/jquery-3.3.1.min.js"></script>
</head>
<body>
<div id="div1">div1....</div>
<div id="div2">div2....</div>
<script>
//1. 通过js方式来获取名称叫div的所有html元素对象
var divs = document.getElementsByTagName("div");
alert(divs.length);//divs可以将其当做数组来使用
//对divs中所有的div 让其标签体内容变为"aaa"
for (var i = 0; i < divs.length; i++) {
//divs[i].innerHTML = "aaa";
$(divs[i]).html("ccc");
}
//2. 通过jq方式来获取名称叫div的所有html元素对象
var $divs = $("div");
alert($divs.length);//$divs也可以当做数组使用
//对divs中所有的div 让其标签体内容变为"bbb" 使用jq方式
//$divs.html("bbb");
// $divs.innerHTML = "bbb";
$divs[0].innerHTML = "ddd";
$divs.get(1).innerHTML = "eee";
/*
1. JQuery对象在操作时,更加方便。
2. JQuery对象和js对象方法不通用的.
3. 两者相互转换
* jq -- > js : jq对象[索引] 或者 jq对象.get(索引)
* js -- > jq : $(js对象)
*/
</script>
</body>
</html>
7.4 JQuery选择器
选择器:筛选具有相似特征的元素(标签)
7.4.1 基本操作学习
1. 事件绑定
//1.获取b1按钮
$("#b1").click(function(){
alert("abc");
});
2. 入口函数
$(function () {
});
window.onload 和 $(function) 区别:
* window.onload 只能定义一次,如果定义多次,后边的会将前边的覆盖掉
* $(function)可以定义多次的。
3. 样式控制:css方法
// $("#div1").css("background-color","red");
$("#div1").css("backgroundColor","pink");
4.代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件绑定</title>
<script src="js/jquery-3.3.1.min.js"></script>
<script>
// 给b1按钮添加单击事件
/* window.onload = function(){
//1.获取b1按钮
$("#b1").click(function(){
alert("abc");
});
}*/
/* //jquery入口函数(dom文档加载完成之后执行该函数中的代码)
$(function () {
//1.获取b1按钮
$("#b1").click(function(){
alert("abc");
});
});*/
/* function fun1(){
alert("abc");
}
function fun2(){
alert("bcd");
}
window.onload = fun1;
//window.onload = fun2;
*/
/* $(function(){
alert(123);
});
$(function(){
alert(234);
});
*/
$(function(){
// $("#div1").css("background-color","red");
$("#div1").css("backgroundColor","pink");
});
/*
window.onload 和 $(function) 区别
* window.onload 只能定义一次,如果定义多次,后边的会将前边的覆盖掉
* $(function)可以定义多次的。
*/
</script>
</head>
<body>
<div id="div1">div1....</div>
<div id="div2">div2....</div>
<input type="button" value="点我" id="b1">
</body>
</html>
7.4.2 选择器分类
7.4.2.1 基本选择器
1. 标签选择器(元素选择器)
语法: $("html标签名") 获得所有匹配标签名称的元素
2. id选择器
语法: $("#id的属性值") 获得与指定id属性值匹配的元素
3. 类选择器
语法: $(".class的属性值") 获得与指定的class属性值匹配的元素
4. 并集选择器:
语法: $("选择器1,选择器2....") 获取多个选择器选中的所有元素
5.示例代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>基本选择器</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="../js/jquery-3.3.1.min.js"></script>
<style type="text/css">
div,span{
width: 180px;
height: 180px;
margin: 20px;
background: #9999CC;
border: #000 1px solid;
float:left;
font-size: 17px;
font-family:Roman;
}
div .mini{
width: 50px;
height: 50px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
div .mini01{
width: 50px;
height: 50px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
</style>
<script type="text/javascript">
$(function () {
// <input type="button" value="改变 id 为 one 的元素的背景色为 红色" id="b1"/>
$("#b1").click(function () {
$("#one").css("backgroundColor","pink");
});
// <input type="button" value=" 改变元素名为 <div> 的所有元素的背景色为 红色" id="b2"/>
$("#b2").click(function () {
$("div").css("backgroundColor","pink");
});
// <input type="button" value=" 改变 class 为 mini 的所有元素的背景色为 红色" id="b3"/>
$("#b3").click(function () {
$(".mini").css("backgroundColor","pink");
});
// <input type="button" value=" 改变所有的<span>元素和 id 为 two 的元素的背景色为红色" id="b4"/>
$("#b4").click(function () {
$("span,#two").css("backgroundColor","pink");
});
});
</script>
</head>
<body>
<input type="button" value="保存" class="mini" name="ok" class="mini" />
<input type="button" value="改变 id 为 one 的元素的背景色为 红色" id="b1"/>
<input type="button" value=" 改变元素名为 <div> 的所有元素的背景色为 红色" id="b2"/>
<input type="button" value=" 改变 class 为 mini 的所有元素的背景色为 红色" id="b3"/>
<input type="button" value=" 改变所有的<span>元素和 id 为 two 的元素的背景色为红色" id="b4"/>
<h1>有一种奇迹叫坚持</h1>
<h2>自信源于努力</h2>
<div id="one">
id为one
</div>
<div id="two" class="mini" >
id为two class是 mini
<div class="mini" >class是 mini</div>
</div>
<div class="one" >
class是 one
<div class="mini" >class是 mini</div>
<div class="mini" >class是 mini</div>
</div>
<div class="one" >
class是 one
<div class="mini01" >class是 mini01</div>
<div class="mini" >class是 mini</div>
</div>
<span class="spanone">class为spanone的span元素</span>
<span class="mini">class为mini的span元素</span>
<input type="text" value="zhang" id="username" name="username">
</body>
</html>
7.4.2.2 层级选择器
1. 后代选择器
语法: $("A B ") 选择A元素内部的所有B元素
2. 子选择器
语法: $("A > B") 选择A元素内部的所有B子元素
3.示例代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>层次选择器</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="../js/jquery-3.3.1.min.js"></script>
<style type="text/css">
div,span{
width: 180px;
height: 180px;
margin: 20px;
background: #9999CC;
border: #000 1px solid;
float:left;
font-size: 17px;
font-family:Roman;
}
div .mini{
width: 50px;
height: 50px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
div .mini01{
width: 50px;
height: 50px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
</style>
<script type="text/javascript">
$(function () {
// <input type="button" value=" 改变 <body> 内所有 <div> 的背景色为红色" id="b1"/>
$("#b1").click(function () {
$("body div").css("backgroundColor","pink");
});
// <input type="button" value=" 改变 <body> 内子 <div> 的背景色为 红色" id="b2"/>
$("#b2").click(function () {
$("body > div").css("backgroundColor","pink");
});
});
</script>
</head>
<body>
<input type="button" value="保存" class="mini" name="ok" class="mini" />
<input type="button" value=" 改变 <body> 内所有 <div> 的背景色为红色" id="b1"/>
<input type="button" value=" 改变 <body> 内子 <div> 的背景色为 红色" id="b2"/>
<h1>有一种奇迹叫坚持</h1>
<h2>自信源于努力</h2>
<div id="one">
id为one
</div>
<div id="two" class="mini" >
id为two class是 mini
<div class="mini" >class是 mini</div>
</div>
<div class="one" >
class是 one
<div class="mini" >class是 mini</div>
<div class="mini" >class是 mini</div>
</div>
<div class="one">
class是 one
<div class="mini01" >class是 mini01</div>
<div class="mini" >class是 mini</div>
</div>
<span class="spanone"> span
</span>
</body>
</html>
7.4.2.3 属性选择器
1. 属性名称选择器
语法: $("A[属性名]") 包含指定属性的选择器
2. 属性选择器
语法: $("A[属性名='值']") 包含指定属性等于指定值的选择器
3. 复合属性选择器
语法: $("A[属性名='值'][]...") 包含多个属性条件的选择器
4.示例代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>属性过滤选择器</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="../js/jquery-3.3.1.min.js"></script>
<style type="text/css">
div,span{
width: 180px;
height: 180px;
margin: 20px;
background: #9999CC;
border: #000 1px solid;
float:left;
font-size: 17px;
font-family:Roman;
}
div .mini{
width: 50px;
height: 50px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
div .mini01{
width: 50px;
height: 50px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
div.visible{
display:none;
}
</style>
<script type="text/javascript">
$(function () {
// <input type="button" value=" 含有属性title 的div元素背景色为红色" id="b1"/>
$("#b1").click(function () {
$("div[title]").css("backgroundColor","pink");
});
// <input type="button" value=" 属性title值等于test的div元素背景色为红色" id="b2"/>
$("#b2").click(function () {
$("div[title='test']").css("backgroundColor","pink");
});
// <input type="button" value=" 属性title值不等于test的div元素(没有属性title的也将被选中)背景色为红色" id="b3"/>
$("#b3").click(function () {
$("div[title!='test']").css("backgroundColor","pink");
});
// <input type="button" value=" 属性title值 以te开始 的div元素背景色为红色" id="b4"/>
$("#b4").click(function () {
$("div[title^='te']").css("backgroundColor","pink");
});
// <input type="button" value=" 属性title值 以est结束 的div元素背景色为红色" id="b5"/>
$("#b5").click(function () {
$("div[title$='est']").css("backgroundColor","pink");
});
// <input type="button" value="属性title值 含有es的div元素背景色为红色" id="b6"/>
$("#b6").click(function () {
$("div[title*='es']").css("backgroundColor","pink");
});
// <input type="button" value="选取有属性id的div元素,然后在结果中选取属性title值含有“es”的 div 元素背景色为红色" id="b7"/>
$("#b7").click(function () {
$("div[id][title*='es']").css("backgroundColor","pink");
});
});
</script>
</head>
<body>
<input type="button" value="保存" class="mini" name="ok" class="mini" />
<input type="button" value=" 含有属性title 的div元素背景色为红色" id="b1"/>
<input type="button" value=" 属性title值等于test的div元素背景色为红色" id="b2"/>
<input type="button" value=" 属性title值不等于test的div元素(没有属性title的也将被选中)背景色为红色" id="b3"/>
<input type="button" value=" 属性title值 以te开始 的div元素背景色为红色" id="b4"/>
<input type="button" value=" 属性title值 以est结束 的div元素背景色为红色" id="b5"/>
<input type="button" value="属性title值 含有es的div元素背景色为红色" id="b6"/>
<input type="button" value="选取有属性id的div元素,然后在结果中选取属性title值含有“es”的 div 元素背景色为红色" id="b7"/>
<div id="one">
id为one div
</div>
<div id="two" class="mini" title="test">
id为two class是 mini div title="test"
<div class="mini" >class是 mini</div>
</div>
<div class="visible" >
class是 one
<div class="mini" >class是 mini</div>
<div class="mini" >class是 mini</div>
</div>
<div class="one" title="test02">
class是 one title="test02"
<div class="mini01" >class是 mini01</div>
<div class="mini" style="margin-top:0px;">class是 mini</div>
</div>
<div class="visible" >
这是隐藏的
</div>
<div class="one">
</div>
<div id="mover" >
动画
</div>
<input type="text" value="zhang" id="username" name="username">
</body>
</html>
7.4.2.4 过滤选择器
1. 首元素选择器
语法: :first 获得选择的元素中的第一个元素
2. 尾元素选择器
语法: :last 获得选择的元素中的最后一个元素
3. 非元素选择器
语法: :not(selector) 不包括指定内容的元素
4. 偶数选择器
语法: :even 偶数,从 0 开始计数
5. 奇数选择器
语法: :odd 奇数,从 0 开始计数
6. 等于索引选择器
语法: :eq(index) 指定索引元素
7. 大于索引选择器
语法: :gt(index) 大于指定索引元素
8. 小于索引选择器
语法: :lt(index) 小于指定索引元素
9. 标题选择器
语法: :header 获得标题(h1~h6)元素,固定写法
10.示例代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>基本过滤选择器</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="../js/jquery-3.3.1.min.js"></script>
<style type="text/css">
div,span{
width: 180px;
height: 180px;
margin: 20px;
background: #9999CC;
border: #000 1px solid;
float:left;
font-size: 17px;
font-family:Roman;
}
div .mini{
width: 50px;
height: 50px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
div .mini01{
width: 50px;
height: 50px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
</style>
<script type="text/javascript">
$(function () {
// <input type="button" value=" 改变第一个 div 元素的背景色为 红色" id="b1"/>
$("#b1").click(function () {
$("div:first").css("backgroundColor","pink");
});
// <input type="button" value=" 改变最后一个 div 元素的背景色为 红色" id="b2"/>
$("#b2").click(function () {
$("div:last").css("backgroundColor","pink");
});
// <input type="button" value=" 改变class不为 one 的所有 div 元素的背景色为 红色" id="b3"/>
$("#b3").click(function () {
$("div:not(.one)").css("backgroundColor","pink");
});
// <input type="button" value=" 改变索引值为偶数的 div 元素的背景色为 红色" id="b4"/>
$("#b4").click(function () {
$("div:even").css("backgroundColor","pink");
});
// <input type="button" value=" 改变索引值为奇数的 div 元素的背景色为 红色" id="b5"/>
$("#b5").click(function () {
$("div:odd").css("backgroundColor","pink");
});
// <input type="button" value=" 改变索引值为大于 3 的 div 元素的背景色为 红色" id="b6"/>
$("#b6").click(function () {
$("div:gt(3)").css("backgroundColor","pink");
});
// <input type="button" value=" 改变索引值为等于 3 的 div 元素的背景色为 红色" id="b7"/>
$("#b7").click(function () {
$("div:eq(3)").css("backgroundColor","pink");
});
// <input type="button" value=" 改变索引值为小于 3 的 div 元素的背景色为 红色" id="b8"/>
$("#b8").click(function () {
$("div:lt(3)").css("backgroundColor","pink");
});
// <input type="button" value=" 改变所有的标题元素的背景色为 红色" id="b9"/>
$("#b9").click(function () {
$(":header").css("backgroundColor","pink");
});
});
</script>
</head>
<body>
<input type="button" value="保存" class="mini" name="ok" class="mini" />
<input type="button" value=" 改变第一个 div 元素的背景色为 红色" id="b1"/>
<input type="button" value=" 改变最后一个 div 元素的背景色为 红色" id="b2"/>
<input type="button" value=" 改变class不为 one 的所有 div 元素的背景色为 红色" id="b3"/>
<input type="button" value=" 改变索引值为偶数的 div 元素的背景色为 红色" id="b4"/>
<input type="button" value=" 改变索引值为奇数的 div 元素的背景色为 红色" id="b5"/>
<input type="button" value=" 改变索引值为大于 3 的 div 元素的背景色为 红色" id="b6"/>
<input type="button" value=" 改变索引值为等于 3 的 div 元素的背景色为 红色" id="b7"/>
<input type="button" value=" 改变索引值为小于 3 的 div 元素的背景色为 红色" id="b8"/>
<input type="button" value=" 改变所有的标题元素的背景色为 红色" id="b9"/>
<h1>有一种奇迹叫坚持</h1>
<h2>自信源于努力</h2>
<div id="one">
id为one
</div>
<div id="two" class="mini" >
id为two class是 mini
<div class="mini" >class是 mini</div>
</div>
<div class="one" >
class是 one
<div class="mini" >class是 mini</div>
<div class="mini" >class是 mini</div>
</div>
<div class="one" >
class是 one
<div class="mini01" >class是 mini01</div>
<div class="mini" >class是 mini</div>
</div>
</body>
</html>
7.4.2.5 表单过滤选择器
1. 可用元素选择器
语法: :enabled 获得可用元素
2. 不可用元素选择器
语法: :disabled 获得不可用元素
3. 选中选择器
语法: :checked 获得单选/复选框选中的元素
4. 选中选择器
语法: :selected 获得下拉框选中的元素
5.示例代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>表单属性过滤选择器</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="../js/jquery-3.3.1.min.js"></script>
<style type="text/css">
div,span{
width: 180px;
height: 180px;
margin: 20px;
background: #9999CC;
border: #000 1px solid;
float:left;
font-size: 17px;
font-family:Roman;
}
div .mini{
width: 50px;
height: 50px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
div .mini01{
width: 50px;
height: 50px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
#job{
margin: 20px;
}
#edu{
margin-top:-70px;
}
</style>
<script type="text/javascript">
$(function () {
// <input type="button" value=" 利用 jQuery 对象的 val() 方法改变表单内可用 <input> 元素的值" id="b1"/>
$("#b1").click(function () {
$("input[type='text']:enabled").val("aaa");
});
// <input type="button" value=" 利用 jQuery 对象的 val() 方法改变表单内不可用 <input> 元素的值" id="b2"/>
$("#b2").click(function () {
$("input[type='text']:disabled").val("aaa");
});
// <input type="button" value=" 利用 jQuery 对象的 length 属性获取复选框选中的个数" id="b3"/>
$("#b3").click(function () {
alert($("input[type='checkbox']:checked").length);
});
// <input type="button" value=" 利用 jQuery 对象的 length 属性获取下拉框选中的个数" id="b4"/>
$("#b4").click(function () {
alert($("#job > option:selected").length);
});
});
</script>
</head>
<body>
<input type="button" value="保存" class="mini" name="ok" class="mini" />
<input type="button" value=" 利用 jQuery 对象的 val() 方法改变表单内可用 <input> 元素的值" id="b1"/>
<input type="button" value=" 利用 jQuery 对象的 val() 方法改变表单内不可用 <input> 元素的值" id="b2"/>
<input type="button" value=" 利用 jQuery 对象的 length 属性获取复选框选中的个数" id="b3"/>
<input type="button" value=" 利用 jQuery 对象的 length 属性获取下拉框选中的个数" id="b4"/>
<br><br>
<input type="text" value="不可用值1" disabled="disabled">
<input type="text" value="可用值1" >
<input type="text" value="不可用值2" disabled="disabled">
<input type="text" value="可用值2" >
<br><br>
<input type="checkbox" name="items" value="美容" >美容
<input type="checkbox" name="items" value="IT" >IT
<input type="checkbox" name="items" value="金融" >金融
<input type="checkbox" name="items" value="管理" >管理
<br><br>
<input type="radio" name="sex" value="男" >男
<input type="radio" name="sex" value="女" >女
<br><br>
<select name="job" id="job" multiple="multiple" size=4>
<option>程序员</option>
<option>中级程序员</option>
<option>高级程序员</option>
<option>系统分析师</option>
</select>
<select name="edu" id="edu">
<option>本科</option>
<option>博士</option>
<option>硕士</option>
<option>大专</option>
</select>
<br/>
<div id="two" class="mini" >
id为two class是 mini div
<div class="mini" >class是 mini</div>
</div>
<div class="one" >
class是 one
<div class="mini" >class是 mini</div>
<div class="mini" >class是 mini</div>
</div>
<div class="one" >
class是 one
<div class="mini01" >class是 mini01</div>
<div class="mini" >class是 mini</div>
</div>
</body>
</html>
7.5 JQuery的DOM操作
7.5.1 内容操作
1. html(): 获取/设置元素的标签体内容 <a><font>内容</font></a> --> <font>内容</font>
2. text(): 获取/设置元素的标签体纯文本内容 <a><font>内容</font></a> --> 内容
3. val(): 获取/设置元素的value属性值
4.代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="../js/jquery-3.3.1.min.js"></script>
<script>
$(function () {
// 获取myinput 的value值
//var value = $("#myinput").val();
//alert(value);
//$("#myinput").val("李四");
// 获取mydiv的标签体内容
//var html = $("#mydiv").html();
//alert(html);
//$("#mydiv").html("<p>aaaa</p>");
// 获取mydiv文本内容
//var text = $("#mydiv").text();
//alert(text);
$("#mydiv").text("bbb");
});
</script>
</head>
<body>
<input id="myinput" type="text" name="username" value="张三" /><br />
<div id="mydiv"><p><a href="#">标题标签</a></p></div>
</body>
</html>
7.5.2 属性操作
7.5.2.1 通用属性操作
1. 通用属性操作
1. attr(): 获取/设置元素的属性
2. removeAttr():删除属性
3. prop():获取/设置元素的属性
4. removeProp():删除属性
* attr和prop区别?
1. 如果操作的是元素的固有属性,则建议使用prop
2. 如果操作的是元素自定义的属性,则建议使用attr
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>获取属性</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="../js/jquery-3.3.1.min.js"></script>
<style type="text/css">
div,span{
width: 140px;
height: 140px;
margin: 20px;
background: #9999CC;
border: #000 1px solid;
float:left;
font-size: 17px;
font-family:Roman;
}
div.mini{
width: 30px;
height: 30px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
div.visible{
display:none;
}
</style>
<script type="text/javascript">
$(function () {
//获取北京节点的name属性值
var name = $("#bj").attr("name");
//alert(name);
//设置北京节点的name属性的值为dabeijing
$("#bj").attr("name","dabeijing");
//新增北京节点的discription属性 属性值是didu
$("#bj").attr("discription","didu");
//删除北京节点的name属性并检验name属性是否存在
$("#bj").removeAttr("name");
//获得hobby的的选中状态
var checked = $("#hobby").prop("checked");
alert(checked);
//var checked = $("#hobby").attr("checked"); //获取不到,弹出undefined
});
</script>
</head>
<body>
<ul>
<li id="bj" name="beijing" xxx="yyy">北京</li>
<li id="tj" name="tianjin">天津</li>
</ul>
<input type="checkbox" id="hobby"/>
</body>
</html>
7.5.2.2 对class属性操作
2. 对class属性操作
1. addClass():添加class属性值
2. removeClass():删除class属性值
3. toggleClass():切换class属性
* toggleClass("one"):
* 判断如果元素对象上存在class="one",则将属性值one删除掉。 如果元素对象上不存在class="one",则添加
4. css():
5.代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>样式操作</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="../js/jquery-3.3.1.min.js"></script>
<style type="text/css">
.one{
width: 200px;
height: 140px;
margin: 20px;
background: red;
border: #000 1px solid;
float:left;
font-size: 17px;
font-family:Roman;
}
div,span{
width: 140px;
height: 140px;
margin: 20px;
background: #9999CC;
border: #000 1px solid;
float:left;
font-size: 17px;
font-family:Roman;
}
div .mini{
width: 40px;
height: 40px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
div .mini01{
width: 40px;
height: 40px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
/*待用的样式*/
.second{
width: 300px;
height: 340px;
margin: 20px;
background: yellow;
border: pink 3px dotted;
float:left;
font-size: 22px;
font-family:Roman;
}
</style>
<script type="text/javascript">
$(function () {
//<input type="button" value="采用属性增加样式(改变id=one的样式)" id="b1"/>
$("#b1").click(function () {
$("#one").prop("class","second");
});
//<input type="button" value=" addClass" id="b2"/>
$("#b2").click(function () {
$("#one").addClass("second");
});
//<input type="button" value="removeClass" id="b3"/>
$("#b3").click(function () {
$("#one").removeClass("second");
});
//<input type="button" value=" 切换样式" id="b4"/>
$("#b4").click(function () {
$("#one").toggleClass("second");
});
//<input type="button" value=" 通过css()获得id为one背景颜色" id="b5"/>
$("#b5").click(function () {
var backgroundColor = $("#one").css("backgroundColor");
alert(backgroundColor);
});
//<input type="button" value=" 通过css()设置id为one背景颜色为绿色" id="b6"/>
$("#b6").click(function () {
$("#one").css("backgroundColor","green");
});
});
</script>
</head>
<body>
<input type="button" value="保存" class="mini" name="ok" class="mini" />
<input type="button" value="采用属性增加样式(改变id=one的样式)" id="b1"/>
<input type="button" value=" addClass" id="b2"/>
<input type="button" value="removeClass" id="b3"/>
<input type="button" value=" 切换样式" id="b4"/>
<input type="button" value=" 通过css()获得id为one背景颜色" id="b5"/>
<input type="button" value=" 通过css()设置id为one背景颜色为绿色" id="b6"/>
<h1>有一种奇迹叫坚持</h1>
<h2>自信源于努力</h2>
<div id="one">
id为one
</div>
<div id="two" class="mini" >
id为two class是 mini
<div class="mini" >class是 mini</div>
</div>
<div class="one" >
class是 one
<div class="mini" >class是 mini</div>
<div class="mini" >class是 mini</div>
</div>
<div class="one" >
class是 one
<div class="mini01" >class是 mini01</div>
<div class="mini" >class是 mini</div>
</div>
<span class="spanone"> span
</span>
</body>
</html>
7.5.3 CRUD操作
1. append():父元素将子元素追加到末尾
对象1.append(对象2): 将对象2添加到对象1元素内部,并且在末尾
2. prepend():父元素将子元素追加到开头
对象1.prepend(对象2):将对象2添加到对象1元素内部,并且在开头
3. appendTo():
对象1.appendTo(对象2):将对象1添加到对象2内部,并且在末尾
4. prependTo():
对象1.prependTo(对象2):将对象1添加到对象2内部,并且在开头
5. after():添加元素到元素后边
对象1.after(对象2): 将对象2添加到对象1后边。对象1和对象2是兄弟关系
6. before():添加元素到元素前边
对象1.before(对象2): 将对象2添加到对象1前边。对象1和对象2是兄弟关系
7. insertAfter()
对象1.insertAfter(对象2):将对象2添加到对象1后边。对象1和对象2是兄弟关系
8. insertBefore()
对象1.insertBefore(对象2): 将对象2添加到对象1前边。对象1和对象2是兄弟关系
代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>内部插入脚本</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="../js/jquery-3.3.1.min.js"></script>
<style type="text/css">
div,span{
width: 140px;
height: 140px;
margin: 20px;
background: #9999CC;
border: #000 1px solid;
float:left;
font-size: 17px;
font-family:Roman;
}
div .mini{
width: 30px;
height: 30px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
div.visible{
display:none;
}
</style>
<script type="text/javascript">
$(function () {
// <input type="button" value="将反恐放置到city的后面" id="b1"/>
$("#b1").click(function () {
//append
//$("#city").append($("#fk"));
//appendTo
$("#fk").appendTo($("#city"));
});
// <input type="button" value="将反恐放置到city的最前面" id="b2"/>
$("#b2").click(function () {
//prepend
//$("#city").prepend($("#fk"));
//prependTo
$("#fk").prependTo($("#city"));
});
// <input type="button" value="将反恐插入到天津后面" id="b3"/>
$("#b3").click(function () {
//after
//$("#tj").after($("#fk"));
//insertAfter
$("#fk").insertAfter($("#tj"));
});
// <input type="button" value="将反恐插入到天津前面" id="b4"/>
$("#b4").click(function () {
//before
//$("#tj").before($("#fk"));
//insertBefore
$("#fk").insertBefore($("#tj"));
});
});
</script>
</head>
<body>
<input type="button" value="将反恐放置到city的后面" id="b1"/>
<input type="button" value="将反恐放置到city的最前面" id="b2"/>
<input type="button" value="将反恐插入到天津后面" id="b3"/>
<input type="button" value="将反恐插入到天津前面" id="b4"/>
<ul id="city">
<li id="bj" name="beijing">北京</li>
<li id="tj" name="tianjin">天津</li>
<li id="cq" name="chongqing">重庆</li>
</ul>
<ul id="love">
<li id="fk" name="fankong">反恐</li>
<li id="xj" name="xingji">星际</li>
</ul>
<div id="foo1">Hello1</div>
</body>
</html>
9. remove():移除元素
对象.remove():将对象删除掉
10. empty():清空元素的所有后代元素。
对象.empty():将对象的后代元素全部清空,但是保留当前对象以及其属性节点
代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>删除节点</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="../js/jquery-3.3.1.min.js"></script>
<style type="text/css">
div,span{
width: 140px;
height: 140px;
margin: 20px;
background: #9999CC;
border: #000 1px solid;
float:left;
font-size: 17px;
font-family:Roman;
}
div.mini{
width: 30px;
height: 30px;
background: #CC66FF;
border: #000 1px solid;
font-size: 12px;
font-family:Roman;
}
div.visible{
display:none;
}
</style>
<script type="text/javascript">
$(function () {
// <input type="button" value="删除<li id='bj' name='beijing'>北京</li>" id="b1"/>
$("#b1").click(function () {
$("#bj").remove();
});
// <input type="button" value="删除city所有的li节点 清空元素中的所有后代节点(不包含属性节点)" id="b2"/>
$("#b2").click(function () {
$("#city").empty();
});
});
</script>
</head>
<body>
<input type="button" value="删除<li id='bj' name='beijing'>北京</li>" id="b1"/>
<input type="button" value="删除所有的子节点 清空元素中的所有后代节点(不包含属性节点)" id="b2"/>
<ul id="city">
<li id="bj" name="beijing">北京</li>
<li id="tj" name="tianjin">天津</li>
<li id="cq" name="chongqing">重庆</li>
</ul>
<p class="hello">Hello</p> how are <p>you?</p>
</body>
</html>
7.6 JQuery 案例
7.6.1 案例一:隔行换色
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="../../js/jquery-3.3.1.min.js"></script>
<script>
//需求:将数据行的奇数行背景色设置为 pink,偶数行背景色设置为 yellow
$(function () {
//1. 获取数据行的奇数行的tr,设置背景色为pink
$("tr:gt(1):odd").css("backgroundColor","pink");
//2. 获取数据行的偶数行的tr,设置背景色为yellow
$("tr:gt(1):even").css("backgroundColor","yellow");
});
</script>
</head>
<body>
<table id="tab1" border="1" width="800" align="center" >
<tr>
<td colspan="5"><input type="button" value="删除"></td>
</tr>
<tr style="background-color: #999999;">
<th><input type="checkbox"></th>
<th>分类ID</th>
<th>分类名称</th>
<th>分类描述</th>
<th>操作</th>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>0</td>
<td>手机数码</td>
<td>手机数码类商品</td>
<td><a href="">修改</a>|<a href="">删除</a></td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>1</td>
<td>电脑办公</td>
<td>电脑办公类商品</td>
<td><a href="">修改</a>|<a href="">删除</a></td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>2</td>
<td>鞋靴箱包</td>
<td>鞋靴箱包类商品</td>
<td><a href="">修改</a>|<a href="">删除</a></td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>3</td>
<td>家居饰品</td>
<td>家居饰品类商品</td>
<td><a href="">修改</a>|<a href="">删除</a></td>
</tr>
</table>
</body>
</html>
7.6.2 案例二:全选和全不选
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="../../js/jquery-3.3.1.min.js"></script>
<script>
//分析:需要保证下边的选中状态和第一个复选框的选中状态一致即可
function selectAll(obj){
//获取下边的复选框
$(".itemSelect").prop("checked",obj.checked);
}
</script>
</head>
<body>
<table id="tab1" border="1" width="800" align="center" >
<tr>
<td colspan="5"><input type="button" value="删除"></td>
</tr>
<tr>
<th><input type="checkbox" οnclick="selectAll(this)" ></th>
<th>分类ID</th>
<th>分类名称</th>
<th>分类描述</th>
<th>操作</th>
</tr>
<tr>
<td><input type="checkbox" class="itemSelect"></td>
<td>1</td>
<td>手机数码</td>
<td>手机数码类商品</td>
<td><a href="">修改</a>|<a href="">删除</a></td>
</tr>
<tr>
<td><input type="checkbox" class="itemSelect"></td>
<td>2</td>
<td>电脑办公</td>
<td>电脑办公类商品</td>
<td><a href="">修改</a>|<a href="">删除</a></td>
</tr>
<tr>
<td><input type="checkbox" class="itemSelect"></td>
<td>3</td>
<td>鞋靴箱包</td>
<td>鞋靴箱包类商品</td>
<td><a href="">修改</a>|<a href="">删除</a></td>
</tr>
<tr>
<td><input type="checkbox" class="itemSelect"></td>
<td>4</td>
<td>家居饰品</td>
<td>家居饰品类商品</td>
<td><a href="">修改</a>|<a href="">删除</a></td>
</tr>
</table>
</body>
</html>
7.6.3 案例三:QQ表情选择
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>QQ表情选择</title>
<script src="../../js/jquery-3.3.1.min.js"></script>
<style type="text/css">
*{margin: 0;padding: 0;list-style: none;}
.emoji{margin:50px;}
ul{overflow: hidden;}
li{float: left;width: 48px;height: 48px;cursor: pointer;}
.emoji img{ cursor: pointer; }
</style>
<script>
//需求:点击qq表情,将其追加到发言框中
$(function () {
//1.给img图片添加onclick事件
$("ul img").click(function(){
//2.追加到p标签中即可。
$(".word").append($(this).clone());
});
});
</script>
</head>
<body>
<div class="emoji">
<ul>
<li><img src="img/01.gif" height="22" width="22" alt="" /></li>
<li><img src="img/02.gif" height="22" width="22" alt="" /></li>
<li><img src="img/03.gif" height="22" width="22" alt="" /></li>
<li><img src="img/04.gif" height="22" width="22" alt="" /></li>
<li><img src="img/05.gif" height="22" width="22" alt="" /></li>
<li><img src="img/06.gif" height="22" width="22" alt="" /></li>
<li><img src="img/07.gif" height="22" width="22" alt="" /></li>
<li><img src="img/08.gif" height="22" width="22" alt="" /></li>
<li><img src="img/09.gif" height="22" width="22" alt="" /></li>
<li><img src="img/10.gif" height="22" width="22" alt="" /></li>
<li><img src="img/11.gif" height="22" width="22" alt="" /></li>
<li><img src="img/12.gif" height="22" width="22" alt="" /></li>
</ul>
<p class="word">
<strong>请发言:</strong>
<img src="img/12.gif" height="22" width="22" alt="" />
</p>
</div>
</body>
</html>
7.6.4 案例四:下拉列表选中条目左右移动

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="../../js/jquery-3.3.1.min.js"></script>
<style>
#leftName , #btn,#rightName{
float: left;
width: 100px;
height: 300px;
}
#toRight,#toLeft{
margin-top:100px ;
margin-left:30px;
width: 50px;
}
.border{
height: 500px;
padding: 100px;
}
</style>
<script>
//需求:实现下拉列表选中条目左右选择功能
$(function () {
//toRight
$("#toRight").click(function () {
//获取右边的下拉列表对象,append(左边下拉列表选中的option)
$("#rightName").append($("#leftName > option:selected"));
});
//toLeft
$("#toLeft").click(function () {
//appendTo 获取右边选中的option,将其移动到左边下拉列表中
$("#rightName > option:selected").appendTo($("#leftName"));
});
});
</script>
</head>
<body>
<div class="border">
<select id="leftName" multiple="multiple">
<option>张三</option>
<option>李四</option>
<option>王五</option>
<option>赵六</option>
</select>
<div id="btn">
<input type="button" id="toRight" value="-->"><br>
<input type="button" id="toLeft" value="<--">
</div>
<select id="rightName" multiple="multiple">
<option>钱七</option>
</select>
</div>
</body>
</html>
8. JQuery 高级
8.1 动画——三种方式显示和隐藏元素
1. 动画
1. 三种方式显示和隐藏元素
1. 默认显示和隐藏方式
1. show([speed,[easing],[fn]])
1. 参数:
1. speed:动画的速度。三个预定义的值("slow","normal", "fast")或表示动画时长的毫秒数值(如:1000)
2. easing:用来指定切换效果,默认是"swing",可用参数"linear"
* swing:动画执行时效果是 先慢,中间快,最后又慢
* linear:动画执行时速度是匀速的
3. fn:在动画完成时执行的函数,每个元素执行一次。
2. hide([speed,[easing],[fn]])
3. toggle([speed],[easing],[fn])
2. 滑动显示和隐藏方式
1. slideDown([speed],[easing],[fn])
2. slideUp([speed,[easing],[fn]])
3. slideToggle([speed],[easing],[fn])
3. 淡入淡出显示和隐藏方式
1. fadeIn([speed],[easing],[fn])
2. fadeOut([speed],[easing],[fn])
3. fadeToggle([speed,[easing],[fn]])
2. 遍历
1. js的遍历方式
* for(初始化值;循环结束条件;步长)
2. JQuery的遍历方式
1. JQuery对象.each(callback)
1. 语法:
jquery对象.each(function(index,element){});
* index:就是元素在集合中的索引
* element:就是集合中的每一个元素对象
* this:集合中的每一个元素对象
2. 回调函数返回值:
* true:如果当前function返回为false,则结束循环(break)。
* false:如果当前function返回为true,则结束本次循环,继续下次循环(continue)
2. $.each(object, [callback])
3. for..of: jquery 3.0 版本之后提供的方式
for(元素对象 of 容器对象)
3. 事件绑定
1. jquery标准的绑定方式
* jq对象.事件方法(回调函数);
* 注:如果调用事件方法,不传递回调函数,则会触发浏览器默认行为。
* 表单对象.submit();//让表单提交
2. on绑定事件/off解除绑定
* jq对象.on("事件名称",回调函数)
* jq对象.off("事件名称")
* 如果off方法不传递任何参数,则将组件上的所有事件全部解绑
3. 事件切换:toggle
* jq对象.toggle(fn1,fn2...)
* 当单击jq对象对应的组件后,会执行fn1.第二次点击会执行fn2.....
* 注意:1.9版本 .toggle() 方法删除,jQuery Migrate(迁移)插件可以恢复此功能。
4. 案例 1. 广告显示和隐藏广告的自动显示与隐藏 <!--引入jquery--> <script type="text/javascript" src="../js/jquery-3.3.1.min.js"></script> <script> /* 需求: 1. 当页面加载完,3秒后。自动显示广告 2. 广告显示5秒后,自动消失。 分析: 1. 使用定时器来完成。setTimeout (执行一次定时器) 2. 分析发现JQuery的显示和隐藏动画效果其实就是控制display 3. 使用 show/hide方法来完成广告的显示 */ //入口函数,在页面加载完成之后,定义定时器,调用这两个方法 $(function () { //定义定时器,调用adShow方法 3秒后执行一次 setTimeout(adShow,3000); //定义定时器,调用adHide方法,8秒后执行一次 setTimeout(adHide,8000); }); //显示广告 function adShow() { //获取广告div,调用显示方法 $("#ad").show("slow"); } //隐藏广告 function adHide() { //获取广告div,调用隐藏方法 $("#ad").hide("slow"); }
<!-- 下方正文部分 -->
<div id="content">
正文部分
</div>
</div>
</body>
</html>
2. 抽奖
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jquery案例之抽奖</title>
<script type="text/javascript" src="../js/jquery-3.3.1.min.js"></script>
<script language='javascript' type='text/javascript'>
/*
分析:
1. 给开始按钮绑定单击事件
1.1 定义循环定时器
1.2 切换小相框的src属性
* 定义数组,存放图片资源路径
* 生成随机数。数组索引
2. 给结束按钮绑定单击事件
1.1 停止定时器
1.2 给大相框设置src属性
*/
var imgs = ["../img/man00.jpg",
"../img/man01.jpg",
"../img/man02.jpg",
"../img/man03.jpg",
"../img/man04.jpg",
"../img/man05.jpg",
"../img/man06.jpg",
];
var startId;//开始定时器的id
var index;//随机角标
$(function () {
//处理按钮是否可以使用的效果
$("#startID").prop("disabled",false);
$("#stopID").prop("disabled",true);
//1. 给开始按钮绑定单击事件
$("#startID").click(function () {
// 1.1 定义循环定时器 20毫秒执行一次
startId = setInterval(function () {
//处理按钮是否可以使用的效果
$("#startID").prop("disabled",true);
$("#stopID").prop("disabled",false);
//1.2生成随机角标 0-6
index = Math.floor(Math.random() * 7);//0.000--0.999 --> * 7 --> 0.0-----6.9999
//1.3设置小相框的src属性
$("#img1ID").prop("src",imgs[index]);
},20);
});
//2. 给结束按钮绑定单击事件
$("#stopID").click(function () {
//处理按钮是否可以使用的效果
$("#startID").prop("disabled",false);
$("#stopID").prop("disabled",true);
// 1.1 停止定时器
clearInterval(startId);
// 1.2 给大相框设置src属性
$("#img2ID").prop("src",imgs[index]).hide();
//显示1秒之后
$("#img2ID").show(1000);
});
});
</head>
<body>
<!-- 小像框 -->
<div style="border-style:dotted;width:160px;height:100px">
<img id="img1ID" src="../img/man00.jpg" style="width:160px;height:100px"/>
</div>
<!-- 大像框 -->
<div
style="border-style:double;width:800px;height:500px;position:absolute;left:500px;top:10px">
<img id="img2ID" src="../img/man00.jpg" width="800px" height="500px"/>
</div>
<!-- 开始按钮 -->
<input
id="startID"
type="button"
value="点击开始"
style="width:150px;height:150px;font-size:22px">
<!-- 停止按钮 -->
<input
id="stopID"
type="button"
value="点击停止"
style="width:150px;height:150px;font-size:22px">
</body>
</html>
5. 插件:增强JQuery的功能
1. 实现方式:
1. $.fn.extend(object)
* 增强通过Jquery获取的对象的功能 $("#id")
2. $.extend(object)
* 增强JQeury对象自身的功能 $/jQuery
9. AJAX
9.1 AJAX概念
1. 概念: ASynchronous JavaScript And XML 异步的JavaScript 和 XML 2. 异步和同步:客户端和服务器端相互通信的基础上 * 客户端必须等待服务器端的响应。在等待的期间客户端不能做其他操作。 * 客户端不需要等待服务器端的响应。在服务器处理请求的过程中,客户端可以进行其他的操作。 Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术 [1] 通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。 这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。 传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。 提升用户的体验
异步和同步

9.2 AJAX 实现方式
9.2.1 JS实现方式(了解)
1. 原生的JS实现方式(了解)
//1.创建核心对象
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
//2. 建立连接
/*
参数:
1. 请求方式:GET、POST
* get方式,请求参数在URL后边拼接。send方法为空参
* post方式,请求参数在send方法中定义
2. 请求的URL:
3. 同步或异步请求:true(异步)或 false(同步)
*/
xmlhttp.open("GET","ajaxServlet?username=tom",true);
//3.发送请求
xmlhttp.send();
//4.接受并处理来自服务器的响应结果
//获取方式 :xmlhttp.responseText
//什么时候获取?当服务器响应成功后再获取
//当xmlhttp对象的就绪状态改变时,触发事件onreadystatechange。
xmlhttp.onreadystatechange=function()
{
//判断readyState就绪状态是否为4,判断status响应状态码是否为200
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
//获取服务器的响应结果
var responseText = xmlhttp.responseText;
alert(responseText);
}
}
9.2.2 JQeury实现方式
2. JQeury实现方式
1. $.ajax()
* 语法:$.ajax({键值对});
//使用$.ajax()发送异步请求
$.ajax({
url:"ajaxServlet1111" , // 请求路径
type:"POST" , //请求方式
//data: "username=jack&age=23",//请求参数
data:{"username":"jack","age":23},
success:function (data) {
alert(data);
},//响应成功后的回调函数
error:function () {
alert("出错啦...")
},//表示如果请求响应出现错误,会执行的回调函数
dataType:"text"//设置接受到的响应数据的格式
});
2. $.get():发送get请求
* 语法:$.get(url, [data], [callback], [type])
* 参数:
* url:请求路径
* data:请求参数
* callback:回调函数
* type:响应结果的类型
3. $.post():发送post请求
* 语法:$.post(url, [data], [callback], [type])
* 参数:
* url:请求路径
* data:请求参数
* callback:回调函数
* type:响应结果的类型
10. Maven
11. JSON
11.1 JSON概念
1. 概念: JavaScript Object Notation JavaScript对象表示法
Person p = new Person();
p.setName("张三");
p.setAge(23);
p.setGender("男");
var p = {"name":"张三","age":23,"gender":"男"};
json现在多用于存储和交换文本信息的语法
进行数据的传输
JSON 比 XML 更小、更快,更易解析。
11.2 JSON基本语法
2.1 语法基本规则
2.1.1 数据在键/值对中:json数据是由键值对构成的
1.键用引号(单双都行)引起来,也可以不使用引号
2.值的取值类型:
1. 数字(整数或浮点数)
2. 字符串(在双引号中)
3. 逻辑值(true 或 false)
4. 数组(在方括号中) {"persons":[{},{}]}
5. 对象(在花括号中) {"address":{"province":"陕西"....}}
6. null
2.1.2 数据由逗号分隔:多个键值对由逗号分隔
3.花括号保存对象:使用{}定义json 格式
4.方括号保存数组:[]
5.代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
//1.定义基本格式
var person = {"name": "张三", age: 23, 'gender': true};
//获取name的值
//var name = person.name;
var name = person["name"];
// alert(name);
//alert(person);
//2.嵌套格式 {}———> []
var persons = {
"persons": [
{"name": "张三", "age": 23, "gender": true},
{"name": "李四", "age": 24, "gender": true},
{"name": "王五", "age": 25, "gender": false}
]
};
// alert(persons);
//获取王五值
var name1 = persons.persons[2].name;
// alert(name1);
//2.嵌套格式 []———> {}
var ps = [{"name": "张三", "age": 23, "gender": true},
{"name": "李四", "age": 24, "gender": true},
{"name": "王五", "age": 25, "gender": false}];
//获取李四值
//alert(ps);
alert(ps[1].name);
</script>
</head>
<body>
</body>
</html>
11.3 JSON获取数据
2. 获取数据:
1. json对象.键名
2. json对象["键名"]
3. 数组对象[索引]
4. 遍历
//1.定义基本格式
var person = {"name": "张三", age: 23, 'gender': true};
var ps = [{"name": "张三", "age": 23, "gender": true},
{"name": "李四", "age": 24, "gender": true},
{"name": "王五", "age": 25, "gender": false}];
//获取person对象中所有的键和值
//for in 循环
/* for(var key in person){
//alert(key + ":" + person.key);这样的方式获取不行。因为相当于 person."name"
alert(key+":"+person[key]);
}*/
//获取ps中的所有值
for (var i = 0; i < ps.length; i++) {
var p = ps[i];
for(var key in p){
alert(key+":"+p[key]);
}
}
11.3 JSON数据和Java对象相互转换
11.3.1 JSON解析器
常见的解析器:Jsonlib,Gson,fastjson,jackson(SpringMVC内置的解析器)

11.3.2 JSON转为Java对象
1. JSON转为Java对象 1. 导入jackson的相关jar包 2. 创建Jackson核心对象 ObjectMapper 3. 调用ObjectMapper的相关方法进行转换 1. readValue(json字符串数据,Class)
11.3.3 Java对象转换JSON
2. Java对象转换JSON 2.1 jackson的使用步骤: 1. 导入jackson的相关jar包 (jackson-annotations-2.2.3.jar\jackson-core-2.2.3.jar\jackson-databind-2.2.3.jar) 2. 创建Jackson核心对象 ObjectMapper 3. 调用ObjectMapper的相关方法进行转换
3. 转换方法:
writeValue(参数1,obj):
参数1:
File:将obj对象转换为JSON字符串,并保存到指定的文件中
Writer:将obj对象转换为JSON字符串,并将json数据填充到字符输出流中
OutputStream:将obj对象转换为JSON字符串,并将json数据填充到字节输出流中
writeValueAsString(obj):将对象转为json字符串
4. 注解:
1. @JsonIgnore:排除属性——被排除属性的键值对就不会被转成json字符串
2. @JsonFormat:属性值得格式化
@JsonFormat(pattern = "yyyy-MM-dd")
5. 复杂java对象转换:
1. List:数组
2. Map:对象格式一致
11.3.4 代码——Java对象&JSON 相互转换
1.Person类(Java对象)
package cn.itcast.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
public class Person {
private String name;
private int age ;
private String gender;
//@JsonIgnore // 忽略该属性
@JsonFormat(pattern = "yyyy-MM-dd")
private Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
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;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
2.JacksonTest测试类:
package cn.itcast.test;
import cn.itcast.domain.Person;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import java.io.FileWriter;
import java.util.*;
public class JacksonTest {
//Java对象转为JSON字符串
@Test
public void test1() throws Exception {
//1.创建Person对象
Person p = new Person();
p.setName("张三");
p.setAge(23);
p.setGender("男");
//2.创建Jackson的核心对象 ObjectMapper
ObjectMapper mapper = new ObjectMapper();
//3.转换
/*
转换方法:
writeValue(参数1,obj):
参数1:
File:将obj对象转换为JSON字符串,并保存到指定的文件中
Writer:将obj对象转换为JSON字符串,并将json数据填充到字符输出流中
OutputStream:将obj对象转换为JSON字符串,并将json数据填充到字节输出流中
writeValueAsString(obj):将对象转为json字符串
*/
String json = mapper.writeValueAsString(p);
//{"name":"张三","age":23,"gender":"男"}
//System.out.println(json);//{"name":"张三","age":23,"gender":"男"}
//writeValue,将数据写到d://a.txt文件中
//mapper.writeValue(new File("d://a.txt"),p);
//writeValue.将数据关联到Writer中
mapper.writeValue(new FileWriter("d://b.txt"),p);
}
@Test
public void test2() throws Exception {
//1.创建Person对象
Person p = new Person();
p.setName("张三");
p.setAge(23);
p.setGender("男");
p.setBirthday(new Date());
//2.转换
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(p);
System.out.println(json);//{"name":"张三","age":23,"gender":"男","birthday":1530958029263}
//{"name":"张三","age":23,"gender":"男","birthday":"2018-07-07"}
}
@Test
public void test3() throws Exception {
//1.创建Person对象
Person p = new Person();
p.setName("张三");
p.setAge(23);
p.setGender("男");
p.setBirthday(new Date());
Person p1 = new Person();
p1.setName("张三");
p1.setAge(23);
p1.setGender("男");
p1.setBirthday(new Date());
Person p2 = new Person();
p2.setName("张三");
p2.setAge(23);
p2.setGender("男");
p2.setBirthday(new Date());
//创建List集合
List<Person> ps = new ArrayList<Person>();
ps.add(p);
ps.add(p1);
ps.add(p2);
//2.转换
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(ps);
// [{},{},{}]
//[{"name":"张三","age":23,"gender":"男","birthday":"2018-07-07"},{"name":"张三","age":23,"gender":"男","birthday":"2018-07-07"},{"name":"张三","age":23,"gender":"男","birthday":"2018-07-07"}]
System.out.println(json);
}
@Test
public void test4() throws Exception {
//1.创建map对象
Map<String,Object> map = new HashMap<String,Object>();
map.put("name","张三");
map.put("age",23);
map.put("gender","男");
//2.转换
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(map);
//{"name":"张三","age":23,"gender":"男"}
System.out.println(json);//{"gender":"男","name":"张三","age":23}
}
//演示 JSON字符串转为Java对象
@Test
public void test5() throws Exception {
//1.初始化JSON字符串(转义字符\用来转化双引号)
String json = "{\"gender\":\"男\",\"name\":\"张三\",\"age\":23}";
//2.创建ObjectMapper对象
ObjectMapper mapper = new ObjectMapper();
//3.转换为Java对象 Person对象
Person person = mapper.readValue(json, Person.class);
System.out.println(person);
}
}
11.4 案例——校验用户名是否存在
校验用户名是否存在
1. 服务器响应的数据,在客户端使用时,要想当做json数据格式使用。有两种解决方案:
1. $.get(type):将最后一个参数type指定为"json"
2. 在服务器端设置MIME类型
response.setContentType("application/json;charset=utf-8");
12. Redis
12.1 NoSQL简介
12.1.1 NoSQL概念
1. 概念: redis是一款高性能的NOSQL系列的非关系型数据库 1.1.什么是NOSQL NoSQL(NoSQL = Not Only SQL),意即“不仅仅是SQL”,是一项全新的数据库理念,泛指非关系型的数据库。 随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。
12.1.2 NOSQL和关系型数据库比较
1.1.1. NOSQL和关系型数据库比较 NOSQL优点: 1)成本:nosql数据库简单易部署,基本都是开源软件,不需要像使用oracle那样花费大量成本购买使用,相比关系型数据库价格便宜。 2)查询速度:nosql数据库将数据存储于缓存之中,关系型数据库将数据存储在硬盘中,自然查询速度远不及nosql数据库。 3)存储数据的格式:nosql的存储格式是key,value形式、文档形式、图片形式等等,所以可以存储基础类型以及对象或者是集合等各种格式,而数据库则只支持基础类型。 4)扩展性:关系型数据库有类似join这样的多表查询机制的限制导致扩展很艰难。 NOSQL缺点: 1)维护的工具和资料有限,因为nosql是属于新的技术,不能和关系型数据库10几年的技术同日而语。 2)不提供对sql的支持,如果不支持sql这样的工业标准,将产生一定用户的学习和使用成本。 3)不提供关系型数据库对事务的处理。
关系型数据库和非关系型数据库对比:

1.1.2. 非关系型数据库的优势: 1)性能NOSQL是基于键值对的,可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析,所以性能非常高。 2)可扩展性同样也是因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展。 1.1.3. 关系型数据库的优势: 1)复杂查询可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。 2)事务支持使得对于安全性能很高的数据访问要求得以实现。对于这两类数据库,对方的优势就是自己的弱势,反之亦然。 1.1.4. 总结 关系型数据库与NoSQL数据库并非对立而是互补的关系,即通常情况下使用关系型数据库,在适合使用NoSQL的时候使用NoSQL数据库, 让NoSQL数据库对关系型数据库的不足进行弥补。 一般会将数据存储在关系型数据库中,在nosql数据库中备份存储关系型数据库的数据
12.2 主流的NOSQL产品
1.2.主流的NOSQL产品
• 键值(Key-Value)存储数据库
相关产品: Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB
典型应用: 内容缓存,主要用于处理大量数据的高访问负载。
数据模型: 一系列键值对
优势: 快速查询
劣势: 存储的数据缺少结构化
• 列存储数据库
相关产品:Cassandra, HBase, Riak
典型应用:分布式的文件系统
数据模型:以列簇式存储,将同一列数据存在一起
优势:查找速度快,可扩展性强,更容易进行分布式扩展
劣势:功能相对局限
• 文档型数据库
相关产品:CouchDB、MongoDB
典型应用:Web应用(与Key-Value类似,Value是结构化的)
数据模型: 一系列键值对
优势:数据结构要求不严格
劣势: 查询性能不高,而且缺乏统一的查询语法
• 图形(Graph)数据库
相关数据库:Neo4J、InfoGrid、Infinite Graph
典型应用:社交网络
数据模型:图结构
优势:利用图结构相关算法。
劣势:需要对整个图做计算才能得出结果,不容易做分布式的集群方案。
12.3 Redis概念 & 应用场景 & 下载安装
1.3 什么是Redis
Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,官方提供测试数据,
50个并发执行100000个请求,读的速度是110000次/s,写的速度是81000次/s ,且Redis通过
提供多种键值数据类型来适应不同场景下的存储需求,目前为止Redis支持的键值数据类型如下:
1) 字符串类型 string
2) 哈希类型 hash
3) 列表类型 list
4) 集合类型 set
5) 有序集合类型 sortedset
1.3.1 redis的应用场景
• 缓存(数据查询、短连接、新闻内容、商品内容等等)
• 聊天室的在线好友列表
• 任务队列。(秒杀、抢购、12306等等)
• 应用排行榜
• 网站访问统计
• 数据过期处理(可以精确到毫秒
• 分布式集群架构中的session分离
2. 下载安装 1. 官网:https://redis.io 2. 中文网:http://www.redis.net.cn/ 3. 解压直接可以使用: * redis.windows.conf:配置文件 * redis-cli.exe:redis的客户端 * redis-server.exe:redis服务器端
12.4 redis的数据结构 & 命令操作
1. redis的数据结构: redis存储的是:key,value格式的数据,其中key都是字符串,value有5种不同的数据结构 value的数据结构: 1) 字符串类型 string 2) 哈希类型 hash : map格式 3) 列表类型 list : linkedlist格式。支持重复元素 4) 集合类型 set : 不允许重复元素 5) 有序集合类型 sortedset:不允许重复元素,且元素有顺序

2. 字符串类型 string 1. 存储: set key value 127.0.0.1:6379> set username zhangsan OK 2. 获取: get key 127.0.0.1:6379> get username "zhangsan" 3. 删除: del key 127.0.0.1:6379> del age (integer) 1 3. 哈希类型 hash 1. 存储: hset key field value 127.0.0.1:6379> hset myhash username lisi (integer) 1 127.0.0.1:6379> hset myhash password 123 (integer) 1 2. 获取: * hget key field: 获取指定的field对应的值 127.0.0.1:6379> hget myhash username "lisi" * hgetall key:获取所有的field和value 127.0.0.1:6379> hgetall myhash 1) "username" 2) "lisi" 3) "password" 4) "123" 3. 删除: hdel key field 127.0.0.1:6379> hdel myhash username (integer) 1 4. 列表类型 list:可以添加一个元素到列表的头部(左边)或者尾部(右边) 1. 添加: 1. lpush key value: 将元素加入列表左表 2. rpush key value:将元素加入列表右边 127.0.0.1:6379> lpush myList a (integer) 1 127.0.0.1:6379> lpush myList b (integer) 2 127.0.0.1:6379> rpush myList c (integer) 3 2. 获取: * lrange key start end :范围获取 127.0.0.1:6379> lrange myList 0 -1 1) "b" 2) "a" 3) "c" 3. 删除: * lpop key: 删除列表最左边的元素,并将元素返回 * rpop key: 删除列表最右边的元素,并将元素返回

5. 集合类型 set : 不允许重复元素 1. 存储:sadd key value 127.0.0.1:6379> sadd myset a (integer) 1 127.0.0.1:6379> sadd myset a (integer) 0 2. 获取:smembers key:获取set集合中所有元素 127.0.0.1:6379> smembers myset 1) "a" 3. 删除:srem key value:删除set集合中的某个元素 127.0.0.1:6379> srem myset a (integer) 1 6. 有序集合类型 sortedset:不允许重复元素,且元素有顺序.每个元素都会关联一个 double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。 1. 存储:zadd key score value 127.0.0.1:6379> zadd mysort 60 zhangsan (integer) 1 127.0.0.1:6379> zadd mysort 50 lisi (integer) 1 127.0.0.1:6379> zadd mysort 80 wangwu (integer) 1 2. 获取:zrange key start end [withscores] 127.0.0.1:6379> zrange mysort 0 -1 1) "lisi" 2) "zhangsan" 3) "wangwu" 127.0.0.1:6379> zrange mysort 0 -1 withscores 1) "zhangsan" 2) "60" 3) "wangwu" 4) "80" 5) "lisi" 6) "500" 3. 删除:zrem key value 127.0.0.1:6379> zrem mysort lisi (integer) 1 7. 通用命令 1. keys * : 查询所有的键 2. type key : 获取键对应的value的类型 3. del key:删除指定的key value
12.5 redis的持久化
4. 持久化 4.1. redis是一个内存数据库,当redis服务器重启,获取电脑重启,数据会丢失, 我们可以将redis内存中的数据持久化保存到硬盘的文件中。 4.2. redis持久化机制——两种机制(RDB和AOF) 4.2.1. RDB:默认方式,不需要进行配置,默认就使用这种机制 * 在一定的间隔时间中,检测key的变化情况,然后持久化数据 1. 编辑redis.windwos.conf文件 # after 900 sec (15 min) if at least 1 key changed save 900 1 # after 300 sec (5 min) if at least 10 keys changed save 300 10 # after 60 sec if at least 10000 keys changed save 60 10000 2. 重新启动redis服务器,并在命令行指定配置文件名称 D:\JavaWeb2018\day23_redis\资料\redis\windows-64\redis-2.8.9>redis-server.exe redis.windows.conf 4.2.2. AOF:日志记录的方式,可以记录每一条命令的操作。可以每一次命令操作后,持久化数据 1. 编辑redis.windwos.conf文件 appendonly no(关闭aof) --> appendonly yes (开启aof) # appendfsync always : 每一次操作都进行持久化 appendfsync everysec : 每隔一秒进行一次持久化 # appendfsync no : 不进行持久化
12.6 Java客户端 Jedis
12.6.1 Jedis快速入门
5. Java客户端 Jedis
* Jedis: 一款java操作redis数据库的工具.
* 使用步骤:
1. 下载jedis的jar包
2. 使用
//1. 获取连接
Jedis jedis = new Jedis("localhost",6379);
//2. 操作
jedis.set("username","zhangsan");
//3. 关闭连接
jedis.close();
12.6.2 Jedis操作redis中的数据结构
* Jedis操作各种redis中的数据结构
1) 字符串类型 string
set
get
//1. 获取连接
Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
//2. 操作
//存储
jedis.set("username","zhangsan");
//获取
String username = jedis.get("username");
System.out.println(username);
//可以使用setex()方法存储可以指定过期时间的 key value
jedis.setex("activecode",20,"hehe");//将activecode:hehe键值对存入redis,并且20秒后自动删除该键值对
//3. 关闭连接
jedis.close();
2) 哈希类型 hash : map格式
hset
hget
hgetAll
//1. 获取连接
Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
//2. 操作
// 存储hash
jedis.hset("user","name","lisi");
jedis.hset("user","age","23");
jedis.hset("user","gender","female");
// 获取hash
String name = jedis.hget("user", "name");
System.out.println(name);
// 获取hash的所有map中的数据
Map<String, String> user = jedis.hgetAll("user");
// keyset
Set<String> keySet = user.keySet();
for (String key : keySet) {
//获取value
String value = user.get(key);
System.out.println(key + ":" + value);
}
//3. 关闭连接
jedis.close();
3) 列表类型 list : linkedlist格式。支持重复元素
lpush / rpush
lpop / rpop
lrange start end : 范围获取
//1. 获取连接
Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
//2. 操作
// list 存储
jedis.lpush("mylist","a","b","c");//从左边存
jedis.rpush("mylist","a","b","c");//从右边存
// list 范围获取
List<String> mylist = jedis.lrange("mylist", 0, -1);
System.out.println(mylist);
// list 弹出
String element1 = jedis.lpop("mylist");//c
System.out.println(element1);
String element2 = jedis.rpop("mylist");//c
System.out.println(element2);
// list 范围获取
List<String> mylist2 = jedis.lrange("mylist", 0, -1);
System.out.println(mylist2);
//3. 关闭连接
jedis.close();
4) 集合类型 set : 不允许重复元素
sadd
smembers:获取所有元素
//1. 获取连接
Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
//2. 操作
// set 存储
jedis.sadd("myset","java","php","c++");
// set 获取
Set<String> myset = jedis.smembers("myset");
System.out.println(myset);
//3. 关闭连接
jedis.close();
5) 有序集合类型 sortedset:不允许重复元素,且元素有顺序
zadd
zrange
//1. 获取连接
Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
//2. 操作
// sortedset 存储
jedis.zadd("mysortedset",3,"亚瑟");
jedis.zadd("mysortedset",30,"后裔");
jedis.zadd("mysortedset",55,"孙悟空");
// sortedset 获取
Set<String> mysortedset = jedis.zrange("mysortedset", 0, -1);
System.out.println(mysortedset);
//3. 关闭连接
jedis.close();
12.6.3 jedis连接池: JedisPool
12.6.3.1 JedisPool 快速入门
* jedis连接池: JedisPool
* 使用:
1. 创建JedisPool连接池对象
2. 调用方法 getResource()方法获取Jedis连接
//0.创建一个配置对象
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(50);
config.setMaxIdle(10);
//1.创建Jedis连接池对象
JedisPool jedisPool = new JedisPool(config,"localhost",6379);
//2.获取连接
Jedis jedis = jedisPool.getResource();
//3. 使用
jedis.set("hehe","heihei");
//4. 关闭 归还到连接池中
jedis.close();
12.6.3.2 jedis 连接池工具类
// 连接池工具类
public class JedisPoolUtils {
/* 配置文件jedis.properties内容:
host=127.0.0.1
port=6379
maxTotal=50
maxIdle=10
*/
private static JedisPool jedisPool;
static{
//读取配置文件
InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
//创建Properties对象
Properties pro = new Properties();
//关联文件
try {
pro.load(is);
} catch (IOException e) {
e.printStackTrace();
}
//获取数据,设置到JedisPoolConfig中
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));
//初始化JedisPool
jedisPool = new JedisPool(config,pro.getProperty("host"),Integer.parseInt(pro.getProperty("port")));
}
/**
* 获取连接方法
*/
public static Jedis getJedis(){
return jedisPool.getResource();
}
}
使用jedis连接池工具类
/**
* jedis连接池工具类使用
*/
@Test
public void test8(){
//通过连接池工具类获取
Jedis jedis = JedisPoolUtils.getJedis();
//3. 使用
jedis.set("hello","world");
//4. 关闭 归还到连接池中
jedis.close();;
}
12.7 案例
案例需求: 1. 提供index.html页面,页面中有一个省份下拉列表 2. 当 页面加载完成后 发送ajax请求,加载所有省份 * 注意:使用redis缓存一些不经常发生变化的数据。 * 数据库的数据一旦发生改变,则需要更新缓存。 * 数据库的表执行 增删改的相关操作,需要将redis缓存数据情况,再次存入 * 在service对应的增删改方法中,将redis数据删除。
13. Linux
13.1 Linux概述
1. Unix简介( 学习Linux之前先了解Unix ) • Unix是一个强大的多用户、多任务操作系统。于1969年在AT&T的贝尔实验室开发。 • UNIX操作系统是商业版,需要收费,价格比Microsoft Windows正版要贵一些。 • UNIX的商标权由国际开放标准组织(The Open Group)所拥有。 2. Linux简介 • Linux是基于Unix的一种自由和开放源码的操作系统 • Linux存在着许多不同的Linux版本,但它们都使用了Linux内核 • Linux可安装在各种计算机硬件设备中,比如手机、平板电脑、路由器、台式计算机 • 诞生于1991 年10 月5 日。是由芬兰赫尔辛基大学学生Linus Torvalds和后来加入的众多爱好者共同开发完成
Linux 的主要发行版本:
|
|---|
3. Linux的历史 Linux最初是由芬兰赫尔辛基大学学生Linus Torvalds由于自己不满意教学中使用的MINIX操作系统, 所以在1990年底由于个人爱好设计出了LINUX系统核心。后来发布于芬兰最大的ftp服务器上。 用户可以免费下载,所以它的周边的程序越来越多,Linux本身也逐渐发展壮大起来。 之后Linux在不到三年的时间里成为了一个功能完善,稳定可靠的操作系统. 4. Linux系统的应用 • 服务器系统Web应用服务器、数据库服务器、接口服务器、DNS、FTP等等; • 嵌入式系统路由器、防火墙、手机、PDA、IP 分享器、交换器、家电用品的微电脑控制器等等, • 高性能运算、计算密集型应用Linux有强大的运算能力。 • 桌面应用系统 • 移动手持系统
5. Linux的版本 • Linux的版本分为两种:内核版本和发行版本 • 内核版本是指在Linus领导下的内核小组开发维护的系统内核的版本号
Linux的主流版本:
|
|---|
13.2 Linux安装
视频链接:https://www.bilibili.com/video/BV1qv4y1o79t?p=512&spm_id_from=pageDriver&vd_source=60482f480b98c4a8ef39f39be38a8b56
1.虚拟机安装
1.什么是虚拟机
• 虚拟机:一台虚拟的电脑.
• 虚拟机软件: VmWare:收费的 VirtualBox:免费的
2.安装VmWare
• 参考《虚拟软件vmware安装.doc》
2.CentOS的安装
• 参考《CentOS6详细安装文档.doc》
13.3 Linux的远程访问
步骤: 1.安装一个远程访问的软件:SecureCRT (安装包在资料中) 2.连接Linux: 需要录入linux的ip地址及用户名密码 查看ip地址ifconfig
|
|---|
13.4 Linux的目录结构

13.5 Linux的常用命令
1.切换目录命令cd:
cd app 切换到app目录
cd .. 切换到上一层目录
cd / 切换到系统根目录
cd ~ 切换到用户主目录
cd - 切换到上一个所在目录
* 使用tab键来补全文件路径
2.列出文件列表:ls ll ls(list)是一个非常有用的命令,用来显示当前目录下的内容。 配合参数的使用,能以不同的方式显示目录内容 格式:ls[参数] [路径或文件名] 常用: ls 显示当前目录下的内容 ls -a 显示所有文件或目录(包含隐藏的文件) ls -l 缩写成ll * 在linux中以 . 开头的文件都是隐藏的文件
3.创建目录(mkdir)和移除目录(rmdir):
mkdir(make directory)命令可用来创建子目录。
mkdir app 在当前目录下创建app目录
mkdir –p app2/test 级联创建aap2以及test目
rmdir(remove directory)命令可用来删除“空”的子目录
rmdir app 删除app目录
rm -r directory_name 删除非空目录
rmdir --ignore-fail-on-non-empty directory_name 删除非空目录
4.浏览文件
【cat 用于显示文件的内容】
格式:cat[参数]<文件名>
* cat yum.conf
【more】
用于要显示的内容会超过一个画面长度的情况。
按空格键显示下一个画面。
回车显示下一行内容。
按 q 键退出查看。
* more yum.conf
【less】
用法和more类似,不同的是less可以通过PgUp、PgDn键来控制。
less yum.conf
PgUp 和 PgDn 进行上下翻页——也可以利用上下键进行查看
【tail 用于显示文件后几行的内容】
tail命令是在实际使用过程中使用非常多的一个命令
用法:
tail -10 /etc/passwd 查看后10行数据
tail -f catalina.log 动态查看日志
* ctrl+c 结束查看
5.文件操作: 【rm 删除文件】 用法:rm [选项]... 文件... rm a.txt 删除a.txt文件 删除需要用户确认,y/nrm 删除不询问 rm -f a.txt 不询问,直接删除rm 删除目录 rm -r a 递归删除不询问递归删除(慎用) rm -rf a 不询问递归删除 rm -rf * 删除所有文件 rm -rf /* 自杀(删除所有文件) 【cp 将文件从一处复制到另一处】 cp(copy)命令可以将文件从一处复制到另一处 一般在使用cp命令时将一个文件复制成另一个文件或复制到某目录时 需要指定源文件名与目标文件名或目录。 cp a.txt b.txt 将a.txt复制为b.txt文件 cp a.txt ../ 将a.txt文件复制到上一层目录中
【mv 移动或者重命名】 mv a.txt ../ 将a.txt文件移动到上一层目录中 mv a.txt b.txt 将a.txt文件重命名为b.txt 【tar 打包或解压】 tar命令位于/bin目录下,它能够将用户所指定的文件或目录打包成一个文件,但不做压缩。 一般Linux上常用的压缩方式是选用tar将许多文件打包成一个文件,再以gzip压缩命令 压缩成xxx.tar.gz(或称为xxx.tgz)的文件。 常用参数: -c:创建一个新tar文件 -v:显示运行过程的信息 -f:指定文件名 -z:调用gzip压缩命令进行压缩 -t:查看压缩文件的内容 -x:解开tar文件 打包: tar –cvf xxx.tar ./* 打包并且压缩:tar –zcvf xxx.tar.gz ./* 解压 tar –xvf xxx.tar tar -zxvf xxx.tar.gz -C /usr/aaa (大写的C——将解压结果放到指定目录)
【find 用于查找符合条件的文件】 示例: find / -name “ins*” 查找文件名称是以ins开头的文件 find / -name “ins*” –ls find / –user itcast –ls 查找用户itcast的文件 find / –user itcast –type d –ls 查找用户itcast的目录 find /-perm -777 –type d-ls 查找权限是777的文件
【grep 查找文件里符合条件的字符串】 用法: grep [选项]... PATTERN [FILE]...示例: grep lang anaconda-ks.cfg 在文件中查找lang grep lang anaconda-ks.cfg –color 高亮显示 6.其他常用命令 【pwd】显示当前所在目录 【touch】创建一个空文件 * touch a.txt 【clear/ crtl + L】清屏
13.6 Vi和Vim编辑器
1.Vim编辑器:
在Linux下一般使用vi编辑器来编辑文件。vi既可以查看文件也可以编辑文件。
三种模式:命令行、插入、底行模式。
切换到命令行模式:按Esc键;
切换到插入模式:按 i 、o、a键;
i 在当前位置前插入
I 在当前行首插入
a 在当前位置后插入
A 在当前行尾插入
o 在当前行之后插入一行
O 在当前行之前插入一行
切换到底行模式:按 :(冒号);
更多详细用法,查询文档《Vim命令合集.docx》和《vi使用方法详细介绍.docx》
打开文件:vim file
退出:esc :q
修改文件:输入i进入插入模式
保存并退出:esc:wq
不保存退出:esc:q!
三种进入插入模式:
i:在当前的光标所在处插入
o:在当前光标所在的行的下一行插入
a:在光标所在的下一个字符插入
快捷键:
dd – 快速删除一行
yy - 复制当前行
nyy - 从当前行向后复制几行
p - 粘贴
R – 替换
其他技巧:
在编辑的时候可以利用:/搜索定位 如搜索:/8080 端口8080
2.重定向输出>和>>
> 重定向输出,覆盖原有内容;
>> 重定向输出,有追加功能;
示例:
cat /etc/passwd > a.txt 将输出定向到a.txt中
cat /etc/passwd >> a.txt 输出并且追加
ifconfig > ifconfig.txt
3.系统管理命令
ps 正在运行的某个进程的状态
ps –ef 查看所有进程
ps –ef | grep ssh 查找某一进程
ps -ef | grep java 查询名称中包含java的进程
kill 2868 杀掉2868编号的进程
kill -9 2868 强制杀死进程
4.管道 |
管道是Linux命令中重要的一个概念,其作用是将一个命令的输出用作另一个命令的输入。
示例
ls --help | more 分页查询帮助信息
ps –ef | grep java 查询名称中包含java的进程
ifconfig | more
cat index.html | more
ps –ef | grep aio
13.7 Linux的权限命令
1.文件权限 r:对文件是指可读取内容 对目录是可以ls w:对文件是指可修改文件内容,对目录 是指可以在其中创建或删除子节点(目录或文件) x:对文件是指是否可以运行这个文件,对目录是指是否可以cd进入这个目录
|
|---|
|
2.Linux三种文件类型: 普通文件: 包括文本文件、数据文件、可执行的二进制程序文件等。 目录文件: Linux系统把目录看成是一种特殊的文件,利用它构成文件系统的树型结构。 设备文件: Linux系统把每一个设备都看成是一个文件 3.文件类型标识 普通文件(-)目录(d)符号链接(l) * 进入etc可以查看,相当于快捷方式字符设备文件(c)块设备文件(s)套接字(s)命名管道(p) 4.文件权限管理: chmod 变更文件或目录的权限。 chmod 755 a.txt chmod u=rwx,g=rx,o=rx a.txt
|
|---|
|
13.8 Linux上常用网络操作
1.主机名配置 hostname 查看主机名 hostname xxx 修改主机名 重启后无效 如果想要永久生效,可以修改/etc/sysconfig/network文件
2.IP地址配置 ifconfig 查看(修改)ip地址(重启后无效) ifconfig eth0 192.168.12.22 修改ip地址 如果想要永久生效 修改 /etc/sysconfig/network-scripts/ifcfg-eth0文件 /etc/sysconfig/network-scripts/ifcfg-eth0文件参数: DEVICE=eth0 #网卡名称 BOOTPROTO=static #获取ip的方式(static/dhcp/bootp/none) HWADDR=00:0C:29:B5:B2:69 #MAC地址 IPADDR=12.168.177.129 #IP地址 NETMASK=255.255.255.0 #子网掩码 NETWORK=192.168.177.0 #网络地址 BROADCAST=192.168.0.255 #广播地址 NBOOT=yes # 系统启动时是否设置此网络接口,设置为yes时,系统启动时激活此设备。 3.域名映射 /etc/hosts文件用于在通过主机名进行访问时做ip地址解析之用 相当于windows系统的C:\Windows\System32\drivers\etc\hosts文件的功能

4.网络服务管理 service network status 查看指定服务的状态 service network stop 停止指定服务 service network start 启动指定服务 service network restart 重启指定服务 service --status–all 查看系统中所有后台服务 netstat –nltp 查看系统中网络进程的端口监听情况 5.防火墙设置 防火墙根据配置文件/etc/sysconfig/iptables来控制本机的”出”、”入”网络访问行为。 service iptables status 查看防火墙状态 service iptables stop 关闭防火墙 service iptables start 启动防火墙 chkconfig iptables off 禁止防火墙自启
13.9 Linux上软件安装
13.9.1 Linux安装软件的常见方式
1.二进制发布包 软件已经针对具体平台编译打包发布,只要解压,修改配置即可 2.RPM包 软件已经按照redhat的包管理工具规范RPM进行打包发布, 需要获取到相应的软件RPM发布包,然后用RPM命令进行安装 缺点:不会自动安装该软件依赖的那些软件包 3.Yum在线安装 软件已经以RPM规范打包,但发布在了网络上的一些服务器上, 可用yum在线安装服务器上的rpm软件,并且会自动解决软件安装过程中的库依赖问题 优点:会自动安装该软件依赖的那些软件包 4.源码编译安装(需要网络的支撑) 软件以源码工程的形式发布,需要获取到源码工程后用相应开发工具进行编译打包部署。
13.9.2 上传与下载工具
1.FileZilla

2.lrzsz 可以使用yum安装方式安装 yum install lrzsz 注意:必须有网络 可以在crt中设置上传与下载目录
|
|---|
上传:
| 点击添加、确定后上传 |
|---|
下载
|
|---|
3.sftp 1.使用alt + p 组合键打开sftp窗口 2.使用put 命令上传

3.使用get命令下载
默认下载位置在当前计算的的文档位置

13.9.3 在Linux上安装JDK
1.上传JDK到Linux的服务器 * 上传JDK * 卸载open-JDK # 查看jdk版本 java –version # 查看安装的jdk信息 rpm -qa | grep java

# 卸载jdk rpm -e --nodeps java-1.6.0-openjdk-1.6.0.35-1.13.7.1.el6_6.i686 rpm -e --nodeps java-1.7.0-openjdk-1.7.0.79-2.5.5.4.el6.i686 2.在Linux服务器上安装JDK 通常将软件安装到/usr/local 直接解压就可以 tar –xvf jdk.tar.gz -C 目标路径 tar -xvf jdk-7u71-linux.tar.gz -C ./jdk 3.配置JDK的环境变量. 配置环境变量: ① vi /etc/profile ② 在末尾行添加 #set java environment JAVA_HOME=/usr/local/jdk/jdk1.7.0_71 CLASSPATH=.:$JAVA_HOME/lib.tools.jar PATH=$JAVA_HOME/bin:$PATH export JAVA_HOME CLASSPATH PATH 保存退出 ③source /etc/profile 使更改的配置立即生效
13.9.4 在Linux上安装Mysql
1.将mysql的安装文件上传到Linux的服务器 将mysql的tar解压 将系统自带的mysql卸载 rpm –qa | grep mysql rpm -ivh MysQL-server-5.6.22-1.el6.i686.rpm

2.安装MYSQL服务端 安装命令: rpm -ivh MySQL-server-5-2-1.el6.i686.rpm

上面的提示告诉我们root用户的密码第一次是随机生成的 它保存在/root/.mysql_secret中,第一次登录需要修改root密码
3.安装MYSQL客户端
安装命令:
rpm -ivh MysQL-client-5.6.1.el6.i686.rpm
查看生成的root密码:
cat /root/ .mysql_secret
显示密码为:_aBE6Mjkn5bb4s1t
尝试登陆mysql:
mysql -uroot -p_aBE6Mjkn5bb4s1t
报错:原因是没有启动mysql服务
需要开启mysql服务:
service mysql start
登录后执行SQL操作报错
原因是第一次操作mysql必须修改root用户的密码
设置root用户的密码
set password = password('root' );(设root为密码)
4.关于mysql远程访问设置
为远程用户开放访问权限:
grant all privileges on *.* to 'root' @'%' identified by 'root';
flush privileges;
在linux中很多软件的端口都被”防火墙”限止,需要将防火墙关闭
防火墙打开3306端口
/sbin/iptables -I INPUT -p tcp --dport 3306 -j ACCEPT
/etc/rc.d/init.d/iptables save
/etc/init.d/iptables status
学习阶段也可以直接将防火墙关闭
service iptables stop;
13.9.5 在Linux上安装tomcat
1.Tomcat上传到linux上 2.将上传的tomcat解压 3.在tomcat/bin目录下执行 startup.sh(注意防火墙) 4.查看目标 tomcat/logs/catalina.out
13.9.6 在Linux上安装redis
1.安装gcc-c++ redis是C语言开发 安装redis需要先将官网下载的源码进行编译,编译依赖gcc环境。 输入命令: yum install gcc-c++ 输入y确认下载 输入y确认安装 安装 gcc 成功! 2.安装redis 1.下载redis wget http://download.redis.io/releases/redis-3.0.4.tar.gz 2.解压 tar -xzvf redis-3.0.4.tar.gz 3.编译安装 切换至程序目录,并执行make命令编译: cd redis-3.0.4 make 执行安装命令 make PREFIX=/usr/local/redis install make install安装完成后,会在/usr/local/bin目录下生成下面几个可执行文件, 它们的作用分别是: redis-server:Redis服务器端启动程序 redis-cli:Redis客户端操作工具。也可以用telnet根据其纯文本协议来操作 redis-benchmark:Redis性能测试工具 redis-check-aof:数据修复工具 redis-check-dump:检查导出工具 3.配置redis 1.复制配置文件到/usr/local/redis/bin目录: cd redis-3.0.4 cp redis.conf /usr/local/redis/bin 4.启动redis 1.进入redis/bin目录 cd redis/bin 2.启动redis服务端 ./redis-server redis.conf 3.克隆新窗口,启动redis客户端 ./redis-cli
7.9.7 部署Java项目到Linux
1. 修改pom配置 在pom.xml中添加<finalName> (指定打包后的文件名) 修改jdk版本1.7

2. 修改项目 2.1 druid.properties :修改字符编码为utf-8

2.2 header.html : 改为相对路径跳转

2.3 route_detail.html :改为相对路径跳转

3. 使用package命令打包

4. 将travel.war上传到tomcat中的webapps目录 cd tomcat/apache-tomcat-7.0.57/webapps 使用rz命令上传traver.war包 由于tomcat是启动状态,所以上传到webapps目录后,tomcat会自动将war包解压缩 如果没有自动解压,可以重启tomcat 也可以通过以下命令查看相关日志: 1.克隆一个会话 2.切换目录到logs下 cd /usr/local/tomcat/apache-tomcat-7.0.57/logs/ 3.查看日志文件catalina.out tail -f catalina.out 6. 重启tomcat 7. 到出本地mysql数据,并导入linux中的mysql
13.10 linux命令积累
查看目录占用内存大小: du -sh /data/logs/it-mailService-provider/ 列出/data/logs/文件夹及其子文件夹下全部文件夹和文件的大小:du -ah /data/logs/
14. Nginx
14.1 Nginx简介
14.1.1 什么是Nginx
1.Nginx 是一款高性能的 http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器 2.由俄罗斯的程序设计师伊戈尔·西索夫(Igor Sysoev)所开发 3.官方测试 nginx 能够支支撑 5 万并发链接,并且 cpu、内存等资源消耗却非常低,运行非常稳定
14.1.2 Nginx 应用场景
1、http 服务器。Nginx 是一个 http 服务可以独立提供 http 服务。可以做网页静态服务器。 2、虚拟主机。可以实现在一台服务器虚拟出多个网站。例如个人网站使用的虚拟主机。 3、反向代理,负载均衡。当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多台服务器集群 可以使用 nginx 做反向代理。并且多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。
14.2 Nginx的安装与启动
14.2.1 Nginx安装前环境准备
1、重新准备一台虚拟机作为服务器。比如IP地址为192.168.177.129
2、需要安装 gcc 的环境
yum install gcc-c++
3、安装第三方的开发包( PCRE、zlib、OpenSSL)
3.1 安装PCRE
yum install -y pcre pcre-devel
注:pcre-devel 是使用 pcre 开发的一个二次开发库。nginx 也需要此库
PCRE(Perl Compatible Regular Expressions)是一个 Perl 库,包括 perl 兼容的正则表达式库
nginx 的 http 模块使用 pcre 来解析正则表达式,所以需要在 linux 上安装 pcre 库
3.2 安装zlib
yum install -y zlib zlib-devel
zlib 库提供了很多种压缩和解压缩的方式,nginx 使用 zlib 对 http 包的内容进行 gzip
所以需要在 linux 上安装 zlib 库
3.3 安装OpenSSL
yum install -y openssl openssl-devel
OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理
功能及 SSL 协议,并提供丰富的应用程序供测试或其它目的使用。nginx 不仅支持 http 协议,还
支持 https(即在 ssl 协议上传输 http),所以需要在 linux安装 openssl 库
14.2.2 Nginx下载&安装
1、Nginx下载
nginx官方网站下载:http://nginx.org/
我们课程中使用的版本是 1.8.0 版本。
2、Nginx安装
第一步:把 nginx 的源码包nginx-1.8.0.tar.gz上传到 linux 系统
第二步:解压缩
tar zxvf nginx-1.8.0.tar.gz
第三步:进入nginx-1.8.0目录 使用 configure 命令创建一个makeFile 文件,命令如下:
./configure \
--prefix=/usr/local/nginx \
--pid-path=/var/run/nginx/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi
执行后可以看到Makefile文件
第四步:编译
make
第五步:安装
make install
3、知识点小贴士 一
Makefile是一种配置文件, Makefile 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个
目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新
编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。
4、知识点小贴士
configure参数
./configure \
--prefix=/usr \ 指向安装目录
--sbin-path=/usr/sbin/nginx \ 指向(执行)程序文件(nginx)
--conf-path=/etc/nginx/nginx.conf \ 指向配置文件
--error-log-path=/var/log/nginx/error.log \ 指向log
--http-log-path=/var/log/nginx/access.log \ 指向http-log
--pid-path=/var/run/nginx/nginx.pid \ 指向pid
--lock-path=/var/lock/nginx.lock \ (安装文件锁定,防止安装文件被别人利用,或自己误操作。)
--user=nginx \
--group=nginx \
--with-http_ssl_module \ 启用ngx_http_ssl_module支持(使支持https请求,需已安装openssl)
--with-http_flv_module \ 启用ngx_http_flv_module支持(提供寻求内存使用基于时间的偏移量文件)
--with-http_stub_status_module \ 启用ngx_http_stub_status_module支持(获取nginx自上次启动以来的工作状态)
--with-http_gzip_static_module \ 启用ngx_http_gzip_static_module支持(在线实时压缩输出数据流)
--http-client-body-temp-path=/var/tmp/nginx/client/ \ 设定http客户端请求临时文件路径
--http-proxy-temp-path=/var/tmp/nginx/proxy/ \ 设定http代理临时文件路径
--http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \ 设定http fastcgi临时文件路径
--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \ 设定http uwsgi临时文件路径
--http-scgi-temp-path=/var/tmp/nginx/scgi \ 设定http scgi临时文件路径
--with-pcre 启用pcre库
14.2.3 Nginx启动与访问
注意:
1、启动nginx 之前,上边将临时文件目录指定为/var/temp/nginx/client,
需要在/var 下创建此目录 mkdir /var/temp/nginx/client -p
2、进入到Nginx目录下的sbin目录
cd /usr/local/nginx/sbin
输入命令启动Nginx
./nginx
启动后查看进程
ps aux|grep nginx
地址栏输入虚拟机的IP即可访问(默认为80端口——直接在浏览器输入IP即可访问)
关闭 nginx:
./nginx -s stop
或者
./nginx -s quit
重启 nginx:
1、先关闭后启动。
2、刷新配置文件:
./nginx -s reload
14.3 Nginx静态网站部署
1、静态网站的部署
将/资料/静态页面/index目录下的所有内容 上传到服务器的/usr/local/nginx/html下即可访问
2、配置虚拟主机
虚拟主机,也叫“网站空间”,就是把一台运行在互联网上的物理服务器划分成多个“虚拟”服务器。
虚拟主机技术极大的促进了网络技术的应用和普及。同时虚拟主机的租用服务也成了网络时代
的一种新型经济形式。
2.1、端口绑定
(1)上传静态网站:
将/资料/静态页面/index目录上传至 /usr/local/nginx/index下
将/资料/静态页面/regist目录上传至 /usr/local/nginx/regist下
(2)修改Nginx 的配置文件:vim /usr/local/nginx/conf/nginx.conf
server {
listen 81; # 监听的端口
server_name localhost; # 域名或ip
location / { # 访问路径配置
root index; # 根目录
index index.html index.htm; # 默认首页
}
error_page 500 502 503 504 /50x.html;# 错误页面
location = /50x.html {
root html;
}
}
server {
listen 82; # 监听的端口
server_name localhost; # 域名或ip
location / { # 访问路径配置
root regist; # 根目录
index regist.html; # 默认首页
}
error_page 500 502 503 504 /50x.html;# 错误页面
location = /50x.html {
root html;
}
}
(3)访问测试:
地址栏输入http://192.168.177.129/:81 可以看到首页面
地址栏输入http://192.168.177.129/:82 可以看到注册页面
(4)补充:editplus的使用:
当修改内容比较多时,vim命令的方式很不方便
可以通过editplus连接服务器,对相应文件进行编辑
editplus连接服务器操作步骤如下:
<1> | <2> | <3> |
|---|---|---|
<4> | <5> | <6> |
修改完后按Ctrl+C保存 | 点击OK完成修改 |
2.2 域名绑定 什么是域名: 域名(Domain Name),是由一串用“点”分隔的字符组成的Internet上某一台计算机或计算机组的名称, 用于在数据传输时标识计算机的电子方位(有时也指地理位置,地理上的域名,指代有行政自主权的一个地 方区域)。域名是一个IP地址上有“面具” 。域名的目的是便于记忆和沟通的一组服务器的地址(网站,电子 邮件,FTP等)。域名作为力所能及难忘的互联网参与者的名称。域名按域名系统(DNS)的规则流程组成。在DNS 中注册的任何名称都是域名。域名用于各种网络环境和应用程序特定的命名和寻址目的。通常,域名表示互联网协议(IP)资源, 例如用于访问因特网的个人计算机,托管网站的服务器计算机,或网站本身或通过因特网传送的任何其他服务。 世界上第一个注册的域名是在1985年1月注册的。
域名级别:
(1)顶级域名
顶级域名又分为两类:
例如:baidu.com
一是国家顶级域名(national top-level domainnames,简称nTLDs),200多个
国家都按照ISO3166国家代码分配了顶级域名,例如中国是cn,美国是us,日本是jp等;
二是国际顶级域名(international top-level domain names,简称iTDs),例如表示工商企业
的 .Com .Top,表示网络提供商的.net,表示非盈利组织的.org,表示教育的.edu,以及没有限制的
中性域名如.xyz等。大多数域名争议都发生在com的顶级域名下,因为多数公司上网的目的都是为了赢利。
但因为自2014年以来新顶级域名的发展,域名争议案件数量增长幅度越来越大[5] 。为加强域名管理,
解决域名资源的紧张,Internet协会、Internet分址机构及世界知识产权组织(WIPO)等国际组织经过
广泛协商, 在原来三个国际通用顶级域名:(com)的基础上,新增加了7个国际通用顶级域名:firm(公司企业)、
store(销售公司或企业)、Web(突出WWW活动的单位)、arts(突出文化、娱乐活动的单位)、rec (突出消遣、娱乐活动的单位)、
info(提供信息服务的单位)、nom(个人),并在世界范围内选择新的注册机构来受理域名注册申请。
(2)二级域名
例如.top,com,edu,gov,net等。
二级域名是指顶级域名之下的域名,在国际顶级域名下,它是指域名注册人的网上名称,例如 ibm,yahoo,microsoft等;
在国家顶级域名下,它是表示注册企业类别的符号,
(3)三级域名
例如:item.map.baidu.com
三级域名用字母( A~Z,a~z,大小写等)、数字(0~9)和连接符(-)组成, 各级域名之间用实点(.)连接,
三级域名的长度不能超过20个字符。如无特殊原因,建议采用申请人的英文名(或者缩写)或者汉语拼音名
(或者缩写) 作为三级域名,以保持域名的清晰性和简洁性。
域名与IP绑定:
一个域名对应一个 ip 地址,一个 ip 地址可以被多个域名绑定。
本地测试可以修改 hosts 文件(C:\Windows\System32\drivers\etc)
可以配置域名和 ip 的映射关系,如果 hosts 文件中配置了域名和 ip 的对应关系,不需要走dns 服务器。
192.168.177.129 www.hmtravel.com
192.168.177.129 regist.hmtravel.com
做好域名指向后,修改nginx配置文件
server {
listen 80;
server_name www.hmtravel.com;
location / {
root cart;
index cart.html;
}
}
server {
listen 80;
server_name regist.hmtravel.com;
location / {
root search;
index search.html;
}
}
执行以下命令,刷新配置
[root@localhost sbin]# ./nginx -s reload
测试:
地址栏输入http://www.hmtravel.com/
14.4 Nginx反向代理
14.4.1 反向代理简介
1、反向代理 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器, 并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
正向代理: 正向代理是针对你的客户端 |
|---|
反向代理: 反向代理是针对服务器的——反向代理代理服务端 |
|
14.4.2 配置反向代理
1、配置反向代理-准备工作
(1) 将travel案例部署到tomcat中(ROOT目录),上传到服务器
(2)启动TOMCAT,输入网址http://192.168.177.129:8080 可以看到网站首页
2、配置反向代理
(1)在Nginx主机修改 Nginx配置文件
upstream tomcat-travel{
server 192.168.177.129:8080; #被代理服务器的IP和端口
}
server {
listen 80; # 监听的端口
server_name www.hmtravel.com; # 域名或ip
location / { # 访问路径配置
# root index; # 根目录
proxy_pass http://tomcat-travel;
index index.html index.htm; # 默认首页
}
}
(2)重新启动Nginx 然后用浏览器测试:http://www.hmtravel.com(此域名须配置域名指向)
|
|---|
14.5 负载均衡
14.5.1 什么是负载均衡
1、负载均衡: 建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络 数据处理能力、提高网络的灵活性和可用性。负载均衡,英文名称为Load Balance,其意思就是分摊到多个操作单元 上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
14.5.2 配置负载均衡
2、配置负载均衡-准备工作 (1)将刚才的存放工程的tomcat复制三份,在tomcat的配置文件conf/server.xml中修改端口分别为8080 ,8081,8082 (2)分别启动这三个tomcat服务 (3)为了能够区分是访问哪个服务器的网站,可以在首页标题加上标记以便区分 视频地址: https://www.bilibili.com/video/BV1qv4y1o79t?p=545&spm_id_from=pageDriver&vd_source=60482f480b98c4a8ef39f39be38a8b56
将刚才的存放工程的tomcat复制三份 |
|---|
3、配置负载均衡
修改 Nginx配置文件:
upstream tomcat-travel {
server 192.168.177.129:8080; #被代理服务器的IP和端口
server 192.168.177.129:8081;
server 192.168.177.129:8082;
}
server {
listen 80; # 监听的端口
server_name www.hmtravel.com; # 域名或ip
location / { # 访问路径配置
# root index; # 根目录
proxy_pass http://tomcat-travel;
index index.html index.htm; # 默认首页
}
error_page 500 502 503 504 /50x.html; # 错误页面
location = /50x.html {
root html;
}
}
地址栏输入http:// www.hmtravel.com / 刷新观察每个网页的标题,看是否不同。
经过测试,三台服务器出现的概率各为33.3333333%,交替显示
如果其中一台服务器性能比较好,想让其承担更多的压力,可以设置权重。
比如想让NO.1出现次数是其它服务器的2倍,则修改配置如下:
upstream tomcat-travel {
server 192.168.177.129:8080;
server 192.168.177.129:8081 weight=2;
server 192.168.177.129:8082;
}
经过测试,每刷新四次,有两次是8081
说明:本内容整理自B站黑马程序员Java web课程视频及文档>>B站黑马程序员Java web课程视频


点击添加、确定后上传
<1>
<2>
<3>
<4>
<5>
<6>
修改完后按Ctrl+C保存
点击OK完成修改
正向代理: 正向代理是针对你的客户端
反向代理: 反向代理是针对服务器的——反向代理代理服务端
将刚才的存放工程的tomcat复制三份

被折叠的 条评论
为什么被折叠?



