XML

xml是什么?
xml是一种表示数据的格式,按照xml规则编写的文本文件称为xml文件。
xml:可扩展标记语言。
百度百科:https://baike.baidu.com/item/可扩展标记语言/2885849?fromtitle=xml&fromid=86251
html也是标记语言,html里面的标记是固定的,每个标记有自己的功能。
xml里面的标记我们可以自己定义。
xml用来表示数据,用来做数据传输。

xml用干什么?
在后续的web开发中很多配置文件,都使用xml来编写。
使用xml编写配置文件,结构清晰,配置清楚。

xml用来?
编写配置文件
数据传输
加入有一个手机APP客户端,是一个网上商城的软件,打开软件需要显示商品列表。那么这个商品列表的数据就可以使用xml来传输。

xml语法
大小写敏感
有开始标记必须有结束标记(标记是成套的)
标记可以是单标记,但必须自己闭合
标记可以包含标记(可以嵌套,嵌套成对嵌套)
标记可以有自己的属性(属性值必须加引号)
标记里面可以有内容
必须有根标记,也叫做根元素。(根元素是其他元素的父元素)

xml文档声明
必须放在第一行

标记命名
区分大小写
不能使用空格和冒号
不建议以XML xml Xml 等跟xml相关名字

xml中特殊符号的表示
http://www.w3school.com.cn/xml/xml_syntax.asp

注释
平时编写xml文件的时候,是没有固定规则的,标记名,属性名,属性值我们可以按照我们的需求随意来开发。
但是当我们使用别人的框架的时候,一般需要提供一个配置文档,来配置我们使用这个框架的时候的一些属性。这个时候,这个配置文档就需要按照框架的要求来编写。框架的要求就是对xml文档的约束。我们可以通过DTD和Schema文档来编写对文档的约束。

对XML的约束
DTD,Schema

定义了约束之后,可以防止我们写错文档
比如某个配置文件,按照相同的约束来书写,更容易让别人阅读和别的程序读取。

什么是DTD
DTD用来约束xml文档,规定xml文档中元素的名称,子元素的名称和顺序,元素的属性。
一般来说我们很少编写自己的DTD文档约束,我们一般会遵循框架提供的DTD约束文档来编写配置文件。

当我们编写的xml不符合DTD约束规则的时候,会报错,方便我们找错。

怎么引入DTD约束
http://www.w3school.com.cn/dtd/dtd_intro.asp
1,内部引入(少用)
2,外部引入(本地)
3,外部引入(网络)常用
示例:Struts框架的配置文档的首行
<!DOCTYPE validators PUBLIC “-//Apache Struts//XWork Validator 1.0.3//EN”
http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">

schema约束(比DTD牛逼,替代DTD)
schema约束文档本身也是一个xml文档,后缀为xsd
语法更加容易阅读,更加友好
功能更加强大,类型更加完善
里面有命名空间

同样,我们也不需要写schema约束文档,我们只需要直接使用框架提供给我们的约束文档即可。

schema文档的使用
http://www.w3school.com.cn/schema/schema_howto.asp

Schema命名空间作用:
程序中
java.util.Date
java.sql.Date

Date d = null;
java.util.Date d = null;

Schema命名空间同理

xml解析方式
DOM方式

DOM文档对象模型(树形结构)
DOM方式解析,就是把xml文档加载到内存形成树形结构,可以进行增删改的操作。

xml里面的dom
html里面的dom
差不多,都是用来解析标签的,解析成一个树,并得到一个document对象。

我们可以使用dom4j来进行dom方式的解析。
https://dom4j.github.io/
dom4j是一个开源是xml解析软件包。

解析的时候需要做的事情
1,解析根元素
2,解析有哪些子元素
3,解析一个元素又哪些属性
4,得到元素的文本内容
5,修改、添加、删除某个元素节点
6,修改、添加、删除某个属性

dom4j解析xml 代码
https://blog.csdn.net/qq_24065713/article/details/77970469

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <goodslist>
  3. <!-- 下面是商品信息 -->
  4. <good id="10001" birthday="2018-4-1">
  5. <price>12</price>
  6. <name>香蕉</name>
  7. <place>广州</place>
  8. </good>
  9. <good id="10002">
  10. <price>39</price>
  11. <name>苹果</name>
  12. <place>北京</place>
  13. </good>
  14. <good>
  15. <price>33</price>
  16. <name>&lt;芒果</name>
  17. <place>广州&amp;</place>
  18. </good>
  19. <good>
  20. <price>12</price>
  21. <name>香蕉</name>
  22. <place>广州</place>
  23. </good>
  24. <Font></Font>
  25. <Good></Good>
  26. <good></good>
  27. <xxxx/>
  28. <!-- 约束 :约束文档
  29. DTD
  30. Schema
  31. -->
  32. </goodslist>
  1. import java.util.Iterator;
  2. import org.dom4j.Attribute;
  3. import org.dom4j.Document;
  4. import org.dom4j.DocumentException;
  5. import org.dom4j.Element;
  6. import org.dom4j.QName;
  7. import org.dom4j.io.SAXReader;
  8. public class ParseXML {
  9. public static void main(String[] args) throws Exception {
  10. SAXReader reader = new SAXReader();
  11. Document document = reader.read("src/NewFile.xml");
  12. Element root = document.getRootElement();//得到根节点
  13. System.out.println(root.getName());//goodslist
  14. Iterator<Element> it = root.elementIterator();
  15. while(it.hasNext()) {
  16. Element ele = it.next();
  17. if(ele.getName().equals("good")) {
  18. Element name = ele.element("name");
  19. if(name!=null)
  20. System.out.println(name.getText());
  21. /*香蕉
  22. 苹果
  23. <芒果
  24. 香蕉
  25. */
  26. }
  27. //System.out.println(ele.getName());
  28. /*获取所有子节点
  29. good
  30. good
  31. good
  32. good
  33. Font
  34. Good
  35. good
  36. xxxx
  37. */
  38. Iterator<Attribute> attributes= ele.attributeIterator();
  39. while(attributes.hasNext()) {
  40. Attribute ab = attributes.next();
  41. System.out.println(ab.getName()+":"+ab.getValue());
  42. /*
  43. id:10001
  44. birthday:2018-4-1
  45. id:10002
  46. * */
  47. }
  48. }
  49. //总结:
  50. //xml:Element Attribute
  51. }
  52. }

dom4j生成xml

  1. import java.io.FileWriter;
  2. import java.io.IOException;
  3. import org.dom4j.Document;
  4. import org.dom4j.DocumentHelper;
  5. import org.dom4j.Element;
  6. public class CreateXML {
  7. public static void main(String[] args) throws Exception {
  8. Document document = DocumentHelper.createDocument();
  9. Element root = document.addElement("root");
  10. Element author1 = root.addElement("author")
  11. .addAttribute("name", "James")
  12. .addAttribute("location", "UK")
  13. .addText("James Strachan");
  14. author1.addElement("sikiedu.com");
  15. Element author2 = root.addElement("author")
  16. .addAttribute("name", "Bob")
  17. .addAttribute("location", "US")
  18. .addText("Bob McWhirter");
  19. FileWriter out = new FileWriter("foo.xml");
  20. document.write(out);
  21. out.close();
  22. }
  23. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <root>
  3. <author name="James" location="UK">James Strachan<sikiedu.com /></author>
  4. <author name="Bob" location="US">Bob McWhirter</author>
  5. </root>

本章讲东西,蛮有用的,不会立即用到,会在后面的开发中慢慢接触到。

JavaWeb基础(JSP)

Java Web和Java EE的区别
Java Web就是以Java语言为基础,使用JSP和Servlet来开发Web程序。Web程序简单理解就是我们平时说的网站。
Java EE是Java的企业级应用,里面包含的功能比较多。JavaEE是个大杂烩,包括Applet、EJB、JDBC、JNDI、Servlet、JSP等技术的标准,运行在一个完整的应用服务器上,用来开发大规模、分布式、健壮的网络应用。这里的网络应用也可以理解为我们平时使用的网站。
可以粗略地认为JavaWeb就是JavaEE的一部分,是成为JavaEE大师过程中的第一站。
https://www.zhihu.com/question/52002845/answer/364360839

使用Java EE开发的应用
国内:淘宝,京东,工行的网银,12306 …
国外:http://www.sohu.com/a/107889267_411661

学习Java Web首先要学习的两门技术
JSP Servlet

JSP和Servlet前置技术
前端技术:HTML、CSS、JavaScript
编程技术:Java语言编程
数据库:MySQL、Oracle、SQL Server

后续学习
SSM SSH框架
SSM:Spring SpringMVC MyBatis
SSH:Spring Struts Hibernate

JSP是什么
百度百科:https://baike.baidu.com/item/JSP/141543?fr=aladdin
简单来说JSP = html + Java代码
在一个正常的网页上,加入java代码之后,就成为了一个jsp页面。

JSP用来开发动态页面
什么是静态页面,什么是动态页面!
SiKi学院的首页,登录后用户名的显示。
静态页面上的内容(文字、图片)是不改变的。Web前端工程师开发出来后的页面就是一个静态页面。我们后端人员需要把静态页面变成动态页面。

Java Web开发需要的软件
JDK 8
Eclipse IDE For Java EE
Tomcat
32还是64位根据自己的电脑选择

Tomcat是干什么的
Eclipse编写代码—->.java—->jdk——>.class—->jre运行
image.png
Eclipse编写代码—->.jsp/servlet—>tomcat运行
image.png

Eclipse配置多个Tomcat
Windows->Preperences->Server->Runtime Environments->Add->选择Tomcat版本->点击Browse选择Tomcat目录添加即可。

怎么在jsp页面上写java代码
<%
%>
这个东西可以多次出现
实现一个显示当前登录的用户名

jsp内容输出表达式
<%= %>

jsp中java代码可以和页面html代码组合使用

成员变量和局部变量
一个jsp对应一个java类,运行的时候,一个jsp会创建一个对应的java对象。
<%! %> jsp定义表达式 定义变量
<%! %>和<% %>变量的区别:在<%! %>里面定义的变量是成员变量,而<%— —%>里面的是局部变量
<%= %>内容输出表达式 ,例如<%=str %>

注释
<%— —%>
不起任何实际作用
还可以注释 <% %>
在java代码中依然可以使用java支持的注释

jsp引入java类(按Alt+/可以自动导入)
<%@page import=”java.util.Random”%>
<%@page import=”java.util.Random,java.text.*”%>

http协议和jsp内置对象

什么是协议
当我们跟别人合作的时候,需要是先定义好双方要做的事情,利益怎么分配等事情。免得在合作的时候出现分歧。

什么是http协议
http协议规定了我们在发起http请求的时候,这个请求的数据包里面都包含了什么样的数据
以及数据按照什么样的先后顺序存放在数据包里面。

http请求和http响应
https://blog.csdn.net/chen1403876161/article/details/51546653

Get方式请求和响应的数据包:
无参:
image.png

带参数:
jsp中可以使用request.getParameter(“user”)和request.getParameter(“password”)进行接收。
image.png

POST方式请求和响应的数据包:
jsp中创建一个登录表单:

  1. <form action="login.jsp" method="post">
  2. <input type="text" name="username"/>
  3. <Input type="password" name="password"/>
  4. <input type="submit" value="提交"/>
  5. </form>

image.png

什么是jsp的内置对象
不需要声明,不需要创建,就可以直接使用的对象,就是内置对象。
九大内置对象。

request:客户端向服务器端发起请求时,服务器端获取客户端的一些信息
response:服务器端向客户端给出一些响应
out

案例:登录注册

总览:
image.png
用户数据类:User.java

  1. package com.siki.model;
  2. public class User {
  3. private String username;
  4. private String password;
  5. private int age;
  6. private String sex;
  7. public User(String username, String password, int age, String sex) {
  8. super();
  9. this.username = username;
  10. this.password = password;
  11. this.age = age;
  12. this.sex = sex;
  13. }
  14. public String getUsername() {
  15. return username;
  16. }
  17. public void setUsername(String username) {
  18. this.username = username;
  19. }
  20. public String getPassword() {
  21. return password;
  22. }
  23. public void setPassword(String password) {
  24. this.password = password;
  25. }
  26. public int getAge() {
  27. return age;
  28. }
  29. public void setAge(int age) {
  30. this.age = age;
  31. }
  32. public String getSex() {
  33. return sex;
  34. }
  35. public void setSex(String sex) {
  36. this.sex = sex;
  37. }
  38. }

数据库处理工具类:DBUtil.java

  1. package com.siki.util;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import com.siki.model.User;
  5. public class DBUtil {
  6. public static Map<String, User> userMap = new HashMap<String, User>();
  7. // 添加用户到数据库,这里用map代替
  8. public static boolean addUser(String username, String password, int age, String sex) {
  9. if (userMap.containsKey(username)) {
  10. return false;
  11. } else {
  12. User user = new User(username, password, age, sex);
  13. userMap.put(username, user);
  14. return true;
  15. }
  16. }
  17. // 验证用户信息是否正确
  18. public static User verifyAccount(String username, String password) {
  19. if (userMap.containsKey(username)) {
  20. User user = userMap.get(username);
  21. if (user.getPassword().equals(password)) {
  22. return user;
  23. } else {
  24. return null;
  25. }
  26. }
  27. return null;
  28. }
  29. }

主页:index.jsp。很简单,就登录和注册两个按钮。分别跳转到login.jsp登录页面和register.jsp注册页面。如果有登录用户,则显示当前登录用户。并显示网站登录人数。

  1. <%@page import="com.siki.model.User"%>
  2. <%@ page language="java" contentType="text/html; charset=utf-8"
  3. pageEncoding="utf-8"%>
  4. <!DOCTYPE html>
  5. <html>
  6. <head>
  7. <meta charset="utf-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  11. <%
  12. Object o = session.getAttribute("user");
  13. if(o != null)
  14. {
  15. User user = (User)o;
  16. out.println("当前登录用户:" + user.getUsername()+"<br>");
  17. }
  18. %>
  19. <%
  20. Object o2 = application.getAttribute("userNum");
  21. if(o2 != null)
  22. {
  23. out.println("当前登录用户数:" + o2+ "个<br>");
  24. }
  25. %>
  26. <a href="login.jsp">登录</a><br>
  27. <a href="register.jsp">注册</a><br>
  28. </body>
  29. </html>

登录页面:login.jsp。一个输入用户名密码的表单,点击登录跳转到login_do.jsp处理请求。如果有数据msg转发过来就显示相应信息。如果有登录用户,则显示当前登录用户。

  1. <%@page import="com.siki.model.User"%>
  2. <%@ page language="java" contentType="text/html; charset=utf-8"
  3. pageEncoding="utf-8"%>
  4. <!DOCTYPE html>
  5. <html>
  6. <head>
  7. <meta charset="utf-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  11. <%
  12. User user = (User)session.getAttribute("user");
  13. if(user != null)
  14. {
  15. out.println("当前登录用户:" + user.getUsername()+"<br>");
  16. }
  17. %>
  18. <%
  19. Object msg=request.getAttribute("message");
  20. if(msg!=null)
  21. out.println(msg);
  22. %>
  23. <br>
  24. 登录
  25. <hr>
  26. <form action="login_do.jsp" method="post">
  27. 用户名:<input type="text" name="username"/><br>
  28. 密码:<input type="password" name="password"/><br>
  29. <input type="submit" value="登录"/>
  30. </form>
  31. </body>
  32. </html>

处理登录请求页面逻辑:login_do.jsp。如果登录成功,转发请求到personCenter.jsp个人中心页面显示个人信息 ,否则返回登录页面重新登陆,并给出登陆失败提示。登录成功后在主页统计登录人数

  1. <%@page import="com.siki.model.User"%>
  2. <%@page import="com.siki.util.DBUtil"%>
  3. <%@ page language="java" contentType="text/html; charset=utf-8"
  4. pageEncoding="utf-8"%>
  5. <!DOCTYPE html>
  6. <html>
  7. <head>
  8. <meta charset="utf-8">
  9. <title>Insert title here</title>
  10. </head>
  11. <body>
  12. <%
  13. String username=request.getParameter("username");
  14. String password=request.getParameter("password");
  15. User user = DBUtil.verifyAccount(username, password);
  16. if(user == null)
  17. {
  18. //登录失败
  19. request.setAttribute("message", "<font color='red'>登录失败!用户名或密码错误!</font>");
  20. request.getRequestDispatcher("login.jsp").forward(request, response);
  21. }
  22. else
  23. {
  24. //登录成功后在主页统计登录人数
  25. int count = 0;
  26. if(application.getAttribute("userNum") != null)
  27. {
  28. count = (Integer)application.getAttribute("userNum");
  29. }
  30. count++;
  31. application.setAttribute("userNum", count);
  32. //登录成功,转发请求到personCenter.jsp。并保存用户到session
  33. session.setAttribute("user", user);
  34. request.getRequestDispatcher("personCenter.jsp").forward(request, response);
  35. }
  36. %>
  37. </body>
  38. </html>

注册页面:register.jsp。一个输入用户名相应信息的表单,点击注册跳转到register_do.jsp处理请求。如果有数据msg转发过来就显示相应信息。如果有登录用户,则显示当前登录用户。

  1. <%@page import="com.siki.model.User"%>
  2. <%@ page language="java" contentType="text/html; charset=utf-8"
  3. pageEncoding="utf-8"%>
  4. <!DOCTYPE html>
  5. <html>
  6. <head>
  7. <meta charset="utf-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  11. <%
  12. User user = (User)session.getAttribute("user");
  13. if(user != null)
  14. {
  15. out.println("当前登录用户:" + user.getUsername()+"<br>");
  16. }
  17. %>
  18. <%
  19. Object msg=request.getAttribute("message");
  20. if(msg!=null)
  21. out.println(msg);
  22. %>
  23. <form action="register_do.jsp" method="post">
  24. 用户名:<input type="text" name="username"/><br>
  25. 密码:<input type="password" name="password"/><br>
  26. 年龄:<input type="text" name="age"/><br>
  27. 性别:男<input type="radio" name="sex" value="男"/><input type="radio" name="sex" value="女"/><br>
  28. <input type="submit" value="注册"/>
  29. </form>
  30. </body>
  31. </html>

处理注册请求页面逻辑:register_do.jsp。如果注册成功,转发请求到login.jsp登录页面进行登录 ,否则返回注册页面重新注册,并给出注册失败提示。

  1. <%@page import="com.siki.util.DBUtil"%>
  2. <%@ page language="java" contentType="text/html; charset=utf-8"
  3. pageEncoding="utf-8"%>
  4. <!DOCTYPE html>
  5. <html>
  6. <head>
  7. <meta charset="utf-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  11. <%
  12. String username=request.getParameter("username");
  13. String password=request.getParameter("password");
  14. int age=Integer.parseInt(request.getParameter("age"));
  15. String sex=new String(request.getParameter("sex").getBytes("ISO-8859-1"),"utf-8");
  16. boolean isScuess=DBUtil.addUser(username, password, age, sex);
  17. if(isScuess)
  18. {
  19. //注册成功,请求转发给login页面并传递数据
  20. request.setAttribute("message", "注册成功!请登录!");
  21. request.getRequestDispatcher("login.jsp").forward(request, response);
  22. }
  23. else
  24. {
  25. request.setAttribute("message", "注册失败!用户名重复!");
  26. request.getRequestDispatcher("register.jsp").forward(request, response);
  27. }
  28. %>
  29. <%-- javahtml混写,注册成功和失败分别在网页上显示
  30. if(isScuess)
  31. {
  32. //out.println("<font color='green'>注册成功</font>");
  33. %>
  34. <font color='green'>恭喜!用户<%=username %>注册成功</font>
  35. <%
  36. }
  37. else
  38. {
  39. //out.println("<font color='red'>注册失败</font>");
  40. %>
  41. <font color='red'>注册失败</font>
  42. <%
  43. }
  44. %>
  45. --%>
  46. </body>
  47. </html>

个人信息页面:personCenter.jsp。登陆成功后显示个人信息。

  1. <%@page import="com.siki.model.User"%>
  2. <%@ page language="java" contentType="text/html; charset=utf-8"
  3. pageEncoding="utf-8"%>
  4. <!DOCTYPE html>
  5. <html>
  6. <head>
  7. <meta charset="utf-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  11. <%
  12. User user = (User)session.getAttribute("user");
  13. %>
  14. 用户名:<%=user.getUsername() %><br>
  15. 密码:<%=user.getPassword() %><br>
  16. 性别:<%=user.getSex() %><br>
  17. </body>
  18. </html>

案例补充

request和response生命周期

每次请求页面都会生成一个新的request对象,里面封装了请求时的一些数据。服务器也会生成一个response对象返回给客户端一些响应。每次请求完毕后request和response都会被销毁。即使请求的是用一个页面,也是新的request和response。所以不能通过直接请求页面request.serAttribute()传递数据。

Q:那为什么在register_do.jsp中注册成功访问login.jsp中却可以访问到数据呢?
A:因为register_do.jsp中将请求转发给了login.jsp(图1),两者是同一个request对象。就比如打客服电话10000,需办理宽带业务,客服10000不受理,帮你把业务转发给了10005,转发后虽然和你对话的是10005的客服,但实际上来电显示还是10000。
所以会发现,虽然显示的是login.jsp页面,但地址栏url实际还是register_do.jsp,如下图2。

而且通过代码:request.getRequestDispatcher(“xxx.jsp”).forward(request, response)也可以发现request和response被当做参数传递了出去。
image.png
image.png

关于getAttribute和getParameter

1,getAttribute表示从request范围取得设置的属性,必须要先setAttribute设置属性,才能通过getAttribute来取得,设置与取得的为Object对象类型
2,getParameter表示接收参数,参数为页面提交的参数,包括:表单提交的参数、URL重写(就是xxx?id=1中的id)传的参数等,因此这个并没有设置参数的方法(没有setParameter),而且接收参数返回的不是Object,而是String类型

登录成功后的跳转参数乱码

1、通过new String(xxx.getBytes(“ISO-8859-1”),”utf-8”)按照它原来的编码格式获得字节数组进行解码,然后按照utf-8重新编码,组成新的支持中文的字符串。
2、转发请求时request.setCharacterEncoding(“utf-8”);

SiKi学院的登录、注册、修改个人资料
首页显示 课程列表
对于登录请求
获取用户输入的用户名和密码request

**

pageContext
pageContext.forward(“xxx.jsp”);
pageContext.include(“xxx.jsp”);
pageContext.getRequest getResponse get..

page是jsp页面对应的类对象

内置对象session

session request 生命周期
image.png

session对象什么时候会被销毁

  • 关闭浏览器
  • 到达有效时间(长时间不操作网站,默认30min,可在tomcat中设置)

Q:如何通过session保存当前登录用户,使登录用户能够在各个页面之间显示?
A:通过session.setAttribute()。

内置对象application

整个tomcat只有一个,相当于整个网站。多个客户端访问也是同一个application。

为什么不用application保存数据?
1)因为所有客户端同享一个application,像某个客户端的用户名密码这种隐私数据其他所有客户端都能访问到,不安全。
2)某个客户端A的某类数据放到application中,其他客户端会覆盖掉相同类型的数据,这样A的数据就会丢失。

application中一般放的是所有客户端都需要的一些全局配置数据(比如统计某网站的登录人数)。
application是为所有客户端服务的,不是为某个客户端服务的。

web容器的生命周期
网站启动起来,创建一个applition,当网站关闭后,application被销毁。
一个web应用只有一个application对象。

JavaWeb基础(Servlet)

什么是Servlet

如果一个jsp页面单纯的只是处理逻辑,不做页面显示用的话,这个时候可以让这个请求交给Servlet来处理。

就像上述例子中的login_do.jsp和register_do.jsp,它们只是用来处理登录和注册的逻辑,不需要展示页面。所以里面混有html是不合理的。jsp应当只做展示。这时候Servlet的作用就体现出来了。

jsp适合做展示,servlet适合做逻辑处理。

Servlet在哪里创建
Servlet本质上也是一个类,继承自javax.servlet.http.HttpServlet

Servlet路径的两种配置方式

1,注解的方式。在类之前@WebServlet(“/xxx_do”)
2,xml配置文件
找到tomcat\webapps\examples\WEB-INF\web.xml复制到工程WEB-INF目录下

配置方式
servlet-name:servlet类别名,一般与类名保持一致。
servlet-class:servlet类完整的名字(包名+类名,注意没有后缀.java!)
url-pattern:servlet访问路径。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
  5. http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  6. version="3.1"
  7. metadata-complete="true">
  8. <servlet>
  9. <servlet-name>LoginServlet</servlet-name>
  10. <servlet-class>com.siki.servlet.LoginServlet</servlet-class>
  11. </servlet>
  12. <servlet-mapping>
  13. <servlet-name>LoginServlet</servlet-name>
  14. <url-pattern>/login_do</url-pattern>
  15. </servlet-mapping>
  16. </web-app>

利用servlet处理注册请求

将register_do的逻辑代码放到servlet,然后修改register.jsp表单的action为register_do。

  1. package com.siki.servlet;
  2. import java.io.IOException;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.annotation.WebServlet;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import com.siki.util.DBUtil;
  9. @WebServlet("/register_do")
  10. public class RegisterServlet extends HttpServlet {
  11. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  12. // TODO Auto-generated method stub
  13. response.getWriter().append("Served at: ").append(request.getContextPath());
  14. }
  15. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  16. String username=request.getParameter("username");
  17. String password=request.getParameter("password");
  18. int age=Integer.parseInt(request.getParameter("age"));
  19. String sex=new String(request.getParameter("sex").getBytes("ISO-8859-1"),"utf-8");
  20. boolean isScuess=DBUtil.addUser(username, password, age, sex);
  21. if(isScuess)
  22. {
  23. //注册成功,请求转发给login页面并传递数据
  24. request.setAttribute("message", "注册成功!请登录!");
  25. request.getRequestDispatcher("login.jsp").forward(request, response);
  26. }
  27. else
  28. {
  29. request.setAttribute("message", "注册失败!用户名重复!");
  30. request.getRequestDispatcher("register.jsp").forward(request, response);
  31. }
  32. }
  33. }

利用servlet处理登录请求

将login_do的逻辑代码放到servlet,然后修改login.jsp表单的action为login_do。

  1. package com.siki.servlet;
  2. import java.io.IOException;
  3. import javax.servlet.ServletContext;
  4. import javax.servlet.ServletException;
  5. import javax.servlet.annotation.WebServlet;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. import com.siki.model.User;
  10. import com.siki.util.DBUtil;
  11. @WebServlet("/login_do")
  12. public class LoginServlet extends HttpServlet {
  13. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  14. // TODO Auto-generated method stub
  15. response.getWriter().append("Served at: ").append(request.getContextPath());
  16. }
  17. /**
  18. * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
  19. */
  20. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  21. String username=request.getParameter("username");
  22. String password=request.getParameter("password");
  23. User user = DBUtil.verifyAccount(username, password);
  24. if(user == null)
  25. {
  26. //登录失败
  27. request.setAttribute("message", "<font color='red'>登录失败!用户名或密码错误!</font>");
  28. request.getRequestDispatcher("login.jsp").forward(request, response);
  29. }
  30. else
  31. {
  32. //登录成功后在主页统计登录人数
  33. int count = 0;
  34. ServletContext application = this.getServletContext();
  35. if(application.getAttribute("userNum") != null)
  36. {
  37. count = (Integer)application.getAttribute("userNum");
  38. }
  39. count++;
  40. application.setAttribute("userNum", count);
  41. //登录成功,转发请求到personCenter.jsp。并保存用户到session
  42. //session在jsp中是内置的,在servlet中获得当前请求所属的session使用request.getSession()
  43. //session.setAttribute("user", user);
  44. request.getSession().setAttribute("user", user);
  45. request.getRequestDispatcher("personCenter.jsp").forward(request, response);
  46. }
  47. }
  48. }
  • ServletContext(Servlet环境,就是jsp的内置对象之一)

整个工程可以认为是一个ServletContext对象(我们在jsp页面获取到的application)
可以认为ServletContext管理着生成的所有的Servlet
(ServletContext里面都可以存放东西,在其他任意地方都可以取)

  • 怎么获取application?

jsp里面:内置
servlet里面:this.getServletContext()

  • 怎么获取session?

jsp里面:内置
servlet里面:request.getSession()

  • 得到当前项目名

String basePath = “/“+request.getServletContext().getContextPath();

  • 给客户端响应输出内容

response.getWriter().append(“xxx”)

Servlet生命周期
第一次被请求的时候会调用init
每一次被请求会调用service方法
终止调用destroy

ServletConfig
一个Servlet有一些配置信息,一个Servlet对应的配置信息对应一个ServletConfig对象。
怎么获取?
this.getServletConfig();

转发和重定向

转发通过request
重定向通过response

转发
里面只有一个请求(可以通过request来传递数据)
浏览器地址不会发生改变

  1. //请求转发到login页面
  2. request.getRequestDispatcher("login.jsp").forward(request, response);

重定向
里面有两个请求(通过url传递数据)
通过application来传递数据,不这么做!!!
地址会发生改变

  1. //重定向到login页面
  2. request.sendRedirect("login.jsp");

两者显示区别:
请求转发:注册成功后会跳转到login.jsp页面。显示的是login.jsp页面,但是地址栏依然是register_do,并且能传递注册成功的信息。
重定向:注册成功后会跳转到login.jsp页面。显示的是login.jsp页面,地址栏也改变成login.jsp,并且无法传递注册成功的信息。

为什么会出现这种情况?
请求转发:url不会改变,虽然显示的是login.jsp的页面,但是url依然是register_do。同时数据也会传递过去。
重定向:首先客户端向服务器端发送了一次register_do请求,服务器端处理完请求给客户端响应,让客户端去访问login.jsp,然后客户端又发送了新的请求login.jsp。所以重定向地址url会改变为login.jsp。因为是重新又发起了一次请求,所以数据没法传递。

举例:
请求转发:比如打10086客服咨询某个问题,客服不清楚,帮你转发给了其他部门,由其他部门为你解答。这时跟你通话的虽然是其他部门的客服,但是来电显示依然是10086。实际只打了一次电话。
重定向:比如打10086客服咨询某个问题,客服不清楚,她给了你其他部门的电话。然后你挂掉电话后重新拨打了其他部门的电话进行咨询。这时跟你通话的是其他部门的客服,来电显示也不再是10086,而是这个部门的电话。实际是打了两次电话。
image.png