Servlet和JSP进阶
Servlet和JSP进阶
- 掌握JavaWeb核心特性
- 掌握Servlet核心对象
- 了解JSP九大内置对象
一、 HTTP请求的结构
HTTP请求包含三部分:请求行、请求头、请求体(只有POST请求才有请求体)
新建一个项目命名为:request-struc
新建一个servlet:
package com.test.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 RequestServlet
*/
@WebServlet("/request")
public class RequestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public RequestServlet() {
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().println("This is get method");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("This is post method");
}
}
新建一个input.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="/request-struc/request" method="get">
<input name="username">
<input name="password" type="password">
<input type="submit">
</form>
</body>
</html>
打开网址:
二、 巧用请求头开发多端应用
同一个网站在不同的设备显示样式不同
编写代码查看请求头:
package com.test.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);
}
}
切换模式:
改进代码:
package com.test.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>这是P C端首页</h1>";
}else if(userAgent.indexOf("iphone") != -1 || userAgent.indexOf("Android") != -1) {
output = "<h1>这是移动端首页</h1>";
}
response.getWriter().println(output);
}
}
三、 响应的结构
-
HTTP请求包含三部分:请求行、请求头、请求体(只有POST请求才有请求体)
-
HTTP常见的状态码
状态码 | 错误描述 |
---|---|
200 | 服务器处理成功 |
404 | 无法找到文件 |
500 | 内部服务器错误 |
403 | 服务拒绝访问 |
301、302 | 请求重定向 |
400 | 无效的请求 |
401 | 未经过授权 |
503 | 服务器超负载或正停机维护,无法处理请求处理 |
四、 ContentType的作用
ContentType决定浏览器采用何种方式对响应体进行处理
MIME类型 | 描述 |
---|---|
text/plain | 纯文本 |
text/html | HTML文件 |
text/xml | XML文档 |
application/x-msdownload | 需要下载的资源 |
image/jpeg | 图片资源 |
image/gif | 图片资源 |
五、 请求转发与重定向
平时我们只用一个servlet,但在实际开发中我们是需要使用多个servlet的,他们之间如何跳转?
多个servlet(JSP)之间跳转有两种方式:
request.getResquestDispatcher().forward()
-请求转发response.sendRedirect()
-响应重定向
在com.test.servlet下面建一个子包com.test.servlet.direct
- 请求转发的形式:
代码:
package com.test.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.getRequestDispatcher("/direct/index").forward(request, response);
}
}
package com.test.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 {
response.getWriter().println("This is index page");
}
}
- 响应重定向的方式
package com.test.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.getRequestDispatcher("/direct/index").forward(request, response);
//响应重定向需要增加contextPath
response.sendRedirect("/servlet_advanced/direct/index");
}
}
两者之间的不同
- 从表象上看,两者的地址栏内容不同
设置请求自定义属性
- 请求允许创建自定义属性
- 设置请求属性:request.setAttribute(属性名,属性值)
- 获取请求属性:Object attr = request.getAttribute(属性名)
代码:
package com.test.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");
//实现了请求转发的功能
request.getRequestDispatcher("/direct/index").forward(request, response);
//响应重定向需要增加contextPath
//response.sendRedirect("/servlet_advanced/direct/index");
}
}
package com.test.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 {
String username = (String)request.getAttribute("username");
response.getWriter().println("This is index page!current username is " + username);
}
}
六、 浏览器Cookie
Cookie(小甜饼)是浏览器保存在本地的文本内容
Cookie常用于保存登录状态、用户资料等小文本
Cookie具有时效性,Cookie内容会伴随着请求发送给Tomcat
举例:7天内自动登录
代码:
package com.test.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 TestLoginServlet
*/
@WebServlet("/cookies/login")
public class TestLoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public TestLoginServlet() {
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("用户登录成功");
Cookie cookie = new Cookie("user", "admin");
response.addCookie(cookie);
response.getWriter().println("login success");
}
}
下面我们读取Cookie:
package com.test.servlet.cookie;
import java.io.IOException;
import java.util.Iterator;
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 TestIndexServlet
*/
@WebServlet("/cookies/index")
public class TestIndexServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public TestIndexServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//request.getCookies()用于获取所有的Cookie信息
Cookie[] cs = request.getCookies();
for (Cookie c : cs) {
System.out.println(c.getName() + ":" + c.getValue());
}
}
}
改进代码,判断用户是否登录:
package com.test.servlet.cookie;
import java.io.IOException;
import java.util.Iterator;
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 TestIndexServlet
*/
@WebServlet("/cookies/index")
public class TestIndexServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public TestIndexServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//request.getCookies()用于获取所有的Cookie信息
Cookie[] cs = request.getCookies();
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("user not login");
}else {
response.getWriter().println("user: "+ user);
}
}
}
那么Cookie的有效时长是多少?默认是当前网页,它随着网页的关闭而终止。如果我们将网址复制并关闭浏览器,然后再打开浏览器直接粘贴网址就会发现网页404。
package com.test.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 TestLoginServlet
*/
@WebServlet("/cookies/login")
public class TestLoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public TestLoginServlet() {
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("用户登录成功");
Cookie cookie = new Cookie("user", "admin");
cookie.setMaxAge(60 * 60 * 24 * 7); //默认是按秒,所以是最后结果是7天
response.addCookie(cookie);
response.getWriter().println("login success");
}
}
这样就解决了时效性问题。
七、 Session 用户会话
- Session(用户会话)用于保存与“浏览器窗口”对应的数据
- 相较于Cookie将资料保存在本地,Session则是将数据保存在服务器,这样既加快速度,也能很好保障安全。
- Session的数据存储在Tomcat服务器的内存中,具有时效性。Session与浏览器窗口绑定,在没人访问的情况下,默认有效时长30分钟
- Session通过浏览器Cookie的Sessionld值提取用户数据
package com.test.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();
session.setAttribute("name", "张三");
request.getRequestDispatcher("/session/index").forward(request, response);
}
}
package com.test.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 name = (String)session.getAttribute("name");
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("这是首页,当前用户为:" + name);
}
}
Session的原理
八、 ServletContext
- ServletContext(Servlet上下文对象),是Web应用全局对象
- 一个Web应用只会创建一个ServletContext对象
- ServletContext随着Web应用启动而自动创建
例如每个网站下面都会有备案信息
代码:
package com.test.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 ServletContextInitServlet
*/
@WebServlet("/servletcontext/init")
public class ServletContextInitServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ServletContextInitServlet() {
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", "© 2018 test.com 京ICP备 12008569号-37");
context.setAttribute("title", "这是一个测试样例!");
response.getWriter().println("init success");
}
}
package com.test.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("/servletcontext/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 = (ServletContext)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);
}
}
九、 总结Java Web三大作用域对象
- HttpServletRequest : 请求对象(生命周期最短)
- HttpSession : 用户会话对象
- ServletContext : web应用全局对象(生命周期最长)
十、 Web应用中乱码问题
- Tomcat默认使用字符集ISO-8859-1,属于西欧字符集
- 解决乱码的核心思路是将ISO-8859-1转换成UTF-8
- Servlet中请求与响应都需要设置UTF-8字符集
1. 解决Post请求中文乱码问题
新建一个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>
package com.test.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 {
// TODO Auto-generated method stub
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 {
String ename = request.getParameter("ename");
String address = request.getParameter("address");
System.out.println(ename + ":" + address);
}
}
浏览器打开:
回到控制台:
改name后:
这样改写太麻烦了,改进:
package com.test.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 {
// TODO Auto-generated method stub
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 {
//改进,一定要写在第一行,并且该方法只能用于请求体中,也就是只有post可以用,而get不可以。
request.setCharacterEncoding("utf-8");
String ename = request.getParameter("ename");
String address = request.getParameter("address");
//String utf8Ename = new String(ename.getBytes("iso-8859-1"), "utf-8");
//String utf8address = new String(address.getBytes("iso-8859-1"), "utf-8");
System.out.println(ename + ":" + address);
}
}
2. 解决Get请求中文乱码问题
package com.test.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 ename = request.getParameter("ename");
String address = request.getParameter("address");
System.out.println(ename + ":" + address);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//改进,一定要卸载第一行。
request.setCharacterEncoding("utf-8");
String ename = request.getParameter("ename");
String address = request.getParameter("address");
//String utf8Ename = new String(ename.getBytes("iso-8859-1"), "utf-8");
//String utf8address = new String(address.getBytes("iso-8859-1"), "utf-8");
System.out.println(ename + ":" + address);
}
}
我们发现控制台输出正常,这是因为对于Tomcat8.X版本,默认get请求发送的中文就是UTF-8,因此无需转换。
十一、 web.xml常用配置
- 修改web应用默认首页
- Servlet通配符映射即初始化参数
- 设置404、500等状态码默认页面
1. 修改web应用默认首页
新建index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
我是默认首页
</body>
</html>
如果向利用url来获取信息,代码:
package com.test.servlet.pattern;
import java.io.IOException;
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.getRequestURI().toString();
System.out.println(url);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1" metadata-complete="false">
<display-name>servlet_advanced</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>PatternServlet</servlet-name>
<servlet-class>com.test.servlet.pattern.PatternServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PatternServlet</servlet-name>
<url-pattern>/pattern/*</url-pattern>
</servlet-mapping>
</web-app>
结果和控制台:
改进:
package com.test.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.getRequestURI().toString();
System.out.println(url);
//获取最后一次/出现的位置
String id = url.substring(url.lastIndexOf("/") + 1);
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.println(id);
if (id.equals("1")) {
out.println("张三");
}else if (id.equals("2")) {
out.println("李四");
}else {
out.println("其他员工");
}
}
}
2. 全局参数的配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1" metadata-complete="false">
<display-name>servlet_advanced</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>PatternServlet</servlet-name>
<servlet-class>com.test.servlet.pattern.PatternServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PatternServlet</servlet-name>
<url-pattern>/pattern/*</url-pattern>
</servlet-mapping>
<!-- 应用程序的全局参数配置 -->
<context-param>
<param-name>copyright</param-name>
<param-value>© 2018 test.com 京ICP备 12008569号-37</param-value>
</context-param>
<context-param>
<param-name>title</param-name>
<param-value>这是一个测试样例</param-value>
</context-param>
</web-app>
package com.test.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 ServletContextInitServlet
*/
@WebServlet("/servletcontext/init")
public class ServletContextInitServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ServletContextInitServlet() {
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 = context.getInitParameter("copyright");
String title = context.getInitParameter("title");
context.setAttribute("copyright", copyright);
context.setAttribute("title", title);
response.getWriter().println("init success");
}
}
3. 设置404、500等状态码默认页面
原始报错:
这样的报错页面会暴露重要信息,所以我们要对错误页面进行修改,代码:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1" metadata-complete="false">
<display-name>servlet_advanced</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>PatternServlet</servlet-name>
<servlet-class>com.test.servlet.pattern.PatternServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PatternServlet</servlet-name>
<url-pattern>/pattern/*</url-pattern>
</servlet-mapping>
<!-- 应用程序的全局参数配置 -->
<context-param>
<param-name>copyright</param-name>
<param-value>© 2018 test.com 京ICP备 12008569号-37</param-value>
</context-param>
<context-param>
<param-name>title</param-name>
<param-value>这是一个测试样例</param-value>
</context-param>
<!-- 指定错误页面 -->
<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>
</web-app>
package com.test.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 ServletContextInitServlet
*/
@WebServlet("/servletcontext/init")
public class ServletContextInitServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ServletContextInitServlet() {
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 = context.getInitParameter("copyright");
String title = context.getInitParameter("title");
context.setAttribute("copyright", copyright);
context.setAttribute("title", title);
response.getWriter().println("init success");
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
资源不存在
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
服务器内部错误,请联系管理员
</body>
</html>
结果:
十二、 JSP九大内置对象
代码 | 含义 |
---|---|
request | 请求对象 - HttpServletRequest |
response | 响应对象 - HttpServletResponse |
session | 用户对象 - HttpSession |
application | 应用全局对象 - ServletContext |
out | 输出对象 - PrintWriter |
page | 当前页面对象 - this |
pageContext | 页面上下文对象 - PageContext |
config | 应用配置对象 - ServletConfig |
exception | 应用异常对象 - Throwable |
例子:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String url = request.getRequestURI().toString();
response.getWriter().println(url);
%>
<%
out.println("<br>AABCC");
session.setAttribute("user", "张三");
out.println((String)session.getAttribute("user"));
%>
<%
String cp = application.getInitParameter("copyright");
out.println("<hr/>");
out.println(cp);
pageContext.getRequest();
pageContext.getResponse();
pageContext.getSession();
pageContext.getServletContext();
%>
</body>
</html>
也可以把错误状态编写成JSP形式:
<%@ page contentType="text/html;charset=utf-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
服务器内部错误,请联系管理员,错误信息如下:
<%
String msg = exception.getMessage();
out.print("<br>" + msg)
%>
</body>
</html>
十三、 Java Web打包与发布
- Java Web应用采用war包进行发布
- 发布路径为:
{TOMCAT_HOME}/webapps
- Eclipse支持war包
导出war包:
发布:
这样就可以不用打开eclipse运行能打开项目,但是地址栏的格式很明显不符合我们平时使用习惯,现在我们优化一下:
先去除8080:
接下来去除上下文路径: