主要内容:
HTTP请求的结构:
post和get请求,其存储格式是一样的,只是存储位置不同,get请求将信息存储在url中,post请求将信息存储在请求体中
利用请求头开发多端应用:
根据请求包含的浏览器信息,选择相适应的输出结果
测试代码:
package com.imooc.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class UserAgentServlet
*/
@WebServlet("/ua")
public class UserAgentServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public UserAgentServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userAgent = request.getHeader("User-Agent");
response.setContentType("text/html;charset=UTF-8");
//返回登陆的平台信息
response.getWriter().println(userAgent);
String output = "";
if(userAgent.indexOf("Windows NT") != -1) {
output = "<h1>这是PC首页</h1>";
}else if(userAgent.indexOf("Macintosh") != -1) {
output = "<h1>这是Macintosh首页</h1>";
}else if(userAgent.indexOf("iPhone") != -1) {
output = "<h1>这是iPhone首页</h1>";
}
response.getWriter().println(output);
}
}
Mac上输出结果:
iphone上输出结果:
响应的结构:
HTTP常见状态码:
ContentType的作用:
测试代码:
package com.imooc.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class ContentTypeServlet
*/
@WebServlet("/ct")
public class ContentTypeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ContentTypeServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String output = "<h1><a href='http://www.baidu.com'><span style='color:pink'>百度</span></a></h1>";
response.setContentType("text/html;charset=UTF-8");
response.getWriter().println(output);
}
}
输出结果:
将格式变为xml:
response.setContentType("text/xml;charset=UTF-8");
输出结果:
请求转发与重定向的作用:
测试代码:从CheckLoginServlet到IndexServlet的两种实现:
request.getRequestDispatcher().forward():
package com.imooc.servlet.direct;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class CheckLoginServlet
*/
@WebServlet("/direct/check")
public class CheckLoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public CheckLoginServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("用户登录成功");
//请求分发器,实现了请求转发的功能
//在服务器tomcat内部实现从一个servlet跳转到另一个servlet
request.getRequestDispatcher("/direct/index").forward(request,response);
//响应重定向需要增加 contextPath
//将第一次请求处理结束以后,由浏览器重新发送新的请求给下一个servlet
//response.sendRedirect("/servlet_advanced/direct/index");
}
}
IndexServlet:
package com.imooc.servlet.direct;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class IndexServlet
*/
@WebServlet("/direct/index")
public class IndexServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public IndexServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().println("This is index page!");
}
}
输出结果:url仍然停止在第一个servlet,但的确执行了第二个servlet
response.sendRedirect():
package com.imooc.servlet.direct;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class CheckLoginServlet
*/
@WebServlet("/direct/check")
public class CheckLoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public CheckLoginServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("用户登录成功");
//请求分发器,实现了请求转发的功能
//在服务器tomcat内部实现从一个servlet跳转到另一个servlet
//request.getRequestDispatcher("/direct/index").forward(request,response);
//响应重定向需要增加 contextPath
//将第一次请求处理结束以后,由浏览器重新发送新的请求给下一个servlet
response.sendRedirect("/servlet_advanced/direct/index");
}
}
输出结果:url指向了第二个servlet
请求转发与响应重定向的原理:
请求转发:
响应重定向:
设置请求自定义属性:
测试代码:
使用请求转发:
package com.imooc.servlet.direct;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class CheckLoginServlet
*/
@WebServlet("/direct/check")
public class CheckLoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public CheckLoginServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("用户登录成功");
request.setAttribute("username","admin");
//请求分发器,实现了请求转发的功能
//在服务器tomcat内部实现从一个servlet跳转到另一个servlet
request.getRequestDispatcher("/direct/index").forward(request,response);
}
}
输出结果:获得属性值,两个servlet收到的请求是一样的
响应重定向:
package com.imooc.servlet.direct;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class CheckLoginServlet
*/
@WebServlet("/direct/check")
public class CheckLoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public CheckLoginServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("用户登录成功");
//设置属性
request.setAttribute("username","admin");
//响应重定向需要增加 contextPath
//将第一次请求处理结束以后,由浏览器重新发送新的请求给下一个servlet
response.sendRedirect("/servlet_advanced/direct/index");
}
}
输出结果:未获得属性值,因为两个servlet收到的请求不一致
编程练习:
待续
浏览器Cookie:
测试代码:
ImoocLoginServlet:
package com.imooc.servlet.cookie;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class ImoocLoginServlet
*/
@WebServlet("/cookies/login")
public class ImoocLoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ImoocLoginServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//一行代码,搞定所有响应乱码
response.setContentType("text/html;charset=GBK");
System.out.println("用户登录成功");
//Cookie(cookie名字 , cookie值);
Cookie cookie = new Cookie("user" , "lcs");
cookie.setMaxAge(60 * 60 * 24 * 7);
//在客户端创建cookie
response.addCookie(cookie);
response.getWriter().println("登录已经成功");
}
}
ImoocIndexServlet:
package com.imooc.servlet.cookie;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class ImoocIndexServlet
*/
@WebServlet("/cookies/index")
public class ImoocIndexServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ImoocIndexServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//一行代码,搞定所有响应乱码
response.setContentType("text/html;charset=GBK");
//request.getCookies()用户获取所有的Cookie
Cookie[] cs = request.getCookies();
if(cs == null) {
response.getWriter().println("用户并未登录");
return;
}
String user = null;
for(Cookie c : cs) {
System.out.println(c.getName() + ":" + c.getValue());
if(c.getName().equals("user")) {
user = c.getValue();
break;
}
}
if(user == null) {
response.getWriter().println("用户并未登录");
}else {
response.getWriter().println("用户已经登录");
//进行换行操作
response.getWriter().println("</br>");
response.getWriter().println("user:" + user);
}
}
}
输出结果:
用户会话Session对象:
SessionLoginServlet:
package com.imooc.servlet.session;
import java.io.IOException;
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 javax.servlet.http.HttpSession;
/**
* Servlet implementation class SessionLoginServlet
*/
@WebServlet("/session/login")
public class SessionLoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public SessionLoginServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("用户登录成功");
//获取用户会话session对象
HttpSession session = request.getSession();
String sessionId = session.getId();
System.out.println(sessionId);
session.setAttribute("name", "lcs");
request.getRequestDispatcher("/session/index").forward(request,response);
}
}
SessionIndexServlet:
package com.imooc.servlet.session;
import java.io.IOException;
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 javax.servlet.http.HttpSession;
/**
* Servlet implementation class SessionIndexServlet
*/
@WebServlet("/session/index")
public class SessionIndexServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public SessionIndexServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String sessionId = session.getId();
System.out.println(sessionId);
String name = (String)session.getAttribute("name");
response.setContentType("text/html;charset=UTF-8");
response.getWriter().println("首页当前用户:"+name);
}
}
在不同浏览器输出:
其sessionId是不同的,是与浏览器绑定在一起的
Session的实现原理:
ServletContext与三大作用域对象:
测试代码:
ServletContentInitServlet:
package com.imooc.servlet.ServletContext;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class ServletContentInitServlet
*/
@WebServlet("/servlet/context/init")
public class ServletContentInitServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ServletContentInitServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = request.getServletContext();
context.setAttribute("copyright","© 2019 imooc.com All Rights Reserved | 京ICP备 12003892号-11");
context.setAttribute("title", "程序员梦工厂");
response.getWriter().println("init success");
}
}
ServletContextDefaultServlet:
package com.imooc.servlet.ServletContext;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class ServletContextDefaultServlet
*/
@WebServlet("/servlet/context/default")
public class ServletContextDefaultServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ServletContextDefaultServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = request.getServletContext();
String copyright = (String)context.getAttribute("copyright");
String title = (String)context.getAttribute("title");
response.setContentType("text/html;charset=UTF-8");
response.getWriter().println("<h1>"+title+"</h1>"+copyright);
}
}
输出结果:
如果更换浏览器,输入http://localhost:8080/servlet_advanced/servlet/context/default,也会输出:毕竟是全局对象
Servlet的三大作用域对象:
目的:共享数据.
request: 每一次请求都是一个新的request对象,如果在Web组件之间需要共享同一个请求中的数据,只能使用请求转发.
session: 每一次会话都是一个新的session对象,如果需要在一次会话中的多个请求之间需要共享数据,只能使用session.
application: 应用对象,Tomcat启动到Tomcat关闭,表示一个应用,在一个应用中有且只有一个application对象.作用于整个Web应用,可以实现多次会话之间的数据共享.
对象名称 对象的类型
request HttpServletRequest
session HttpSession
servletcontext(application) ServletContext
作用域对象如何共享数据:
设置作用域中的共享数据.
作用域对象.setAttribute(String name,Object value);
获取作用域中的共享数据.
Object value = 作用域对象.getAttribute(String name);
删除作用域中的指定的共享数据.
作用域对象.removeAttribute(String name);
注意:
在哪一个作用域中设置共享数据,就只能从该作用域中取出数据.
解决Web请求中文乱码问题:
解决Post请求中文乱码问题:
charset_form.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="/servlet_advanced/charset/process" method="post">
姓名:<input name="ename">
地址:<input name="address">
<input type="submit" value="提交">
</form>
</body>
</html>
CharsetServlet:有两种方法实现
方法1:String utf8Ename = new String(name.getBytes("iso-8859-1"),"UTF-8");
方法2:request.setCharacterEncoding("UTF-8");
package com.imooc.servlet.charset;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class CharsetServlet
*/
@WebServlet("/charset/process")
public class CharsetServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public CharsetServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().append("Served at: ").append(request.getContextPath());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//方法二:
//request.setCharacterEncoding()用于将请求体中的字符集转换为UTF-8
//要写在第一行
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("ename");
String address = request.getParameter("address");
//方法一:
// String utf8Ename = new String(name.getBytes("iso-8859-1"),"UTF-8");
// String utf8Address = new String(address.getBytes("iso-8859-1"),"UTF-8");
System.out.println(utf8Ename+":"+utf8Address);
}
}
输出结果:
解决Get请求和响应中文乱码问题:
在Tomcat8及其以上版本请求无需配置哦,但是对于响应,还是要配置:
response.setContentType("text/html;charset=UTF-8 ");
测试代码:
CharsetServlet:
package com.imooc.servlet.charset;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class CharsetServlet
*/
@WebServlet("/charset/process")
public class CharsetServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public CharsetServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//对于Tomcat8.x的版本,默认get请求发送中文就是UTF-8的格式,因此无需转换
String name = request.getParameter("ename");
String address = request.getParameter("address");
System.out.println(name + ":" + address);
//但是对于响应,还是要配置
response.setContentType("text/html;charset=UTF-8 ");
response.getWriter().println(name + ":" + address);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 方法二:
// request.setCharacterEncoding()用于将请求体中的字符集转换为UTF-8
// 要写在第一行
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("ename");
String address = request.getParameter("address");
// 方法一:
// String utf8Ename = new String(name.getBytes("iso-8859-1"),"UTF-8");
// String utf8Address = new String(address.getBytes("iso-8859-1"),"UTF-8");
System.out.println(name + ":" + address);
}
}
输出结果:
web.xml常用配置:
模糊匹配:
package com.imooc.servlet.pattern;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class PatternServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//查询员工的基本信息
//获取当前访问的URL并将其转换为字符串
String url = request.getRequestURL().toString();
//将url输入到控制台
System.out.println(url);
//获取id,通过截取字符串方法
String id = url.substring(url.lastIndexOf("/") + 1);
//强制类型转换
int eid = Integer.parseInt(id);
//设置字符集编码
response.setContentType("text/html;charset=utf-8");
//创建PrintWriter对象
PrintWriter out = response.getWriter();
out.println(id);
if(eid == 1) {
out.println("张三");
}else if(eid == 2) {
out.println("李四");
}else {
out.println("其他员工");
}
}
}
在web.xml中添加:
<servlet>
<servlet-name>patternServlet</servlet-name>
<servlet-class>com.imooc.servlet.pattern.PatternServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>patternServlet</servlet-name>
<url-pattern>/pattern/*</url-pattern>
</servlet-mapping>
输出结果:
错误页面处理,防止漏洞被别有用心的人利用:
重写两个错误处理页面:
404.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
资源不存在!
</body>
</html>
505.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
服务器内部错误,请联系管理员!
</body>
</html>
在web.xml添加:
<!-- 指定错误页面 -->
<error-page>
<error-code>404</error-code>
<location>/error/404.html</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/500.html</location>
</error-page>
输出结果:
JSP九大内置对象:
代码暂时搁置
Web应用程序的打包与发布: