Servlet和Http学习
1. Servlet概述
•Servlet是Server Applet的简称,意思为用Java编写的服务器端的程序,它运行在web服务器中,web服务器负责Servlet和客户的通信以及调用Servlet方法,Servlet和客户通信采用“请求/响应”的模式。
•Servlet的作用:
1.接收用户发送的请求
2.调用其他的java程序来处理请求
3.根据处理结果,服务器将响应返回给客户端
2. Servlet创建和使用
1.创建一个index.html,制作一个登录表单
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--
Http协议:超文本传输协议
超链接,提交表单都是属于http请求
一次请求中包含:请求头`请求行`请求体(表单post提交数据)
-->
<form action="login" method="post">
账号:<input type="text" name="account"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
2.在WEB_INF中创建lib包,存放jar包,添加jsp-api.jar和servlet-api.jar(地址https://mvnrepository.com)
3.导入jar包
4.jar包导入以后,选择应用,OK
5.创建.java文件,继承HttpServlet,重写父类方法
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import java.io.IOException;
public class LoginServlet_bank1 extends HttpServlet {
/*
* 在客户端第一次访问loginServlet时创建,服务器启动时创建
* 只被调用一次,只创建一个servlet对象 单实例的
* 在创建servlet时,应由servlet容器完成,创建实例应在init()之前
* */
public LoginServlet_bank1() {
System.out.println("LoginServlet无参构造方法");
}
/*
* 提供服务器
* 每次请求都会调用service
* */
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("service");
}
/*
* 初始化,在创建对象后,构造方法执行后,调用init方法,完成一些初始化操作
* 只执行一次
* 如果没有初始化操作可以不用重写init()方法,服务器会调用init(),调用父类中的方法
* */
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println(config.getInitParameter("count"));
System.out.println("init");
}
/*
在服务器关闭前,servlet销毁之前调用
可以在此方法中完成一些最终操作,比如保存日志
如果没有最终操作,可以不用重写,但会调用父类中的destory方法
*/
@Override
public void destroy() {
System.out.println("destroy");
}
}
6.在WEB-INF中web.xml进行配置
web.xml:用于存储Web项目配置信息,在服务器启动时,由服务器读取
xml可扩展标展标记语言,主要用于存储数据
<!-- 配置servlet-->
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>com.ff.firstWeb.serverlet.LoginServlet</servlet-class>
<!--配置初始化参数-->
<init-param>
<param-name>count</param-name>
<param-value>111111</param-value>
</init-param>
<!-- 值<0,第一次访问时创建. 值>=0,在服务器启动时创建 -->
<load-on-startup>0</load-on-startup>
</servlet>
<!--
给servlet配置一个访问地址,映射
反射机制可以根据类的地址动态创建对象
-->
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
7.启动,即可向服务器发送请求
3.Servlet的生命周期
4.Http协议
什么是HTTP?
超文本传输协议 (HyperText Transfer Protocol)服务器传输超文本到本地浏览器的传送协议,是互联网上应用最为流行的一种网络协议,用于定义客户端浏览器和服务器之间交换数据的过程。
HTTP是一个基于TCP/IP通信协议来传递数据.
HTTP是一个属于应用层的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统.
5.Http请求
目前将http请求分为:
1.get:主要从古武器获取数据,也可以向服务器发送数据,数据在地址中传递,会在地址栏中显示
超链接
在浏览器地址栏中直接输入地址访问
js
window.open(url)
location.assign(url)
location.replace(url)
表单:method="get"
2.post:向服务器发送数据,提交数据在请求体发送,长度没有限制,数据在请求中相对安全
表单:method="post"
get和post的区别
get:主要用于从服务器获取数据
也可以向服务器发送数据,数据在地址中传输,会在地址栏中显示
长度有限制
相对不安全
post:主要用于向服务器发送数据
提交数据在请求体中发送,长度没有限制
数据在请求体中相对安全
HttpServletRequest是ServletRequest的子接口
HttpServletRequest比ServletRequest多了一些针对于Http协议的方法。
请求和响应是Web交互最基本的模式,在Servlet中,用HttpServletRequest来表示请求。
HttpServletRequest :封装了请求的信息,可以从中获取任何请求信息。
获取客户端/服务器信息
getMethod()//得到客户机请求方式
getScheme()//请求协议
getRemoteAddr()//返回发出请求的客户机的IP地址
getServerName()//服务器名(ip或域名)
getServerPort()//服务器端口
getParameter(name) //--- String 通过name获得值
getParameterValues //--- String[ ] 通过name获得多值
package com.ff.firstWeb.serverlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Enumeration;
public class LoginServlet_bank2 extends HttpServlet {
/*
无参构造方法默认存在
init()可以不用重写,会调用父类的方法
servlet可以调用父类的
get请求--doGet()
post请求--doPost()
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet");
String name = req.getParameter("name");
String age = req.getParameter("age");
System.out.println(name+"::"+age);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
System.out.println("doPost");
String acount = req.getParameter("acount");
String password = req.getParameter("password");
String sex = req.getParameter("sex");
String work = req.getParameter("work");
String[] course = req.getParameterValues("course");
System.out.println(acount+"::"+password+"::"+sex+"::"+work+"::"+ Arrays.toString(course));
//请求接收中的数据(请求行,请求头)
/*System.out.println(req.getMethod());
System.out.println(req.getRemoteAddr());
System.out.println(req.getServerName());
System.out.println(req.getServerPort());
System.out.println(req.getScheme());
System.out.println(req.getProtocol());
System.out.println(req.getContentType());
System.out.println(req.getContextPath());
System.out.println(req.getHeader("User-Agent"));
Enumeration<String> headerNames = req.getHeaderNames();
while (headerNames.hasMoreElements()){
String name = headerNames.nextElement();
System.out.println(name+":"+req.getHeader("name"));
}*/
//向客户端做出相应,本质使用IO字符输出流
PrintWriter out = resp.getWriter();
}
}
6.Http响应
一个http响应代表服务器向客户端回送的数据,它包括:响应行,响应头,响应体。
响应行里包含了http协议版本,以及用于描述服务器对请求的处理结果。
HTTP/1.1 (协议版本) 200(状态吗) OK(状态码描述)
状态码:服务器和浏览器用于确定状态的固定数字号码
200:请求成功
302:请求重定向
400:语义有误,当前请求无法被服务器理解或请求参数有误
404:请求资源不存在,通常是路径写错了或者服务器资源删除了
500:服务内部错误(代码异常)
响应头用于描述服务器的基本信息,以及数据描述
Server Apache-Coyote/1.1
Content-Type text/html;charset=UTF-8
Content-Length 0
Date Wed, 13 Sep 2017 02:26:07 GMT
响应体代表服务器向客户端浏览器回送的正文
package com.ff.firstWeb.serverlet;
import com.ff.firstWeb.dao.checkDao;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class LoginServlet extends HttpServlet {
/*
无参构造方法默认存在
init()可以不用重写,会调用父类的方法
servlet可以调用父类
get请求--doGet()
post请求--doPost()
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String account = req.getParameter("account");
String password = req.getParameter("password");
//设置响应内容的编码格式
resp.setHeader("content-type","text/html;charset=utf-8");
//向客户端做出相应,本质使用IO字符输出流
PrintWriter out = resp.getWriter();
Connection connection = null;
try {
if (checkDao.link(account, password)) {
int x = 10/0;
String ip = req.getRemoteAddr();
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String login_time = dateFormat.format(date);
checkDao.insert(account,ip,login_time);
out.print("登陆成功");
} else {
out.print("密码或账户错误");
}
} catch (Exception throwables) {
throwables.printStackTrace();
resp.sendRedirect("505.jsp");
}
}
}
8.jsp的引入(解决复杂动态页面的响应)
package com.ff.firstWeb.serverlet;
import javax.servlet.ServletException;
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 LoginServlet_bank3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
System.out.println("doPost");
String acount = req.getParameter("acount");
String password = req.getParameter("password");
System.out.println(acount+"::"+password);
//设置响应内容的编码格式
resp.setHeader("content-type","text/html;charset=utf-8");
//向客户端做出相应,本质使用IO字符输出流
PrintWriter out = resp.getWriter();
if (acount.equals("admin") && password.equals("111")){
//早期的动态页面就是从servlet中输出的
out.print("登陆成功");
out.print("<Html>");
out.print("<head>");
out.print("</head>");
out.print("<body>");
for (int i = 0; i < 10; i++) {
out.print("<h1>"+i+"</h1>");
}
out.print("</body>");
out.print("</Html>");
//问题:响应的页面十分复杂
//解决方法:使用jsp的动态页面,本质也是servlet,作用是向客户端响应内容
}else{
out.print("账号或密码失败");
}
}
}
在jsp中书写java代码需要<%%>包含起来
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<% for (int i = 0; i < 10; i++) {%>
<h1>动态信息<%System.out.println(i)%></h1>
<%
}
%>
</body>
</html>