javaweb入门基础知识学习
1.Http协议
http是超文本传输协议,用于定义客户端浏览器与服务器之间交换数据的过程。先请求后响应。Http请求协议包括:请求行、请求头、请求体。Http响应协议包括:请求行、请求头、请求体。
http请求
请求行:POST /index.jsp HTTP/1.1
GET /get.html?name=xiaoming&passWord=123456 HTTP/1.1
(请求方式 资源路径 协议/版本)
请求头:
Host:1localhost:8080
Connection: keep-alive
Upgrade-Insecure-Requests:1
User-Agent: Chrome/58.0.3029.110 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: text/html, application/xhtml +xml, application/xml;q=0.9,image/webp,*/*;q=0.8
Refhrer: http://1ocalhost:8080/post. html Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.8, en;q=0.6
Cookie: Idea-cf2f8ff1=49d3921e-2812-464b-b68b-6c54c9b5cbc7.
JSESSIONID=8990466BFC3DCC6778D2A03630270A7D
请求体:name=xiaoming&passWord=123456 (GET请求没有请求体)
http响应
响应行:HTTP/1.1 200 OK
(协议/版本 状态码 状态码描述)
200 请求成功 302 请求重定向 400请求错误语法错误 403权限不够 404 资源不存在 500 服务器内部错误
响应头:
Accept-Ranges:bytes
ETag:W/"413-1495617981796"
Last-lModified:Wed,24 May 2017 09:26:21 GMT
Content-Type:text/html
Content-Length:413
Date:Wed,24 May 2017 09:29:37 GMT
响应体:服务器向浏览器返回的html正文
2.Servlet
交互式地浏览和修改数据,生成动态的Web内容。
在HTTP请求过程中会把请求的参数存放在请求行的URL中,或者是请求体中,这个参数需要服务器来接收解析并处理,Servlet就是用来处理这个过程的。
一个Servlet 2.0
1.继承HttpServlet
2.复写HttpServlet中的doGet()、doPost()
3.配置web.xml
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>httphello</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hi</url-pattern>
</servlet-mapping>
4.部署项目并通过浏览器访问servlet
一个Servlet 3.0
注解:
@WebServlet(name = "TestServlet",urlPatterns = "/hello")
2.1 HttpServletRequest
在Servlet的API中,定义了一个HttpServletRequest接口,它继承自ServletRequest接口,专门用于封装HTTP的请求,由于HTTP请求包含着请求行、请求头和请求体三部分,因此在HttpServletRequest中分别定义了接收请求行、请求头和请求体的相关方法。
请求行:
request.getMethod(); //请求方式
request.getRequetURI(); //request.getRequetURL() 请求资源
request.getProtocol(); //请求http协议版本
request.getRemoteAddr(); //发出请求客户端IP地址
request.getLocalAddr(); //服务器接收请求的IP地址
request.getRemotePort(); //访问客户端的端口号
请求头:
request.getHeader("name") //根据name,获取对应请求头数据
request.getHeaderNames() //获取所有的请求头名称返回类型Enumeration
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
System.out.println(name+":"+request.getHeader(name));
}
请求参数:
request.getParameter("参数名"); //根据参数名获取参数值(注意,只能获取一个值的参数)
request.getParameterValue("参数名“); //根据参数名获取参数值(可以获取多个值的参数)
request.getParameterNames(); //获取所有参数名称列表 返回类型Enumeration
request.getParameterMap(); //该方法用于将请求中的所有参数和值装入一个map对象然后返回
1.访问html文件(html中action提交的Servlet)
2.调用对应的Servlet中的方法,获取html中对应参数的内容
3.输出在对应位置。
2.2 HttpServletResponse
在Servlet的API中,定义了个HttpServletResponse接口,它继承自ServletResponse接口,专门用于封装HTTP的响应,由于HTTP响应包含着响应行、响应头和响应体三部分,因此在HttpServletResponse中分别定义了发送响应行、响应头和响应体的相关方法。
响应行:
setStatus(int status); //状态码200
sendError(int code); //错误信息的状态码404
响应成功了,需要第一个,sendError是返回页面的。
响应头:
百度
响应消息体:
由于在HTTP响应消息中,大量的数据都是通过响应体传递的,因此ServletResponse遵循以I0流传递大数据的设计理念,定义了两个与输出流相关的方法,具体如下:
1.getoutputStream()方法:该方法获取的字节流输出对象为ServletOutputStream类型,它是0utputStream的子类,因此可以直接输出字节数组中的二进制数据。
2.getWrite()方法:该方法获得的字符输出流对象是PrintWriter类型由于它可以直接输出文本类型,因此要输出网页文档,需要使用这个方法
2.3 Servlet生命周期
第一次:
判断Servlet实例是否存在?
> 装载Servlet类并创建实例
> 调用init(ServletConfig)方法
> 调用service(ServletRequest,ServletResponse)方法
> 调用对应的doGet doPost方法
服务器关闭?
>调用destroy()方法。
第二次:
判断Servlet实例是否存在?
> 调用service(ServletRequest,ServletResponse)方法
注意:Servlet实例是单例的,即无论请求多少次Servlet,最多只有一个Servlet实例,如果是多个客户端并发,同时访问Servlet的时候,服务器会启动多个线程分别执行Servlet的service方法
原因:如果我们每次访问都创健一个Servlet实例,会占用和浪费过多的计算机资源
2.3.1 ServletConfig对象
ServletConfig对象是它所对应的Servlet对象的相关配置信息,在web.xml中比如编码
@Override
public void init() throws ServletException {
super.init();
ServletConfig servletConfig = this.getServletConfig();
String encoding = servletConfig.getInitParameter("encoding");
System.out.println(encoding);
}
2.3.2 ServletContext对象
ServletContext定义:ServletContext即Servlet上下文对象,该对象表示当前的web应用环境信息,如果每个Servlet都配置编码,太累了。这个对象用于全局对象,在多个Servlet之间共享参数。
在web.xml中配置初始化参数:
<context-param>
<param-name>参数名</param-name>
<param-value>参数值</param-value>
</context-param〉
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String encoding = this.getServletContext().getInitParameter("encoding");
System.out.println(encoding);
}
2.使用ServletContext在多个Servlet*享数据
·void setAttribute(String name,Object object);存放数据
·Object getAttribute(String name);获取数据
·void removeAttribute(String name);删除数据
2.4 Servlet 转发重定向
请求转发是一次请求一次响应;
重定向是两次请求两次响应;
请求转发:
重定向:
response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);//302
response.setHeader("Location","https://www.baidu.com");
或者:
response.sendRedirect("https://www.baidu.com");
2.5自动刷新跳转页面
response.setContentType("text/html;chatset=utf-8");
response.setHeader("refresh","3;url='/home.html'");
response.getWriter().print("3秒后自动刷新");
JSP中实现自动刷新:
<meta http-equiv='refresh' content='3:url=/hello/honme.html'>
2.6 文件下载
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String filename = request.getParameter("filename");
//告诉浏览器,需要下载不是打开
String mimeType = this.getServletContext().getMimeType(filename);
response.setContentType(mimeType);
response.setHeader("Content-Disposition", "attachment;filename=" + filename);
//获取文件的绝对路径
String realPath = this.getServletContext().getRealPath(filename);
FileInputStream in = new FileInputStream(realPath);
ServletOutputStream outputStream = response.getOutputStream();
//文件拷贝
int len = 0;
byte[] buffer = new byte[1024];
while ((len = in.read(buffer) )>0) {
outputStream.write(buffer, 0, len);
}
in.close();
outputStream.close();
}
3.Cookie、Session会话
request无法完成多个Servlet数据共享,ServletContext可以但是不能为每个客户端保存数据。
3.1Cookie
将数据存储在客户端的本地,在本地清除后,数据消失。存储在response中的响应头中set-cookie。请求其他Servlet时通过request携带cookie在请求头中带过去。
问题:
1.服务器如何发送cookie给客户端浏览器?
Cookie cookie = new Cookie("goods", "cup");
cookie.setMaxAge(60*10);//持久化
cookie.setPath("/hello/getCookieServlet")//携带路径
response.addCookie(cookie);
//访问其他网站时候不携带cookie信息,当浏览器重启后,cookie也会消失。所以要设置cookie持久化时间。
//如果不设置携带路径,那么该cookie信息会在访问产生该cookie的web资源的所有路径都携带cookie信息。
//cookie.setMaxAge(0);//删除cookie
2.服务器如何获取cookie信息?
Cookie[] cookies = request.getCookies();
for (Cookie cookie1 : cookies) {
String name = cookie1.getName();
if (name.equals("goods")) {
String cookie1Value = cookie1.getValue();
response.getWriter().write("goods"+cookie1Value);
}
}
记录上一次访问网站的时间:
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd-hh:mm:ss");
String time = simpleDateFormat.format(date);
Cookie cookie = new Cookie("time",time);
cookie.setMaxAge(60 * 60 * 24);
response.addCookie(cookie);
response.setContentType("text/html;charset=utf-8");
//获取客户端传来的cookie
Cookie[] cookies = request.getCookies();
String timeValue = null;
for (Cookie cookie1 : cookies) {
if (cookie1.getName().equals("time")) {
timeValue= cookie1.getValue();
}
}
if (timeValue == null) {
response.getWriter().write("欢迎您访问网站");
}
response.getWriter().write("您上次访问的时间:" + timeValue);
3.2 Session
数据存储在服务器,基于cookie,唯一性标识JSESSIONID。
1.获取session
HttpSession session = request.getSession();
String id = session.getId();
2.存取数据
session.setAttribute("goods","cup");
session.getAttribute("goods");
session.removeAttribute("good");
3.生命周期
第一次执行request.getSession();就创建了,
设置过期消失时间(默认30分钟) 或者 服务器关闭的时候。
web.xml
<session-config>
<session-timeout>10</session-timeout>
</session-config>
4.session持久化
cookie中存储着JSESSIONID。关闭浏览器cookie消失了,JSESSIONID也就没有了。所以要对cookie进行持久化。
Cookie cookie = new Cookie("JSESSIONID",session.getId());
cookie.setMaxAge(60 * 60 * 24);
response.addCookie(cookie);
5.购物车简单案例
@WebServlet(name = "AddCartServlet",urlPatterns = "/addCart")
public class AddCartServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.获取商品信息
String name = request.getParameter("name");
// 2.需要保存商品信息到session
HttpSession session = request.getSession();
List list = (List) session.getAttribute("list");
//第一次访问的时候,购物车list不存在
response.setContentType("text/html;charset=utf-8");
if (list == null) {
list = new ArrayList();
}
list.add(name);
session.setAttribute("list", list);
//session 持久化
Cookie cookie = new Cookie("JSESSIONID",session.getId());
cookie.setMaxAge(60 * 60 * 24);
cookie.setPath("/hello");
response.addCookie(cookie);
}
}
@WebServlet(name = "GetCartServlet",urlPatterns = "/getCart")
public class GetCartServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
List<String> list = (List<String>) session.getAttribute("list");
response.setContentType("text/html;charset=utf-8");
for (String s : list) {
response.getWriter().write(s+"<br>");
}
}
}
<body>
<h1>商品列表</h1>
<a href="/addCart?name=杯子">杯子</a>
<a href="/addCart?name=书包">书包</a>
<a href="/addCart?name=笔记本">笔记本</a>
</body>
4.request和session的区别
request对象和session对象的最大区别是生命周期
session作用域更大,可以实现会话跟踪。
5.过滤器Filter
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
6.三大域与监听器
// request 请求域生命周期很短 ServletRequest
//session 会话默认30分钟左右 控制登陆标记 登录状态 标识一个会话 HttpSession
//context 应用域生命周期最长 伴随着整个应用 Servletcontext
<session-config>
<session-timeout>30</session-timeout>
</session-config>