【基础知识】_JAVAWEB基础

JAVAWEB基础

XML

xml也是一种标记语言,xml标签都是自定义的,不想html标签都是预定义的。xml本来是设计出来与html竞争的,只不过竞争不过,转而改变了发展方向,主要用于作为配置文件存储数据。

约束

约束是规定xml文档的书写规则。约束文档一般是由要使用的框架预先编写定义好的,为了使框架能够正确解析xml文档的xml文档书写规则。程序员只需要能够读懂约束文档就可以使用它来编写所需要的xml文档。

当前主流约束主要有两种:DTD和Schema,其中SSM框架使用的就是Schema类型框架。

Schema

Schema约束文档的后缀名为.xsd,其内容书写语法其实与xml相同。

在一个xml文档中引入Schema约束的基本步骤:

  1. 填写xml文档的根元素
  2. 引入xsi前缀. xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance"
  3. 引入xsd文件命名空间. xsi:schemaLocation=”http://www.itcast.cn/xml student.xsd”
  4. 为每一个xsd约束声明一个前缀,作为标识 xmlns=”http://www.itcast.cn/xml"

e.g.

1
2
3
<students   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.itcast.cn/xml student.xsd"
xmlns="http://www.itcast.cn/xml">

Jsoup

解析xml文档就是将文档中的数据读取到内存中。Jsoup是一款java的HTML解析器,可以直接解析URL地址、HTML文本内容,也可以解析xml文档。Jsoup的主要作用就是作为一个java文件中的一个工具类,查询html文件或者xml文件中的标签、属性等内容。

  • 基本使用步骤:

    1. 导入jar包
    2. 获取Document对象
    3. 获取Element对象
    4. 获取标签属性或标签体内容

    e.g.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //获取xml文件的地址路径字符串
    String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").getPath();

    //将xml文档按DOM的形式加载进内存,形成一颗DOM树,并获取Document对象
    Document document = Jsoup.parse(new File("E:/files/IntelliJ IDEA/041Xml/out/production/041Xml/student.xml"),"utf-8");

    //获取Element对象
    Elements elements = document.getElementsByTag("name");
    Element element = elements.get(0);

    //获取标签体内容
    String name1 = element.text();

  • Jsoup对象

    Document parse(File in,String charsetName):将xml或html文件加载进内存,并返回Document对象

  • Document对象

    Element getElementById(String id):根据id属性值获取唯一的标签对象

    Elements select(String cssQuery):根据css选择器获取标签对象集合,比如”name”、”#1”、”.tab”

    Elements getElementsByTag(String tagName):根据标签名获取标签对象集合

    Elements getElementsByAttribute(String key):根据属性名称获取标签对象集合

    Elements getElementsByAttributeValue(String key,String value):根据属性键值对获取标签对象集合

  • Elements对象:Element标签对象的集合,就直接当成ArrayList<Element>来用就可以了。

    Element get(int index):获取集合中对应索引位置的标签对象

  • Element对象

    String attr(String key):根据属性名获取属性值

    String text():获取标签体中的文本内容

    String html():获取包括子标签的所有标签体内容

Jsoup使用案例

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
public static void main(String[] args) throws IOException {

String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").getPath();
//非常重要:获取类的类加载器;
//由类加载器的资源获取方法动态获取到项目中src目录下的student.xml文件的url路径;
//获取url路径对象中的字符串路径属性。

System.out.println(path);
/**
* 非常重要:这里出巨大巨大问题,因为我们当初设置的项目存放目录中有一个文件夹IntelliJ IDEA,
* 当我们在用Java中的一些获取路径方法获取路径字符串时,得到的字符串会将这个文件夹字符串输出为IntelliJ%20IDEA,
* 也就是说会自动将其中的空格按utf-8进行编码,然后我们在后面将该字符串作为一些IO方法的输入时,这些方法时无法自动
* 将%20解码为空格,所以这些方法都会执行错误,导致无法找到文件路径。
* 1.解决办法:在这个文件夹中的项目中,当需要将文件绝对路径作为方法输入时,只能自己手动输入了。
* 2.经验教训:以后在做项目的时候,项目所在文件路径中的文件夹命名一定要严格一些,像空格这种比较奇怪的字符一定不要有。
*/

Document document = Jsoup.parse(new File("E:/files/IntelliJ IDEA/041Xml/out/production/041Xml/student.xml"),"utf-8");//(parse:解析)
//将xml文档按DOM的形式加载进内存,形成一颗DOM树,并获取Document对象。(非常重要:此处的绝对路径字符串中的/换成\\也可以。)

Elements elements = document.getElementsByTag("name");
//获取元素Elements对象。(这里通过标签名称获取到了一个元素动态数组)

Element element = elements.get(0);
//获取数组中第一Element对象。

String name1 = element.text();
//通过元素对象的text()方法获取元素文本数据(就是元素对应标签的标签体内容)。

System.out.println(name1);
//因为其实该elment元素中含有两个子元素分别包含两个数据,所以这里输出时系统会自动在两个数据之间加一个空格间隔。
}
  • 类名.class.getClassLoader()方法常用于获取类的类加载器
  • 类加载器的getResource(String 文件名)资源获取方法:该方法可以动态获取项目中src目录下的文件
  • getPath()方法用于获取文件对象的url地址绝对路径字符串
  • 非常重要:这里出巨大巨大问题,因为我们当初设置的项目存放目录中有一个文件夹IntelliJ IDEA,当我们在用Java中的一些获取路径方法获取路径字符串时,得到的字符串会将这个文件夹字符串输出为IntelliJ%20IDEA,也就是说会自动将其中的空格按utf-8进行编码,然后我们在后面将该字符串作为一些IO方法的输入时,这些方法时无法自动将%20解码为空格,所以这些方法都会执行错误,导致无法找到文件路径。
    • 解决办法:在这个文件夹中的项目中,当需要将文件绝对路径作为方法输入时,只能自己手动输入了。
    • 经验教训:以后在做项目的时候,项目所在文件路径中的文件夹命名一定要严格一些,像空格这种比较奇怪的字符一定不要有。

Servlet

web服务器软件

  • 服务器:安装了服务器软件的计算机,比如我们的电脑之前装过MySQL服务器软件,那么我们的电脑就可以叫做MySQL服务器
  • 服务器软件:接收用户的请求,处理请求,做出响应
  • web服务器软件:在web服务器软件中,可以部署web项目,让用户浏览器来访问这些项目
  • web项目主要由静态资源和动态资源组成,常用动态资源有Servlet/JSP

Servlet概念

Servlet就是运行在服务器端的小程序。Servlet实际上就是java中的一个接口,该接口定义了java类被浏览器访问到的规则,所以服务器动态资源中的java类必须是Servlet接口的实现子类,这样才能被tomcat所识别运用。

Servlet使用步骤

  1. 创建JavaEE项目

  2. 定义一个类,实现Servlet接口

  3. 实现接口中的抽象方法

  4. 在web-inf文件夹中的web.xml配置文件中配置Servlet动态资源

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <!--配置动态资源的资源名称(其实就是给该Servlet类取一个简短一些的别名,否则直接写全类名称很冗长)-->
    <servlet>
    <servlet-name>demo1</servlet-name>
    <servlet-class>jia.zheng.servlet.ServletDemo1</servlet-class>
    </servlet>

    <!--配置动态资源的路径,就是访问到该动态资源的url中的一部分(一般就是直接在资源名称前面加/)-->
    <servlet-mapping>
    <servlet-name>demo1</servlet-name>
    <url-pattern>/demo1</url-pattern>
    </servlet-mapping>

通过浏览器请求动态资源的原理步骤

  1. 当服务器接受到客户端浏览器的请求后,会解析所要请求的URL路径,获取访问的Servlet的资源路径
  2. 查找web.xml文件,是否有对应的<url-pattern>标签体内容
  3. 如果有,则在找到对应的<servlet-class>全类名
  4. tomcat会将该Servlet类的字节码文件加载进内存,并且通过反射创建该类的实例对象
  5. 通过反射创建并执行类中方法

e.g. http://localhost:8080/day13_tomcat/demo1是一个典型的动态资源url:其中localhost:8080是服务器主机ip地址和服务器软件端口;/day13_tomcat是虚拟目录,我们可以在idea中自行更改和设置;/demo1是资源路径。

Servlet注解配置

Servlet3.0以后支持通过注解来配置Servlet,不再需要web.xml来配置,这样方便了很多。

注解配置使用步骤:

  1. 创建JavaEE项目,选择Servlet的版本3.0以上,可以不用创建web-inf文件夹和web.xml文件
  2. 定义一个类,实现Servlet接口
  3. 复写方法
  4. 在类上使用@WebServlet注解,进行配置
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
@WebServlet(urlPatterns="/annotation")//使用注解配置,将该servlet接口实现类与一个唯一的资源路径相匹配。
public class ServletAnnotation implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {

}

@Override
public ServletConfig getServletConfig() {
return null;
}

@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Servlet3.0来了。。。。。");
}

@Override
public String getServletInfo() {
return null;
}

@Override
public void destroy() {}
}
  • 注解中的urlPatterns=不写也可以,直接写成@WebServlet("/annotation")也是可以正确运行的,因为资源路径是默认最重要的配置属性。
  • 一个Servlet也可以定义多个资源路径,@WebServlet("/d","/dd","/ddd")这三个不同的资源路径访问到的都是同一个Servlet资源。
  • @WebServlet("/*")表示任何字符串代替的资源路径都可以访问到该Servlet资源。

tomcat在于idea结合使用时,项目部署后,tomcat真正访问的是out/artifacts文件夹中的web项目和文件。

Servlet体系结构

继承关系:Servlet接口——>GenericServlet抽象类——>HttpServlet抽象类

  • GenericServlet:将Servlet接口中其他方法做了默认空实现,只将service()方法作为抽象。这样将来要定义Servlet类时,直接继承GenericServlet,只需要实现service()方法就可以。当然,如果还想实现其他方法,直接重写那些方法就可以。
  • HttpServlet:对http协议进行了一些封装,简化了操作,在service()方法中已经帮我们编写好了判断请求方式的代码,我们只需要重写出对应判断结果的doGet/doPost方法。实际上这个是最常使用的。

HTTP

HTTP概念

hyper text transfer protocol超文本传输协议,定义了客户端和服务器端通信时,发送数据的格式,也就是客户端发送给服务器的请求消息服务器发送给客户端的响应消息的格式。

  • 一次请求对应一次响应
  • 每次请求之间相互独立,不能交互数据

请求消息数据格式

  1. 请求行:请求方式 请求url 请求协议/版本

    其中常用的请求方式主要有两种

    • GET:请求参数在请求行中,在url后面;请求的url长度有限制;不太安全
    • POST:请求参数在请求体中;请求的url长度没有限制;相对安全
  2. 请求头:(主要是一些键值对形式的请求信息) 请求头名称:请求头值

  3. 请求空行

    一个空行,主要用于分割请求头和请求体。GET请求没有这个部分

  4. 请求体:键=值

    封装POST请求消息中的请求参数,比如表单提交的键值对数据。GET请求没有这个部分,GET请求的请求参数直接放在请求行中。

响应消息数据格式

  1. 响应行:协议/版本 响应状态码 状态码描述

    响应状态码都是三位数字,比如200表示响应成功,302表示重定向,404表示找不到请求路径对应的资源,500表示服务器内部出现异常。

  2. 响应头:响应头名称:响应头值

  3. 响应空行

  4. 响应体

    响应体一般就是一个html代码文档,代表页面的响应显示效果。


Request

原理

request和response指的是Servlet类中必须要用到的两个实例化对象,其中request对象是用来获取请求消息中数据内容的,response对象是用来设置响应消息数据内容的。

体系结构

继承关系:ServletRequest接口——>HttpServletRequest接口——> org.apache.catalina.connector.RequestFacade 类

获取请求数据的方法

  1. String getMethod():获取请求行中的请求方式
  2. String getContextPath():获取请求的url中的虚拟路径
  3. String getServletPath():获取请求的url中的Servlet资源路径
  4. String getQueryString():获取get方式请求参数
  5. String getRequestURI():获取请求URI
  6. StringBuffer getRequestURL():获取请求的URL
    • URL:统一资源定位符 : http://localhost/day14/demo1
    • URI:统一资源标识符 :/day14/demo1 (虚拟路径+资源路径)
  7. String getProtocol():获取协议及版本
  8. String getRemoteAddr():获取客户机的IP地址
  9. String getHeader(String name):通过请求头的名称获取请求头的值
  10. Enumeration<String> getHeaderNames():获取所有的请求头名称
  11. BufferedReader getReader():获取字符输入流,只能操作字符数据
  12. ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据
  13. String getParameter(String name):根据参数名称获取参数值
  14. String[] getParameterValues(String name):根据参数名称获取参数值的数组(一般作用于表单中的复选框)
  15. Enumeration<String> getParameterNames():获取所有请求的参数名称
  16. Map<String,String[]> getParameterMap():获取所有参数的map集合

其他方法

  1. setCharacterEncoding(“utf-8”):设置请求参数编码方式的方法,实参一般为”utf-8”或”gbk”

  2. RequestDispatcher getRequestDispatcher(String path):通过request对象获取请求转发器对象,参数path一般是资源路径。请求转发器对象中有一个方法forward(ServletRequest request,ServletResponse response),该方法可以将请求和响应转发到另一个Servlet动态资源中。

    请求转发是一种在服务器内部的资源跳转方式,跳转时浏览器地址栏路径不变,转发虽然访问了一个以上动态资源,但是只算一次请求。

  3. void setAttribute(String name,Object obj):存储数据到request域中

    request域代表一次请求的范围,一般用于在请求转发跳转的多个动态资源中共享数据。

  4. Object getAttitude(String name):通过键获取request域中值

  5. void removeAttribute(String name):通过键移除request域中键值对

  6. ServletContext getServletContext():获取ServletContext

使用案例

  1. 表单提交案例
1
2
3
4
<form action="/Demo1" method="post"><!--表单输入数据提交到的动态资源路径为"/Demo1",提交方式为"post"-->
<input name="username">
<input type="submit" value="提交">
</form>
  • form表单标签的属性action的属性值为动态资源的uri(虚拟路径+资源路径),可用于指定表单数据所提交到的动态资源;属性method可用于设定提交方式。
  1. 转发案例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

request.setAttribute("msg","hello");
//将数据存储到request域中,数据以键值对的形式存储。
//如果想要在下一个跳转资源中获取request域中的共享资源,则必须在跳转之前把数据存入request域中。

RequestDispatcher requestDispatcher = request.getRequestDispatcher("/ServletRequestDemo1");
//获取一个跳转到"/ServletRequestDemo1"资源的请求转发器对象。

requestDispatcher.forward(request,response);
//带着请求对象和响应对象跳转到另一个动态资源当中去,执行其他操作。
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//直接引用doPost()表示,两种不同提交方式对应执行相同操作。
this.doPost(request,response);
}

Response

常用方法

  1. setHeader(String name, String value):设置响应头

  2. PrintWriter getWriter():获取字符输出流

    e.g.

    1
    2
    3
    4
    5
    //获取响应的Servlet字符输出流。
    PrintWriter pw = response.getWriter();

    //输出数据。(字符输出流的write方法直接以字符串为输入,并将其输出显示)
    pw.write("<h1>你好</h1>");
  3. ServletOutputStream getOutputStream():获取字节输出流

    e.g.

    1
    2
    //将图片输出到页面展示。(也要先获取响应的字节输出流)
    ImageIO.write(image,"jpg",response.getOutputStream());
    1
    2
    3
    4
    5
    //获取Servlet字节输出流。
    ServletOutputStream sos = response.getOutputStream();

    //字节输出流的write方法的输入参数应该为字节码,如果想要输出字符串数据则需要先用getBytes()方法将字符串数据转化为字节码数据。getBytes()默认编码方式为gbk,我们这里可以将其设置为utf-8。
    sos.write("<h1>你好啊</h1>".getBytes("utf-8"));
    • Byte:四位二进制表示一个字节,字节码一般由十六进制数组成,因为四位二进制数范围正好是0~15
  4. sendRedirect(String path):重定向,跳转到其他资源,其中参数path一般用 uri统一资源标识符。重定向时,浏览器地址栏会发生变化;重定向可以访问其他服务器的资源;重定向是两次请求,每次重定向则浏览器发送一条新的请求,不能使用request对象来共享数据。

    相对路径一般以.开头,绝对路径一般以/开头,url和uri都是绝对路径。转发方法的路径参数一般不需要加虚拟目录,因为虚拟目录由项目唯一确定,而转发只能发生在同一项目的不同资源间;而<a>、<form>、重定向中的路径参数都要加虚拟目录甚至是协议、ip、端口,因为它们能实现不同主机、不同项目之间资源的跳转。

    e.g.

    1
    2
    //使用虚拟路径动态获取方法来获取该动态资源所在项目的虚拟路径,并加上资源路径,作为重定向方法的输入字符串。
    response.sendRedirect(request.getContextPath()+"/ResponseDemo2");
  5. setContentType(“text/html;charset=utf-8”):设置响应体输出格式和字符串输出编码字符集

    浏览器页面出现乱码的主要原因就是,编、解码使用的字符集不一样。动态资源输出数据时会将字符串数据按某种字符集(gbk或者utf-8)编码,然后到浏览器中要先按某种字符集解码成字符串,才能在界面上显示,当编、解码字符集不一样就会乱码。


ServletContext对象

ServletContext对象代表整个web项目,一个web项目对应一个ServletContext对象

获取

  • request.getServletContext():通过request对象获取ServletContext对象
  • this.getServletContext():直接通过动态资源HttpServlet获取ServletContext对象

方法

  1. String getMimeType(String file):获取项目中文件的MIME类型,比如text/html、image/jpeg

  2. setAttribute(String name,Object value):将键值对存储在项目域中

  3. getAttribute(String name):根据键获取项目域中的值

  4. removeAttribute(String name):根据键删除项目域中的键值对

    request域中的共享数据只有在一次请求范围内的资源才可以共享;而ServletContext对象对应的项目域中的共享数据可以被整个项目中的所有资源共享,所有用户的所有请求的资源都可以共享。

  5. String getRealPath(String path):获取文件的真实路径,也就是服务器路径

    e.g.

    String b = context.getRealPath("/filename");

    这句是获取项目中web目录下的文件部署在tomcat上后的绝对路径
    String c = context.getRealPath("/WEB-INF/filename");

    这句是获取项目中web/WEB-INF目录下的文件部署在tomcat上后的绝对路径
    String a = context.getRealPath("/WEB-INF/classes/filename");

    这句是获取项目中src目录下的文件编译并部署在tomcat上后的绝对路径

    • 项目文件部署到tomcat上之后,其实这些文件就是放在了idea项目中的out/artifacts文件夹中。
    • 在工作空间中编写web项目时,一般src文件夹中只放java源代码文件,静态资源、配置文件、图片附件等都放在web文件夹中,jar包放在web/web-inf/lib文件夹中。
    1
    2
    3
    4
    ServletContext servletContext = request.getServletContext();
    String path = servletContext.getRealPath("/img/"+"welcome.jpg");
    //就一个filename本来就不够,前面要加/才是资源路径。
    //而且寻找web中文件真实路径时,注意要把文件夹名称也加上,该方法只能先帮我们找到web文件夹的路径。
    • 该方法只能先帮我们找到web文件夹的路径,剩下的文件夹目录要我们自己加上。(项目部署到tomcat服务器上之后,原来工作空间中的web文件夹结构保持不变)

会话技术

会话:浏览器第一次给服务器资源发送请求,会话就建立了,直到有一方断开即结束会话,一次会话中可以包含多次请求和响应。会话技术的主要功能就是为了在一次会话的多此请求之间,共享数据,这个功能主要通过项目中Servlet动态资源创建的Cookie对象和Session对象实现。其中Cookie对象主要用于客户端会话技术,Session主要用于服务器端会话技术。

Cookie相关方法

Cookie对象的主要作用就是将数据保存到客户端中

  1. new Cookie(String name, String value):在动态资源中创建Cookie对象,绑定数据。从Cookie对象的初始化方法也可以看出,每一个Cookie对象本质上就是一个键和值都为字符串的键值对。一次会话中可以有多个Cookie对象。
  2. response.addCookie(Cookie cookie):将Cookie对象从服务器中发送到浏览器中。只有将Cookie对象发送到浏览器中后,该对象才能成为本次会话中的共享数据。在每次浏览器发送请求时,请求信息都会将该共享数据放在cookie请求头中。
  3. Cookie[] request.getCookies():获取会话中的所有Cookie,返回一个Cookie对象数组。
  4. Cookie.setMaxAge(int seconds):会话共享数据持久化存储方法。输入参数为会话共享数据在硬盘中的存活时间,当输入参数为非正数时,表示不进行持久化存储。
  • cookie对象主要用于浏览器用户在不登陆的情况下,完成服务器对客户端的身份识别。

使用案例

1
2
3
4
5
6
7
8
9
10
String str = "hello cookie!";

//cookie不支持空格等特殊字符,我们先对数据进行URL编码才可以作为cookie信息,使用的时候再URL解码就行了。
String urlStr = URLEncoder.encode(str,"Utf-8");

//创建cookie对象。
Cookie c = new Cookie("msg",urlStr);

//将cookie对象作为响应数据的一部分发送给浏览器,这样Cookie中的数据才能成为会话共享数据。
response.addCookie(c);
  • URL使用utf-8字符集编码是将每一个中英文字符和特殊字符都编码成一个%加上两位十六进制数。实际上URL编码的主要意义和作用就是用国际通用字符组成的字符串,来代替包括特殊语言和特殊符号的字符串。
  • URLEncoder.encode(str, “UTF-8”);//字符串url编码,方法输入和返回值都是字符串。
  • URLDecoder.decode(str, “UTF-8”);//字符串url解码,方法输入和返回值都是字符串。
1
2
3
4
5
6
7
8
9
10
11
//在另一个动态资源中。

Cookie[] cs = request.getCookies();
//遍历请求数据中的所有Cookie对象,并获取其中共享数据。

if (cs != null) {
for (Cookie c : cs) {
String str = URLDecoder.decode(c.getValue(),"utf-8");
//先将cookie信息中的url码数据进行解码为原来的字符串。
}
}

Session

Session相关方法

  1. HttpSession session = request.getSession():获取HttpSession对象,保存在服务器端
  2. Object HttpSession.getAttribute(String name):通过HttpSession中的键获取值
  3. void HttpSession.setAttribute(String name, Object value):将键值对存储到HttpSession对象中
  4. void HttpSession.removeAttribute(String name):通过HttpSession中的键删除值