赞
踩
JavaWeb是指用Java技术来解决Web互联网领域的技术栈。Web包括:Web客户端和Web服务端两部分
Web开发:
Web(World Wide Web),即全球广域网,也称为万维网,它是一种基于超文本和HTTP的、全球性的、动态交互的、跨平台的分布式图形信息系统。是建立在Internet上的一种网络服务,为浏览者在Internet上查找和浏览信息提供了图形化的、易于访问的直观界面
静态Web
动态web
ASP:
PHP:
JSP/Servlet:
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端(维护方便、体验一般)
CS架构:Client/Server,客户端/服务器架构模式(开发、维护麻烦,体验较好)
服务器硬件:也是计算机,只不过服务器要比我们平常使用的计算机在各方面性能好很多!
服务器只是一台设备,必须安装服务器软件才能提供相应的服务
Tomcat服务器软件是一个免费的开源的Web应用服务器。是Apache软件基金会的一个核心项目。由 Apache,Sun和其他一些公司及个人共同开发而成
由于Tomcat只支持Servlet/JSP少量JavaEE规范,所以是一个开源免费的轻量级Web服务器
JavaEE规范: Java Enterprise Edition(Java企业版) JavaEE规范就是指Java企业级开发的技术规范总和。包含13项技术规范:JDBC、JNDI、EJB、 RMI、JSP、Servlet、XML、JMS、Java IDL、JTS、JTA、JavaMail、JAF
因为Tomcat支持Servlet/JSP规范,所以Tomcat也被称为Web容器、Servlet容器。JavaWeb程序需要依赖Tomcat才能运行
解压缩安装到指定目录即可!
目录结构
启动和关闭Tomcat
Tomcat的默认端口为8080,所以在浏览器的地址栏输入: http://127.0.0.1:8080,即可访问 tomcat服务器!
关闭:
bin/shutdown.bat
:正常关闭可能遇到的问题
乱码问题解决方案:修改conf/logging.prooperties
文件解决,修改为GB
可以配置启动的端口号
如果端口被占用,可在conf/server.xml
配置端口号
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
Tomcat部署项目:将编写好的项目放到 webapps
目录下,即可部署完成!
HTTP:Hyper Text Transfer Protocol(超文本传输协议),规定了浏览器与服务器之间数据传输的规则
浏览器和服务器是按照HTTP协议进行数据通信的
HTTP协议又分为:请求协议和响应协议
请求协议:浏览器将数据以请求格式发送到服务器
响应协议:服务器将数据以响应格式返回给浏览器
区别方式 | GET请求 | POST请求 |
---|---|---|
请求参数 | 请求参数在请求行中 | 请求参数在请求体中 |
请求参数长度 | 请求参数长度有限制(浏览器的不同限制也不同) | 请求参数长度无限制 |
安全性 | 安全性低。原因:请求参数暴露在浏览器地址栏中 | 安全性相对高 |
与HTTP的请求一样,HTTP响应的数据也分为3部分:响应行、响应头 、响应体
状态码 | 说明 |
---|---|
1xx | 响应中,临时状态码。表示请求已经接受,告诉客户端应该继续请求或者如果已经完成则忽略 |
2xx | 成功,表示请求已经被成功接收,处理已完成 |
3xx | 重定向,重定向到其它地方,让客户端再发起一个请求以完成整个处理 |
4xx | 客户端错误,处理发生错误,责任在客户端,如:客户端的请求一个不存在的资源,客户端未被授权,禁止访问等 |
5xx | 服务器端错误,处理发生错误,责任在服务端,如:服务端抛出异常,路由出错, HTTP版本不支持等 |
为什么要学习Maven
Maven是Apache旗下的一个开源项目,是一款用于管理和构建java项目的工具
Maven的核心思想:约定大于配置
Apache 软件基金会,成立于1999年7月,是目前世界上最大的最受欢迎的开源软件基金会,也是一个专门为支持开源项目而生的非盈利性组织
Maven模型
之前在项目中需要jar包时,直接就把jar包复制到项目下的lib目录,而现在书写在pom.xml文件中的坐标又是怎么能找到所要的jar包文件的呢?Maven仓库
仓库:用于存储资源,管理各种jar包
仓库的本质就是一个目录(文件夹),这个目录被用来存储开发中所有依赖(就是jar包)和插件
Maven仓库分为:
当项目中使用坐标引入对应依赖jar包后,首先会查找本地仓库中是否有对应的jar包
还可以搭建远程仓库(私服),将来jar包的查找顺序则变为: 本地仓库 —> 远程仓库—> 中央仓库
下载之后解压缩到指定位置即可;
目录结构如下:
在系统变量处新建一个变量MAVEN_HOME
在Path中进行配置
%MAVEN_HOME%\bin
使用mvn -version
测试是否配置成功(在cmd窗口中)
在maven安装目录中新建一个目录:MavenRepository
(本地仓库,用来存储jar包)
进入到conf目录下修改settings.xml
配置文件,大概50行左右
<!-- maven本地仓库地址 -->
<localRepository>E:\Environment\apache-maven-3.8.1\MavenRepository</localRepository>
由于中央仓库在国外,所以下载jar包速度可能比较慢,而阿里公司提供了一个远程仓库,里面基本也都有开源项目的jar包
进入到conf目录下修改settings.xml
配置文件,大概160行左右,在<mirrors></mirrors>标签中添加 mirror 子节点:
<!-- 阿里云(私服)远程仓库 -->
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
注:项目创建成功后,看下Maven的配置!
first-maven-project
— src (源代码目录和测试代码目录)
--- main (源代码目录) --- java (源代码java文件目录) --- resources (源代码配置文件目录) --- test (测试代码目录) --- java (测试代码java目录) --- resources (测试代码配置文件目录)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
— target (编译、打包生成文件存放目录)
注:在web应用下才会出现
解决警告问题
必要的配置:为什么会有这个问题?访问一个网站,需要指定文件夹名字!
启动
POM (Project Object Model) :指的是项目对象模型,用来描述当前的maven项目
使用pom.xml文件来实现
<?xml version="1.0" encoding="UTF-8"?> <!--Maven的版本和头文件--> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <!-- POM模型版本 --> <modelVersion>4.0.0</modelVersion> <!-- 当前项目坐标 GAV--> <groupId>com.baidu</groupId> <artifactId>javaweb-01-maven</artifactId> <version>1.0-SNAPSHOT</version> <!-- 项目的打包方式 jar:java应用 war:javaWeb应用 --> <packaging>war</packaging> <name>javaweb-01-maven Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <!-- 配置 --> <properties> <!-- 项目的默认构建编码 --> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- 编译版本 --> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> <!-- 项目依赖 --> <dependencies> <!-- 具体依赖的jar包配置文件 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> </dependencies> </project>
maven由于它的约定大于配置,之后可以会遇到我们写的配置文件,无法被导出或者生效的问题,解决方案:
<!--在build中配置resources,来防止我们资源导出失败的问题--> <build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
直接依赖:在当前项目中通过依赖配置建立的依赖关系
间接依赖:被依赖的资源如果依赖其他资源,当前项目间接依赖其他资源
排除依赖:指主动断开依赖的资源。(被排除的资源无需指定版本)
<!-- 排除依赖, 主动断开依赖的资源 -->
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
在项目中导入依赖的jar包后,默认情况下,可以在任何地方使用
作用范围:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
给junit依赖通过scope标签指定依赖的作用范围。 那么这个依赖就只能作用在测试环境,其他环境下不能使用
scope标签的取值范围:
scope值 | 主程序 | 测试程序 | 打包(运行) | 范例 |
---|---|---|---|---|
compile(默认) | Y | Y | Y | log4j |
test | - | Y | - | junit |
provided | Y | Y | - | servlet-api |
runtime | - | Y | Y | jdbc驱动 |
Maven的生命周期就是为了对所有的构建过程进行抽象和统一。 描述了一次项目构建,经历哪些阶段
Maven对项目构建的生命周期划分为3套(相互独立):
常用生命周期命令
生命周期的顺序是:clean —> validate —> compile —> test —> package —> verify —> install —> site —> deploy
注:在同一套生命周期中,在执行后面的生命周期时,前面的生命周期都会执行
执行可通过idea可视化界面操作或者打开cmd窗口输入:mvn clean/test/package...
Servlet是Sun公司开发动态web的一门技术
Servlet是JavaEE规范之一,规范就是接口
Servlet是JavaWeb三大组件之一,三大组件分别是:Servlet程序、Filter过滤器、Listener监听器
Servlet是运行在服务器上的一个java小型程序,它可以接收客户端发送过来的请求,并响应数据给客户端
sun在这些API中提供一个接口:Servlet,如果想开发一个Servlet程序,只需要完成两个小步骤
把实现了Servlet接口的Java程序叫做:Servlet
Servlet可以动态生成HTML内容从而对客户端进行响应
1.执行Servlet构造器方法
2.执行init初始化方法
第一、二步,是在第一次访问的时候创建Servlet程序会调用
3.执行service方法
第三步,每次访问都会调用
4.执行destroy销毁方法
第四步,在web工程停止的时候调用
Servlet接口有两个默认的实现类:HttpServlet、GenericServlet
构建一个普通Maven项目,删除里面的src目录,在这个项目里面建立Module;这个空的工程就是Maven主工程
环境优化
编写一个servlet程序
public class HelloServlet extends HttpServlet {
//由于get或者post只是请求实现的不同的方式,可以相互调用,因为业务逻辑都一样
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//ServletOutputStream outputStream = resp.getOutputStream();
PrintWriter writer = resp.getWriter();//响应流
writer.println("hello,Servlet!");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
编写servlet的映射
为什么需要映射:写的是java程序,但要通过浏览器访问,而浏览器需要连接web服务器,所以要在web服务注册我们写的servlet。还需要给他能够访问的路径
<!--servlet标签给Tomcat配置Servlet程序--> <servlet> <!--servlet-name标签 给Servlet程序起一个别名(一般是类名)--> <servlet-name>hello</servlet-name> <!--servlet-class是Servlet程序的全类名--> <servlet-class>com.zhang.servlet.HelloServlet</servlet-class> <!--init-param是初始化参数!--> <init-param> <!--参数名--> <param-name>username</param-name> <!--参数值--> <param-value>root</param-value> </init-param> </servlet> <!--servlet-mapping标签给Servlet程序配置访问地址--> <servlet-mapping> <!--servlet-name标签的作用是告诉服务器,我当前配置的地址给那个Servlet程序使用--> <servlet-name>hello</servlet-name> <!--url-pattern标签配置访问地址--> <!-- / 斜杆在服务器解析的时候,表示地址为:http://ip地址:端口号/工程路径 /hello 表示地址为:http://ip地址:端口号/工程路径/hello 配置的url-pattern(资源路径)就是你要访问的地址! --> <url-pattern>/hello</url-pattern> </servlet-mapping>
配置tomcat
注:配置项目发布的路径就OK了
启动测试
Servlet是由Web服务器调用,web服务器是在收到浏览器请求之后会:
1、共享数据
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//this.getInitParameter(); // 初始化参数
//this.getServletConfig(); // servlet配置
//this.getServletContext(); // servlet上下文
ServletContext context = this.getServletContext();
context.setAttribute("username","张三"); // 将一个数据保存着在servletContext 键=>值对
}
}
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String username = (String) context.getAttribute("username");
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().println("名字是:" + username);
}
}
<servlet>
<servlet-name>getServlet</servlet-name>
<servlet-class>com.zhang.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getServlet</servlet-name>
<url-pattern>/getServlet</url-pattern>
</servlet-mapping>
测试访问结果
2、获取初始化参数
<!--配置一些web应用初始化参数-->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://127.0.0.1:3306//mybatis</param-value>
</context-param>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
String url = servletContext.getInitParameter("url");
resp.getWriter().println(url);
}
3、请求转发
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
System.out.println("进入了s3");
// RequestDispatcher dispatcher = servletContext.getRequestDispatcher("/gp"); //转发的请求路径
// dispatcher.forward(req,resp); //调用forward实现请求转发
servletContext.getRequestDispatcher("/s2").forward(req,resp);
}
4、读取资源文件
Properties
发现:都被打包了同一个路径下,classes,俗称这个路径为classpath
需要一个文件流:
username = root
password = 123456
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties prop = new Properties();
prop.load(is);
String user = prop.getProperty("username");
String pwd = prop.getProperty("password");
resp.getWriter().println(user + ":" + pwd);
}
访问测试即可ok;
每次只要有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的HTTP协议信息解析好封装到Request对象中然后传递到service 方法( doGet和doPost)中给我们使用。可以通过HttpServletRequest对象,从而获取到所有请求的信息
1、获取前端传递的参数
2、请求转发
方法名称 | 说明 |
---|---|
String getParameter(String name) | 根据表单组件名称获取提交数据 |
String[ ] getParameterValues(String name) | 获取表单组件对应多个值时的请求数据 |
// 后台接收中文乱码问题
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String pwd = req.getParameter("pwd");
String[] hobbys = req.getParameterValues("hobbys");
System.out.println("====================");
System.out.println(username);
System.out.println(pwd);
System.out.println(Arrays.toString(hobbys));
System.out.println("====================");
// 通过请求转发
req.getRequestDispatcher("/success.jsp").forward(req, resp);
HttpSerletRespise类和HttpServletRequest类一样。每次请求进来Tomcat 服务器都会创建一个Response对象传递给 Servlet 程序去使用。HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息,如果需要设置返回给客户端的信息,可以通过HttpServletResponse对象来进行设置
1、简单分类
负责向浏览器发送数据的方法
// 字节流 常用于下载(传递二进制数据)
ServletOutputStream getOutputStream() throws IOException;
// 字符流 常用于回传字符串(常用)
PrintWriter getWriter() throws IOException;
注:两个流同时只能使用一个,如果使用了字节流,就不能再使用字符流,反之亦然
2、常见应用
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1. 获取下载文件的路径 String realPath = "E:\\Program Files (x86)\\IntelliJ IDEA Project\\Jsp\\javaweb-01-servlet\\target\\classes\\6.jpeg"; System.out.println("下载的文件的路径:" + realPath); //2. 下载的文件名是什么? String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1); //3. 设置想办法让浏览器支持(Content-disposition)下载我们需要的东西 中文文件名URLEncoder.encode编码,否则可能乱码 resp.setHeader("Content-Disposition", "attachment;filename" + URLEncoder.encode(fileName,"utf-8")); //4. 获取下载文件的输入流 FileInputStream in = new FileInputStream(realPath); //5. 创建缓冲区 int len = 0; byte[] buffer = new byte[1024]; //6. 获取OutputStream对象 ServletOutputStream out = resp.getOutputStream(); //7. 将FileOutStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端 while ((len = in.read(buffer)) > 0) { out.write(buffer, 0, len); } //8. 关闭流 in.close(); out.close(); }
3、实现重定向
B一个web资源收到客户端A请求后,B它会通知A客户端区访问另外一个web资源C,这个过程叫重定向
常见场景:用户登录
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.sendRedirect("/login.jsp"); // 重定向
}
面试题:请你聊聊重定向和转发的区别?
请求转发是指:服务器收到请求后,从一次资源跳转到另一个资源的操作叫请求转发
请求重定向是指:客户端给服务器发请求,然后服务器告诉客户端说。我给你一个地址。你去新地址访问。叫请求重定向
请求转发的特点:
请求重定向的特点:
常见场景:网站登录之后,你下次不用登录了,第二次访问直接就登录上去了
Cookie[] cookies = req.getCookies(); // 获取Cookie
cookie.getName(); // 获取Cookie的key
cookie.getValue(); // 获得Cookie的值
new Cookie("lastLoginTime", System.currentTimeMillis() + ""); // 新建一个Cookie
cookie.setMaxAge(24 * 60 * 60); // 设置Cookie的有效期
resp.addCookie(cookie); // 响应给客户端一个Cookie
删除Cookie:
优缺点
优缺点
Session和Cookie的区别:
会话自动过期:web.xml配置
<!--设置session默认注销的时间-->
<session-config>
<!-- 15分钟后session自动失效,以分钟为单位-->
<session-timeout>15</session-timeout>
</session-config>
JSP (Java Server Pages):Java服务器端页面,也和Servlet一样,用于动态web技术!
jsp的主要作用是代替Servlet程序回传html页面的数据
因为Servlet程序回传html页面数据是一件非常繁锁的事情。开发成本和维护成本都极高
最大的特点:
Jsp到底是如何执行的?
发现页面转变成了Java程序!
浏览器想服务器发送请求,不管访问什么资源,实际上都是在访问Servlet!
Jsp最终也会被转换成为一个Java类,Jsp本质上就是一个Servlet程序
//初始化
public void _jspInit() {
}
//销毁
public void _jspDestroy() {
}
//JspService
public void _jspService(HttpServletRequest request, HttpServletResponse response)
任何语言都有自己的语法,JSP 作为Java技术的一种应用, 它拥有一些自己扩充的语法,Java中的所有语法都支持!
jsp表达式
<%--jsp表达式 作用:用来将程序的输出,输出到客户端
<%=变量或者表达式%>
--%>
<%=new java.util.Date()%>
jsp脚本片段
<%--jsp脚本片段--%> <% int sum = 0; for (int i = 1; i <= 100; i++) { sum += i; } out.print("<h1>Sum=" + sum + "</h1>"); %> <!--打印5次hello,world!--> <% for (int i = 1; i <= 5; i++) { %> <h2>hello,world!<%=i%></h2> <% } %>
jsp声明
<%--jsp声明--%>
<%!
static {
System.out.println("Loading Servlet!");
}
private int globalVar = 0;
public void sayHello(){
System.out.println("hello,jsp!");
}
%>
jsp声明:会被编译到Jsp生成Java的类中!其他的,就会生成到_jspSServlet方法中!
在Jsp中,嵌入Java代码即可!
<%%> <!--脚本片段 -->
<%=%> <!--表达式 -->
<%!%> <!--声明 -->
<!--我是html的注释--> <!--注释 -->
<%--我是Jsp的注释--%>
Jsp的注释,不会再客户端显示,html注释会在客户端显示!
小结:
<%@ page language="java" import="java.util.*,java.text.*" contentType="text/html; charset=utf-8" %>
<%--设置页面编码--%>
<%@ page pageEncoding="utf-8" %>
<%--定制错误页面--%>
<%@ page errorPage="error/500.jsp"%>
<%--显示的声明这是一个错误页面--%>
<%@ page isErrorPage="true"%>
<%--设置公共部分--%>
<%@ include file="common/header.jsp"%>
<%--设置公共部分--%>
<%@ include file="common/header.jsp"%>
<h2 class="content">页面主体</h2>
<%--设置公共部分--%>
<%@ include file="common/footer.jsp"%>
<%--jsp标签--%>
<jsp:include page="common/header.jsp"/>
<h2 class="content">页面主体</h2>
<jsp:include page="common/footer.jsp"/>
两者区别:
<% //存放数据 //(PageContextImpl类) 保存的数据值能在一个页面中有效 pageContext.setAttribute("name1", "小张"); // (HttpServletRequest类) 一次请求内有效 request.setAttribute("name2", "小赵"); //(HttpSession类) 一个会话范围内有效(打开浏览器访问服务器,直到关闭浏览器) 默认30分钟 session.setAttribute("name3", "小林"); // (ServletContext类) 整个web工程范围内都有效(只要web工程不停止,所有数据都在) application.setAttribute("name4", "小李"); %> <% //通过pageContext取出保存的值,通过寻找的方式来找 //从底层到高层(作用域): page-->request-->session-->application //JVM:双亲委派机制 String name1 = (String) pageContext.findAttribute("name1"); String name2 = (String) pageContext.findAttribute("name2"); String name3 = (String) pageContext.findAttribute("name3"); String name4 = (String) pageContext.findAttribute("name4"); String name5 = (String) pageContext.findAttribute("name5"); //不存在 %> <%--使用EL表达式输出 ${} --%> <h1>取出的值为</h1> <h2>${name1}</h2> <h2>${name2}</h2> <h2>${name3}</h2> <h2>${name4}</h2> <%--自动过滤掉--%> <h2>${name5}</h2>
request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻,用户看完没用的!
session:客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如:购物车
application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如:聊天数据
<!-- JSTL表达式依赖 -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!-- stardust标签库 -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
EL表达式:${ }
Jsp标签
<jsp:include page="header.jsp"></jsp:include>
<%--http:localhost:8082/jsp04.jsp?name=zhangtao&age=19--%>
<jsp:forward page="jsp04.jsp">
<%-- 携带参数--%>
<jsp:param name="name" value="zhang"/>
<jsp:param name="age" value="19"/>
</jsp:forward>
JSTL表达式
JSTL标签库的使用就是为了弥补HTML标签的不足;它自定义许多标签,可以供我们使用,标签的功能和java代码一样!
核心标签
JSTL标签库使用步骤
c:if
<form action="coreif.jsp" method="get">
<%--
EL表达式获取表单的数据
${param.参数名}
--%>
<input type="text" name="username" value="${param.username}">
<input type="submit" value="登录"/>
</form>
<%--判断,如果提交的用户名是管理员,则登录成功--%>
<c:if test="${param.username=='admin'}" var="isAdmin">
<c:out value="管理员,欢迎你!"/>
</c:if>
<%--自闭和标签--%>
<c:out value="${isAdmin}"/>
c:choose c:when
<%--定义一个变量score,值为85--%>
<c:set var="score" value="98"/>
<c:choose>
<c:when test="${score>=90}">你的成绩为优秀!</c:when>
<c:when test="${score>=80}">你的成绩为一般!</c:when>
<c:when test="${score>=70}">你的成绩为良好!</c:when>
<c:when test="${score<=60}">你的成绩为一般般,继续努力!</c:when>
</c:choose>
c:forEach
<% ArrayList<String> person = new ArrayList<>(); person.add("张三"); person.add("李四"); person.add("王五"); person.add("赵六"); request.setAttribute("list", person); %> <%-- var,每一次遍历处理的变量 items,要遍历的对象 begin, 哪里开始 end, 到哪里 step, 步长 --%> <c:forEach var="person" items="${list}"> <c:out value="${person}"/><br/> </c:forEach> <hr/> <c:forEach var="person" items="${list}" begin="1" end="3" step="1"> <c:out value="${person}"/><br/> </c:forEach>
拦截请求常见的应用场景有
权限检查
日记操作
事务管理
代码示例:
public class AdminFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) servletRequest; HttpSession session = req.getSession(); Object user = session.getAttribute("user"); // 如果等于空,说明用户还没有登录! if (user == null) { HttpServletResponse resp = (HttpServletResponse) servletResponse; resp.sendRedirect(req.getContextPath() + "/login.jsp"); } else { // 让程序继续往下访问用户的目标资源 filterChain.doFilter(servletRequest, servletResponse); } } }
<!--filter标签用于配置一个Filter过滤器--> <filter> <!--给Filter起一个别名--> <filter-name>AdminFilter</filter-name> <!--配置Filter的全类名--> <filter-class>com.zhang.filter.AdminFilter</filter-class> <init-param> <param-name>username</param-name> <param-value>root</param-value> </init-param> <init-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:3303/flower</param-value> </init-param> </filter> <!--filter-mapping 配置Filter过滤器的拦截路径--> <filter-mapping> <!--表示当前的拦截路径给那个filter使用--> <filter-name>AdminFilter</filter-name> <!-- url-pattern 表示:http://ip:port/工程路径/ 映射到IDEA的web目录 /admin/* 表示请求地址到 http://ip:port/工程路径/admin/* --> <url-pattern>/admin/*</url-pattern> </filter-mapping>
1.构造器方法
2.init初始化方法
第1、2步,在web工程启动的时候执行(Filter已经创建)
3.doFilter过滤方法
第3步,每次拦截请求,就会执行
4.destroy销毁
第4步,停止web工程的时候,就会执行(停止web工程的时候,也会销毁过滤器
FilterChain:多个过滤器如何一起工作
FilterChain()方法的作用:
执行下一个Filter过滤器(如果有)
执行目标资源(如果没有)
在多个Filter过滤器执行的时候,他们执行的优先顺序是由它们在web.xml中从上到下配置的顺序决定!
多个Filter过滤器执行的特点:
1.所有Filter的目标资源默认都执行在同一个线程中
2.多个Filter共同执行的时候,它们都使用同一个Request对象
注:轻量级指的是跟xml做比较!
数据交换指的是客户端和服务器之间业务数据的传递格式
json是由键值对组成,并且由花括号(大括号) 包裹。每个键由引号引起来,键和值之间使用冒号进行分隔,多组键值对之间进行逗号进行分隔
let jsonStr = {
"id": 1001,
"name": '晓琳',
"age": 19,
"hobby": ['girl', 'code', 'swim', 'game'],
}
json的两个常用方法
JSON.stringify() // 把Js对象转换成为json字符串
JSON.parse() // 把json字符串转换成为Js对象
let jsonStr = JSON.stringify(jsonObj); // 把js对象转换成为json字符串
console.log(jsonStr);
let parseJsonObj = JSON.parse(jsonStr); // 把json字符串解析成为json对象
console.log(parseJsonObj);
需导入fastjson1.2.78.jar包
JavaBean和Json的互转
public void test1() {
// JavaBean和Json的互转
Person p1 = new Person(1001, "admin");
// toJSONString() 将Java对象转换成为json字符串
String personJsonStr = (String) JSON.toJSONString(p1);
System.out.println(personJsonStr);
// parseObject() 将json字符串转换成为Java对象
Person person = JSON.parseObject(personJsonStr, Person.class);
System.out.println(person);
}
List和Json的互转
@Test public void test2() { // List和Json的互转 List<Person> list = new ArrayList<>(); Person p1 = new Person(1001, "admin"); Person p2 = new Person(1002, "小张"); Person p3 = new Person(1003, "晓琳"); list.add(p1); list.add(p2); list.add(p3); // 将list集合转换成为Json字符串 String listStr = JSON.toJSONString(list); System.out.println(listStr); // 将Json字符串转换为list集合 匿名内部类 ArrayList<Person> personList = JSON.parseObject(listStr, new TypeReference<ArrayList<Person>>() {}); System.out.println(personList); }
Map和Json的互转
@Test public void test3() { // Map和Json的互转 Map<Integer, Person> map = new HashMap<>(); map.put(1, new Person(100, "晓琳")); map.put(2, new Person(102, "小张")); map.put(3, new Person(103, "小赵")); // 将map转换成为json字符串 String mapStr = JSON.toJSONString(map); System.out.println(mapStr); // 将json字符串转换成为map HashMap<Integer, Person> personHashMap = JSON.parseObject(mapStr, new TypeReference<HashMap<Integer, Person>>() { }); System.out.println(personHashMap); }
什么是Ajax请求?
使用原生Ajax技术实现异步交互
五步使用法:
1.创建XMLHTTPRequest对象
2.使用open方法设置和服务器的交互信息
3.设置发送的数据,开始和服务器端交互
4.注册事件
5.更新界面
get请求:
<button>点击发送请求</button> <div class="result"> </div> <script> document.querySelector("button").addEventListener("click", () => { let uname = "小昭" // 1.创建对象 const xhr = new XMLHttpRequest() // 2.初始化 设置请求方法 和 url xhr.open("POST", `http://localhost:8000/server?name=${uname}`) // 设置请求头 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") // 设置响应体数据的类型 xhr.responseType = "json" // 超时设置 超过2s取消发送请求 xhr.timeout = 2000 // 超时回调 xhr.ontimeout = () => alert("请求超时 请稍后重试") // 网络异常回调 xhr.onerror = () => alert("你的网络似乎出现了一些问题 请稍后重试") xhr.onreadystatechange = () => { // readyState = 4 请求已完成并且响应已经准备好 // status = 200 说明可以接收到响应数据,表示服务端已经返回所有的结果 if (xhr.readyState === 4 && xhr.status === 200) { // 处理结果 console.log(xhr.status); // 状态码 console.log(xhr.statusText); // 状态字符串 console.log(xhr.getAllResponseHeaders()); // 所有响应头 console.log(xhr.response); // 响应体 document.querySelector(".result").innerHTML = xhr.response } } // 3.发送请求 xhr.send(`name:${uname}&pwd:${upwd}`) }) </script>
ajax格式:
$.ajax方法
url 表示请求的地址
type 表示请求的方式GET/POST请求
data 表示发送给服务器的数据
两种格式:
1.name=value&name=value
2.{key:value}
dataType 预期服务器端返回的数据类型
常用的数据类型有:text(纯文本)、xml(xml数据)、json(json对象)
contentType 设置请求头
success 请求成功时调用次函数
error 请求失败时调用次函数
示例:
<div class="container"> <button class="btn btn-danger">POST</button> <button class="btn btn-info">通用型(ALL)</button> </div> <script> $("button").eq(0).click(() => { $.post("http://localhost:8000/user", { uname: "小昭", age: 18 }, function (data) { console.log(data) }) }) $("button").eq(1).click(() => { $.ajax({ // 请求地址 url: "http://localhost:8000/user", // 请求类型 type: "POST", // 请求参数 data: { uname: "小昭", age: 18 }, // 响应体结果 dataType: "json", // 成功回调 success: function (data) { console.log(data) }, // 超时时间 timeout: 2000, // 失败回调 error: function () { console.log("出错了"); }, // 头信息 headers: { uname: "Mr zhang" } }) // 表单序列化 serialize(),serialize()可以把表单中所有表单项的内容都获取到 // 并以name=value&name=value的形式进行拼接 $("#submit").click(function () { // 序列化表单内容为字符串,用于 Ajax 请求! // alert($("#form1").serialize()); $.getJSON("http://localhost:8080/07_json_ajax/ajax", "action=jquerySerialize&" + $("#form1").serialize(), function (data) { $("#msg").html(" serialize方法 编号:" + data.id + ",姓名:" + data.name); }); }) }) </script>
同源策略(Same-Origin Policy)最早由Netscape 公司提出,是浏览器的一种安全策略
如何解决跨域?
CORS是什么?
CORS (Cross-Origin Resource Sharing),跨域资源共享。CORS 是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get和post请求。跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源
CORS 是如何工作的?
CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行
CORS的使用
主要是服务器端的设置:
<script>
document.querySelector("button").addEventListener("click", () => {
$.get("http://localhost:8000/cors-server", function (resp) {
console.log(resp)
})
})
// 服务器端设置
app.get("/cors-server", (req, resp) => {
// 设置响应头 允许跨域
resp.setHeader("Access-Control-Allow-Origin", "*") // 所有地址地址都可跨域请求
// resp.setHeader("Access-Control-Allow-Origin", "http://localhost:8000") // 只有该地址才可跨域请求
resp.setHeader("Access-Control-Allow-Headers", "*") // 所有请求头都可跨域请求
resp.setHeader("Access-Control-Allow-Method", "*") // 所有请求方式都可跨域请求
</script>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。