前端学习【2】
开头我先来两嗓子,这几篇的内容有点过多了,所以这部分是由几篇文章共同完成的,避免文章过长,影响阅读体验。
xml
什么是XML
XML 指可扩展标记语言(eXtensible Markup Language):XML是一种用于描述数据的标记语言。
XML有什么用
XML主要的作用:
1.用来保存数据,而且这些数据具有自我描述性。
2.可以作为项目或者模块的配置文件。
3.还可以作为网络传输的格式(JSON为主)。
XML语法
1.开始标签和结束标签。
2.注释
3.版本信息
4.根标签
5.标签名和属性
6.编码
xmL文档说明
1 | <!-- xml声明 |
文本区域(CDATA)
CDATA语法可以告诉xml解析器,CDATA里面的文本内容,只是纯文本,不需要XML语法解析。1
2
3<![CDATA[
<<<<<<<<<<<<<<hell,xml>>>>>>>>>>>>
]]>
XML解析
概述
XML解析就是从XML获取到数据
常见的解析思想
DOM文档对象模型:就是把文档的各个组成部分看做成对应的对象。把XML文件全部加载到内存,在内存中形成一个树形结构,再获取对应的值。
早期JDK为我们提供了两种XML解析技术DML和SAX。
面试题:解析XML的方式
- DOM解析:将标记语言一次性加载进内存,再内存中形成一颗DOM树。
- 优点:操作方便,可以对文档进行CRUD的所有操作。
- 缺点:占内存。
- SAX解析:逐行读取,基于事件驱动。
- 优点:不占内存。
- 缺点:只能读取,不能增删改。
常用的解析工具包
jsoup:可以解析XML,更多用于解析HTML,用于网络爬虫
jdom:Jdom组织提供的工具包
dom4j:dom4j组织提供的工具包,使用的较多。
DOM4J
属于第三方公司的技术,我们需要使用dom4j,就需要再官网下载。
1 | 1.先加载xml文件创建document对象 |
案例1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35package com.iweb.test;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.util.List;
public class Test1 {
public static void main(String[] args) throws Exception{
// 要创建一个document对象,需要我们事先创建一个SAXReader对象
SAXReader reader=new SAXReader();
// reader对象用于读取xml文件,然后返回一个document对象
Document document = reader.read("src/books.xml");
// 通过document对象拿到xml的根元素对象
Element root = document.getRootElement();
// 将对象元素对象转换String对象
//System.out.println(root.asXML());
// 通过根元素对象,获取所有的book标签对象
// root.elements(标签名) 它可以拿到当前元素下指定的子元素集合
List<Element> books = root.elements("book");
// 遍历每个boos标签对象,然后获取book标签对象内的每一个元素
for(Element book : books){
// attributeValue获取已知属性名
String id=book.attributeValue("id");
// 获得指定标签名的元素
Element name=book.element("name");
Element author=book.element("author");
Element price=book.element("price");
// getText()方法拿到起始标签和结束标签之间的文本内容
System.out.println("id:"+id+",name:"+name.getText()+",author:"+author.getText()+",price:"+price.getText());
}
}
}
Maven
maven是一款用于管理和构建java项目工具,是apache旗下的一个开源项目。
依赖管理
管理项目依赖的jar包,避免版本冲突问题。
项目构建
开发一套系统,代码需要进行编译、测试、打包、发布等过程,这些操作是所有项目都需要做的,如果需要反复进行就显得特别麻烦,而maven提供了一套简单的命令就能够完成构建项目。
统一项目结构
maven提供了标准,统一的项目结构。
标准Maven项目结构1
2
3
4
5
6
7
8├───src
│ ├───main
│ │ ├───java
│ │ └───resources
│ └───test
│ ├───java
│ └───resources
└───target
maven项目的目录结构中,main目录下存放的是项目源码。test目录存放测试代码。无论是在main还是在test下,都有两个目录,一个是java用来存放源代码,一个是resources用来存放配置文件。
maven就是一款管理和构建java项目的工具
maven概述
maven是一个项目管理和构建工具,它基于项目对象模型(project Object model)简称pom,通过小段描述信息来管理项目的构建,报告和文档。
mavne作用:
- 方便依赖管理
- 统一项目结构
- 标准项目构建流程
1 | <groupId>com.iweb</groupId> |
坐标:就是资源jar包的唯一标识,通过坐标可以定位到所需要的资源(jar)位置,坐标的组成部分:
- groupId:组织名
- artifactId:模板名
- version:版本号
maven仓库
仓库:用于存储资源,管理各种jar包
仓库的本质就是一个目录,这个目录被用来存储开发中所需要的依赖(jar包)
- 本地仓库:自己计算上的一个目录(用来存储jar包)
- 中央仓库:由maven团队维护的全球唯一的
https://mvnrepository.com/
- 远程仓库:一般由公司团队团建的私有仓库
当项目中使用坐标引入对应依赖jar后,首先会在本地仓库中查找是否有对应的jar包。
- 如果有,项目直接引用
- 如果没有,去中央仓库下载对应的jar包到本地
还可以搭建远程仓库(私服),将jar包查找顺序变为:本地仓库—>远程仓库—>中央仓库。
maven安装
maven是一个绿色软件,解压即可。
bin:存放的是可执行命令
conf:存放maven的配置文件(settings.xml配置文件需要修改)
lib:存放maven依赖的jar包
配置本地仓库
1.在自己计算上新建一个目录(本地仓库,用来存储jar包)
2.进入到conf目录下修改settings.xml配置文件
- 使用记事本软件打开settings.xml文件
- 复制
<localRepository>
粘贴到注释的外面 - 复制之前新建的用来存储jar包的路径,替换掉
<localRepository>
标签体内容
配置阿里云私服
中央仓库在国外,所以下载jar包速度可能比较慢,阿里提供了一个远程仓库,里面基本也都有开源项目的jar包。
进入到conf目录下修改settings.xml配置文件
在 <mirror>
标签下为其添加子标签,内容如下:1
2
3
4
5
6<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
注意配置的文件,在<mirrors>
中间添加配置
配置环境变量
Maven环境的配置类似于JDK环境变量配置一样。
1.在系统变量新建一个变量
- MAVEN_HOME:D:\soft\apache-maven-3.6.0
2.编辑系统变量 Path,添加变量值: - %MAVEN_HOME%\bin
打开DOS命令提示符进行验证,出现如图所示表示安装成功:1
mvn -v
pom.xml文件详解
POM项目对象模型,用来描述当前maven项目,使用pom.xml文件来描述当前项目。
maven坐标
通过坐标可以唯一定位资源位置。
依赖管理
依赖:只当前项目运行所需要的jar包,一个项目可以引入多个依赖。
在当前工程中,我们需要用到junit来继续测试,此时我们在maven工程的pom.xml文件中,引入junit的依赖。步骤如下:
1.在pom.xml中编写<dependencys>
标签
2.在<dependencys>
标签中使用<dependency>
引入坐标
3.定义坐标的groupId
、artifactId
1 | <dependencies> |
点击刷新按钮,引入最新加入的坐标
刷新依赖:保证每一次引入新的依赖,或者修改现有的依赖配置,都可以加入最新的坐标。
如果引入的依赖,在本地仓库不存在,将会连接远程仓库或者中央仓库,然后下载依赖,这个过程会比较耗时。
如果不知道依赖的坐标,可以到mvn的(中央仓库)[https://mvnrepository.com/]
查找依赖
利用中央仓库搜索依赖的坐标,以mysql为例
在项目的pom.xml文件中添加项目资源依赖1
2
3
4
5<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
Serlvet
这是个至关重要的技术,用于处理客户端请求和响应。
web服务器
服务器软件是基于请求和响应来开发,在web服务器软件中,可以部署web项目,让用户通过浏览器来访问这些项目。
什么是请求
请求是指客户端给服务器发送数据,叫请求request
什么是响应
响应是指服务器给客户端回传数据,叫响应response
请求和响应的关系
请求和响应都是成对出现的,有请求就有响应
常见的java相关的web服务器软件
- Tomcat:apache基金组织中小型的JavaEE服务器,支持servlet/jsp规范,开源免费。
- webLogic:oralce公司,大型的JavaEE服务器,收费的。
- Jboss:Jboss公司,大型的JavaEE服务器,收费的。
- websphere:IBM公司,大型的JavaEE服务器,收费的。
Tomcat的使用
Tomcat是一个开源的免费的web服务器软件,支持servlet/jsp规范。
我们可以通过这个网站来获得:[点这里](https://tomcat.apache.org/)
获得后直接就可以通过执行startup.bat文件来启动tomcat服务器。
对于中文乱码的问题,在tomcat的conf目录下的server.xml文件中,修改Connector标签的属性:
1
2
3
4 <Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8"/>
如果你所在的地域或者机器属性不支持UTF-8编码,那么可以修改为GBK编码。
但是为了方便我们一般会将tomcat集成到IDEA等中进行使用,具体的操作如下:
1.在IDEA中打开项目
2.点击项目结构(Project Structure)
3.点击模块(Modules)
4.点击依赖(Dependencies)
5.点击加号(+)
6.点击Maven
7.点击OK
8.在弹出的对话框中,选择Tomcat服务器
9.点击OK
10.点击运行(Run)按钮
11.选择Tomcat服务器
12.点击OK
13.等待服务器启动完成
14.在浏览器中输入localhost:8080,即可访问项目。
本站为了节省资源,并不予以图片截图等的示例,若是不了解具体操作细节,请参考官方文档。或者借鉴他人博客来帮助自己学习
在tomcat中,存在以下文件布局:
- bin:存放的是可执行命令
- conf:存放maven的配置文件(settings.xml配置文件需要修改)
- lib:存放maven依赖的jar包
- webapps:存放的是项目文件,每个项目文件都是一个文件夹,文件夹的名称就是项目的名称。
- work:存放的是项目的临时文件,在项目运行过程中,会生成一些临时文件,这些文件会被存放到work目录下。
- logs:存放的是日志文件,在项目运行过程中,会生成一些日志文件,这些文件会被存放到logs目录下。
- temp:存放的是临时文件,在项目运行过程中,会生成一些临时文件,这些文件会被存放到temp目录下。
若是你想要在tomcat中部署项目,那么需要将项目文件放到webapps目录下。
想要停止该服务器运行,只需要在DOS命令提示符中执行shutdown.bat文件即可,或者使用ctrl+c来停止,在idea中则更加简单,只需要点击停止按钮即可。
如果你发现自己有一个端口被占用了,那么可以在conf目录下的server.xml文件中,修改Connector标签的属性:1
2
3
4<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8"/>
将port属性的值修改为其他的端口号,即可。毕竟8080端口过于热门
若是您想要将现有的web项目部署到tomcat中,那么需要将项目文件放到webapps目录下。
在webapps目录下,每个项目文件都是一个文件夹,文件夹的名称就是项目的名称。
在浏览器中输入localhost:8080/项目名称,即可访问项目。
什么是Serlvet
- serlvet是JavaEE规范之一,规范就是接口
- servlet是JavaWeb三大组件之一,三大组件分别是servlet程序、Filter过滤器、Listener监听器。
- servlet是运行在服务器上的一个java小程序,它可以接受客户端发送过来的请求,并响应数据给客户端
实现Serlvet程序
导入servlet依赖坐标,这个坐标宁可以在maven的中央仓库中找到。点这里1
2
3
4
5
6<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
其他的您想要添加的依赖都可以通过中央仓库的途径来增加
我们若是想要高效的实现Serlvet首先我们得编写一个类,这个类需要实现Serlvet接口。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 package com.iweb.servlet;
import javax.servlet.*;
import java.io.IOException;
public class MyServlet implements Servlet {
public MyServlet(){
System.out.println("构造函数");
}
// 对servlet进行初始化
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init");
}
// 获取servlet配置信息
public ServletConfig getServletConfig() {
System.out.println("getServletConfig");
return null;
}
// service方法专门用于处理请求和响应的方法
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("service");
}
public String getServletInfo() {
System.out.println("getServletInfo");
return null;
}
public void destroy() {
System.out.println("destroy");
}
}
并对web.xml文件进行配置1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 <!-- 通过servlet标签给tomcat配置servlet程序 -->
<servlet>
<!-- servlet-name标签 给servlet程序取个一个别名(一般写类名) -->
<servlet-name>MyServlet</servlet-name>
<!-- servlet-class标签 是servlet程序的全类名 包名.类名 -->
<servlet-class>com.iweb.servlet.MyServlet</servlet-class>
</servlet>
<!-- servlet-mapping标签是给servlet程序配置访问地址 -->
<servlet-mapping>
<!-- servlet-name标签的作用是告诉服务器,我当前配置的路径给哪个servlet程序使用 -->
<servlet-name>MyServlet</servlet-name>
<!-- url-pattern 标签配置访问地址
/myServlet 在服务器解析的时候,表示地址为 http://127.0.0.1:8081/myServlet
-->
<url-pattern>/myServlet</url-pattern>
</servlet-mapping>
这种手动置入的行为很容易出现错误1
2
3
4
5
6
7
8
9
10 1.url-pattern中配置的路径没有以斜杠打头
java.lang.IllegalArgumentException:
Invalid <url-pattern> [myServlet] in servlet mapping
2.servlet-name配置的值不存在
Caused by: java.lang.IllegalArgumentException:
Servlet mapping specifies an unknown servlet name [MyServlet1]
3.servlet-class标签的全类名配置错误
java.lang.ClassNotFoundException: com.iweb.servlet.MyServlet1
Serlvet的生命周期
1.执行servlet构造方法
2.执行init方法
- 第一步和第二步在第一次访问的时候创建servlet会被调用
3.service方法
● 每次访问都会被调用
4.执行destroy销毁方法 - 在web工程停止的时候调用
HttpServlet实现servlet程序
一般在实际项目开发中,都是使用继承HttpServlet类的方式去实现servlet程序。
1.编写一个类去继承HttpServlet类
2.编写业务需要重写doGet或者doPost方法
3.到web.xml中配置servlet程序的访问地址
- 配置servlet的名称
- 配置servlet的全类名
- 配置servlet的访问地址
4.在浏览器中访问servlet程序的访问地址,即可访问servlet程序。对应的xml配置:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22package com.iweb.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MyServlet1 extends HttpServlet {
// doGet()在get请求的时候调用
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet...");
}
// doPost()在post请求的时候调用
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost...");
}
}1
2
3
4
5
6
7
8
9
10
11
12
13<servlet>
<servlet-name>MyServlet1</servlet-name>
<servlet-class>com.iweb.servlet.MyServlet1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet1</servlet-name>
<url-pattern>/myServlet1</url-pattern>
</servlet-mapping>
这里做一个面试题,GET和POST的区别
- GET请求:
- 1.请求参数在URL中显示
- 2.请求参数的大小有限制
- 3.请求参数的类型只能是文本类型
- POST请求:
- 1.请求参数在请求体中显示
- 2.请求参数的大小没有限制
- 3.请求参数的类型没有限制
GenericServlet实现servlet程序
1 | package com.iweb.servlet; |
web.xml配置1
2
3
4
5
6
7
8
9
10
11
12
13 <servlet>
<servlet-name>MyServlet2</servlet-name>
<servlet-class>com.iweb.servlet.MyServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet2</servlet-name>
<url-pattern>/myServlet2</url-pattern>
</servlet-mapping>
Servlet继承体系
我用一句话来说明白这个过程吧,servlet程序是继承自HttpServlet类的,HttpServlet类是继承自GenericServlet类的,GenericServlet类是继承自Servlet接口的。(阿巴阿巴我自己都不清楚)
ServletContext类
1.ServletContext是一个接口,表示servlet上下文对象。
2.一个web工程,只有一个ServletContext实例。
3.ServletContext对象是一个域对象。
4.ServletContext是在web工程部署启动的时候创建,在web工程停止的时候销毁
什么是域对象?
域对象,是可以像Map一样存取数据的对象,叫做域对象。
域对象是指存取数据的操作范围,整个web工程。
ServletContext类有四个作用
1.获取web.xml中配置的上下文参数
2.获得当前的工程路径
3.获取工程部署后在服务器硬盘上的绝对路径
4.像Map一样存取数据
注意一下啊这个存储数据的范围是整个web工程,所以在不同的servlet程序中,获取的ServletContext对象是同一个。并且这些数据都是在服务器启动的时候就已经加载好的,所以在servlet程序中可以直接获取到。和项目强制绑定
1 | <!-- context-param是上下参数(属于这个web工程) |
对应构造类java示例1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 package com.iweb.servlet;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class MyServlet implements Servlet {
ServletContext servletContext=null;
// service方法专门用于处理请求和响应的方法
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
// 获取web.xml中配置的上下文参数 context-param
// 获得username参数
String username = servletContext.getInitParameter("username");
String password = servletContext.getInitParameter("password");
System.out.println(username+"\t"+password);
// 获取当前的工程路径
String contextPath = servletContext.getContextPath();
System.out.println(contextPath);
System.out.println("当前的工程路径-->"+contextPath);
// 获取工程部署后在服务器硬盘上的绝对路径
System.out.println("工程部署的路径-->"+servletContext.getRealPath("/"));
}
public MyServlet(){
System.out.println("构造函数");
}
// 对servlet进行初始化
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init");
servletContext = servletConfig.getServletContext();
}
// 获取servlet配置信息
public ServletConfig getServletConfig() {
System.out.println("getServletConfig");
return null;
}
public String getServletInfo() {
System.out.println("getServletInfo");
return null;
}
public void destroy() {
System.out.println("destroy");
}
}
Servlet3.0规范
可以看见,我们在对servlet进行配置的时候,需要在web.xml中进行配置,这过于繁琐和复杂,但是在Servlet3.0规范中,我们可以不使用web.xml进行配置,而是使用注解的方式进行配置。
@WebServlet注解用于将一个类声明为servlet,该注解将会在部署时被容器处理,容器将根据具体的属性配置相应的类部署为servlet。该注解具体常用属性:
1 | package com.iweb.servlet; |
以上配置之后,就不需要在web.xml中配置响应的标签了。
但是请一定要注意书写的数据类型和路径格式等细节问题,很容易造成错误。
HTTP协议
HTTP协议
HTTP:Hypertext Transfer Protocol超文本传输协议,规定了浏览器和服务器之间数据传输的规则。
- HTTP是互联网应用最广泛的一种网络协议
- HTTP协议要求:浏览器向服务器发送请求数据时,或者服务器在向浏览器响应数据时,都必须按照固定的格式进行数据传输。
我们学习HTTP协议,就是学习请求和响应数据的具体格式内容。
就我个人而言很喜欢HTTP,方便且强大。而且依托于html的强大功能,我们可以很方便的实现一个简单的网站。
HTTP协议的特点:
基于TCP协议:面向连接,安全
TCP是一种面向连接的(建立连接之前需要经过三次握手),可靠的,基于字符流的传输层通信协议,在数据传输方便更安全
基于请求-响应:一次请求对应一次响应(先请求后响应)
请求和响应是一一对应的关系,没有请求就没有响应
HTTP协议的格式
● 客户端给服务器发送数据叫请求
● 服务器给客户端回传数据叫响应
○ 请求又分为Get请求,和Post请求中。
请求协议:浏览器将数据以请求格式发送给服务器,包括请求行,请求头,请求体。
请求行:HTTP请求中的第一行数据,由请求方式、资源路径、协议/版本组成。
请求方式:GET
资源路径:/web_project02_war/myServlet3
请求参数:username=admin123&password=123456
- 请求参数是以key=value形式组成
- 多个请求参数之间使用&连接
请求头:第二行开始,格式为key:value,在请求头设置浏览器的一些自身信息和响应的形式 - host:请求的主机名
- User-Agent:浏览器版本
- Accept:表示浏览器能接受的资源类型
- Accept-Language:浏览器支持的语言,服务器可以根据此返回不同语言的网页
- Accept-Encoding:浏览器支持压缩类型
请求体:存储请求参数
GET请求的请求体参数在请求行中
Post方式的请求协议:
请求行:包含请求方式Post,资源路径,协议/版本
请求头
请求体:存储请求参数
GET&POST
GET:GET请求的参数直接附加在URL上,以?号分隔路径于参数,多个参数使用&连接,这种方式使参数在URL中可见。
例如:1
http://localhost:8081/web_project02_war/myServlet3?username=admin123&password=123456
可以看见,GET请求的参数直接附加在URL上,以?号分隔路径于参数,多个参数使用&连接,这种方式使参数在URL中可见。在开发过程中这种调试可以更加的直观,但是在实际开发运用中这种行为过于危险
POST:POST请求的参数不直接附加在URL上,而是存储在请求体中。
例如:1
http://localhost:8081/web_project02_war/myServlet3
可以看见,POST请求的参数不直接附加在URL上,而是存储在请求体中。在开发过程中这种调试相对GET请求来说更加的安全,但是在实际开发运用中这种行为相对GET请求来说更加的安全。
那些是GET请求,那些是POST请求
● get请求有那些:
○ form标签method=get
○ a标签
○ 在浏览器地址中输入地址后敲回车
● post请求有那些:
○ form标签method=post
HttpServletRequest
每次只要有请求进入tomcat服务器,tomcat服务器就把请求过来的http协议信息解析好封装到request对象,然后传递到service(doGet和doPost)方法中给我们使用,我们可以通过HttpServletRequest对象,获取请求中的信息1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package com.iweb.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* urlPatterns 指定一组servlet的url匹配等价于 <url-pattern>
* loadOnStartup 指定servlet的加载顺序
* name 指定servlet的name属性,如果没有指定则以该servlet的取值为类的全类名 <servlet-name>
* value 该属于等价于 urlPatterns属性,两个属性不能同时使用
*/
public class MyServlet3 extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("绝对路径-->"+req.getRequestURL());
System.out.println("获取请求的参数-->"+req.getParameter("username"));
System.out.println("获取客户端的IP地址-->"+req.getRemotePort());
}
}
如何获取请求参数
获取请求行中的参数:1
2
3
4
5
6req.getRequestURL();//获取请求的绝对路径
req.getRequestURI();//获取请求的资源路径
req.getMethod();//获取请求的方式
req.getProtocol();//获取请求的协议
req.getServerName();//获取请求的服务器名
req.getServerPort();//获取请求的服务器端口
获取请求头中的参数:1
req.getHeader("key");//获取请求头中的key值
获取请求体中的参数:1
req.getParameter("key");//获取请求体中的key值
获取请求参数的名称:1
req.getParameterNames();//获取请求参数的名称
获取请求参数的名称和值:1
req.getParameterMap();//获取请求参数的名称和值
获取请求参数的值:1
req.getParameterValues("key");//获取请求参数的值
获取请求参数的值:1
req.getParameter("key");//获取请求参数的值
OK打住,再写下去我要炸了。我直接用一个典型的案例来给大家做介绍吧
index.html1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<form action="paramsServlet" method="post">
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password"/><br/>
性别:<input type="radio" value="man" name="sex" checked/>男
<input type="radio" value="woman" name="sex"/>女<br/>
兴趣爱好:<input type="checkbox" name="hobby" value="java"/>java
<input type="checkbox" name="hobby" value="python"/>python
<input type="checkbox" name="hobby" value="c++"/>c++<br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
servlet1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package com.iweb.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
public class ParamsServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求中的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String sex = req.getParameter("sex");
String[] hobby = req.getParameterValues("hobby");
System.out.println(username+"\t"+password+"\t"+sex);
System.out.println(Arrays.toString(hobby));
}
}
你要是直接截取上述代码,你会发现在中文传递上会存在一些问题,所以我们需要单独去对这个问题进行解决
doGet请求的中文乱码解决1
2
3
4
5
6
7
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求中的参数
String username = req.getParameter("username");
// 先以iso-8859-1进行编码,再以UTF-8进行解码
username=new String(username.getBytes("iso-8859-1"),"utf-8");
}
doPost请求的中文乱码解决1
2
3
4 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设置请求体的字符集为UTF-8解决post请求的中文乱码问题
req.setCharacterEncoding("utf-8");
}
请求转发
什么是请求转发?
请求转发是指,服务器收到请求后,从一次资源跳转到另外一个资源的操作叫做请求转发。
请求转发特点:
1.浏览器地址栏没有变化
2.他们是一次请求
3.他们共享request域中的数据
4.不可以访问工程以外的资源
5.request域中的数据只能是一次请求
实现方法:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class ServletTest1 extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求中的参数(办事的材料)
String username = req.getParameter("username");
System.out.println("在servlet1柜台查看参数(材料):"+username);
// 给材料盖个章,并传递到servlet2(柜台)绑定上request域对象中
req.setAttribute("key",username);
// 问路,走向servlet2
// 请求转发必须以/打头
req.getRequestDispatcher("/servletTest2").forward(req,resp);
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class ServletTest2 extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 检查柜台1是否有盖章
Object key = req.getAttribute("key");
System.out.println("检查柜台1是否有盖章:"+key);
// 处理业务
System.out.println("servlet2处理自己的业务");
}
}
HttpServletResponse
HttpServletResponse和HttpServletRequest类一样,每次请求进来,tomcat服务器都会创建一个Response对象传递给servlet程序去使用,
HttpServletRequest类表示请求过来的信息,HttpServletResponse表示所有响应的信息,如果我们需要设置返回给客户端的信息,可以通过HttpServletResponse对象来设置。
字有点多,我一句话用大白话说清楚:
HttpServletResponse类表示响应的信息,我们可以通过HttpServletResponse对象来设置响应的信息。
两个输出流的说明
字节流 getOutputStream():用于下载
字符流 getWriter():用于回传字符串(常用)
两个流同时只能使用一个,使用了字节流就不能使用字符流,反之亦然,否则会报错。
有点难记啊,打多了写多了就记得了1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package com.iweb.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class ResponseServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 接受客户端传递过来的参数
int age =Integer.parseInt(req.getParameter("age"));
System.out.println(age);
// 往客户端回传字符串(数据)
PrintWriter writer = resp.getWriter();
writer.write("客户端你好,已经收到了你的数据");
}
}
响应的乱码问题
因为各种软件,地域的标准不同,所以在不同的地域,会有不同的编码标准,在中文的地域,会使用gbk编码,在英文的地域,会使用utf-8编码,所以在回传字符串时,需要注意编码问题,否则会出现乱码问题。
下面就是个姐姐乱码问题的典型实例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package com.iweb.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class ResponseServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 处理请求中文乱码
req.setCharacterEncoding("utf-8");
// 处理响应中文乱码
// 同时设置服务器和客户端使用UTF-8字符集,还设置响应头
// 方法一定要在获取流对象之间调用才有效
resp.setContentType("text/html;charset=utf-8");
// 接受客户端传递过来的参数
int age =Integer.parseInt(req.getParameter("age"));
System.out.println(age);
// 往客户端回传字符串(数据)
PrintWriter writer = resp.getWriter();
writer.write("客户端你好,已经收到了你的数据");
}
}
请求中定向
重定向行为,是指客户端给服务器发请求,然后服务器告诉客户端,之前的访问地址已经被废弃,去新的地址访问,叫做请求重定向。
因为我认为转换页面等行为本质上是路径选取,所以我认为重定向可以做到很多的功能,比如:
1.访问一个页面,但是这个页面需要登录才能访问,那么我们就可以在servlet中判断用户是否登录,如果没有登录,就可以重定向到登录页面。
2.访问一个页面,但是这个页面的访问地址已经被废弃,我们可以重定向到新的地址。
3.访问一个页面,但是这个页面的访问地址已经被废弃,我们可以重定向到新的地址。
请求重定向的特点:
1.浏览器地址会发生改变
2.两次请求
3.不能共享request域中的数据
4.不能访问web-inf下的资源
以下是一个重定向的案例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package com.iweb.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ServletTest3 extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 绑定数据到request域中
req.setAttribute("username","admin123");
// 重定向
resp.sendRedirect("servletTest4");
}
}
最终要的部分来自最后的那一行:1
resp.sendRedirect("servletTest4");
更多请转下一篇:前端学习【3】