目录
前言
前面已经学习了Java Web的一些基础知识,对于如何编写JSP文件和Servlet有了个基本了解,现在我们就一起学一点进阶知识,相信学完你会收获满满!
学习内容
请求结构
我们实际开发过程中比较常用的两种请求方式为GET请求和POST请求,下面我们通过一个简单的例子了解一下这两种请求方式的请求结构。
- Servlet代码
package com.example.web1;
/**
* Description:
*
* @Author: kk(专业bug开发)
* DateTime: 2022-01-05 22:13
*/
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "Servlet4", value = "/Servlet4")
public class Servlet4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("this is get");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("this is post");
}
}
- Html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/web1_war_exploded/Servlet4" method="post">
<input name="username">
<input name="password" type="password">
<input type="submit">
</form>
</body>
</html>
- GET请求结构
- POST请求结构
请求头开发多端应用
我们在使用网页的时候会发现很多网页在手机和在网页显示的内容是一样的,仅仅在细节上不太一样。这种情况我们就可以使用请求头判断客户端类型,对应展示页面。
- 获取请求头类型并判断客户端
package com.example.web1; /**
* Description:
*
* @Author: kk(专业bug开发)
* DateTime: 2022-01-05 22:43
*/
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "Servlet5", value = "/Servlet5")
public class Servlet5 extends HttpServlet {
@Override
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 = "<h3>这是PC端访问</h3>";
}else if(userAgent.indexOf("iPhone") != -1||userAgent.indexOf("Android") != -1){
output = "<h3>这是手机端访问</h3>";
}
response.getWriter().println(output);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
- 页面显示效果
请求转发与重定向
现在打开一个需要登录的页面做一个实验:在首页点击登录,进入登录以后正常登录,登录完成以后你会发现页面重新返回首页,但这时候是登录状态。这里登录逻辑验证完成以后页面返回首页就是请求转发。
- 请求转发
request.getRequestDispatcher("/Servletlogin").forward(request, response);
package com.example.web1; /**
* Description:这是登录校验
*
* @Author: kk(专业bug开发)
* DateTime: 2022-01-05 23:23
*/
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "Servletcheck", value = "/Servletcheck")
public class Servletcheck extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("登录成功!");
// 实现请求转发
request.getRequestDispatcher("/Servletlogin").forward(request, response);
}
}
package com.example.web1; /**
* Description:这是登陆后的页面
*
* @Author: kk(专业bug开发)
* DateTime: 2022-01-05 23:24
*/
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "Servletlogin", value = "/Servletlogin")
public class Servletlogin extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("this is index page!");
}
}
- 重定向
package com.example.web1; /**
* Description:
*
* @Author: kk(专业bug开发)
* DateTime: 2022-01-05 23:23
*/
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "Servletcheck", value = "/Servletcheck")
public class Servletcheck extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("登录成功!");
// 实现响应重定向
response.sendRedirect("/web1_war_exploded/Servletlogin");
}
}
- 请求转发与重定向
请求转发意味着服务器完成跳转,只会产生一次请求。
响应重定向由浏览器跳转,会产生两次请求。
浏览器Cookie
大家打开自己电脑上需要登录的网站,然后登录后关闭浏览器,重新打开后发现我们的登录信息依旧保存在浏览器,这就是通过Cookie实现的。
- 设置Cookie
Cookie cookie = new Cookie("user", "kkkkkkk");
//设置cookie的最长生命,单位为秒
cookie.setMaxAge(60 * 60 * 24 * 7);
response.addCookie(cookie);//生成并添加Cookie信息
package com.example.web1; /**
* Description:
*
* @Author: kk(专业bug开发)
* DateTime: 2022-01-06 10:33
*/
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "ServletCookie", value = "/ServletCookie")
public class ServletCookie extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("登陆成功!");
Cookie cookie = new Cookie("user", "kkkkkkk");
//设置cookie的最长生命,单位为秒
cookie.setMaxAge(60 * 60 * 24 * 7);
response.addCookie(cookie);
response.getWriter().print("<h1>login success</h1>");
}
}
- 读取Cookie
request.getCookies() //用于获取保存的cookie信息,返回的是一个数组
package com.example.web1; /**
* Description:
*
* @Author: kk(专业bug开发)
* DateTime: 2022-01-06 10:42
*/
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "ServletgetCookie", value = "/ServletgetCookie")
public class ServletgetCookie extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// request.getCookies()用于获取保存的cookie信息,返回的是一个数组
Cookie[] cookies = request.getCookies();
String user = null;
for(Cookie c : cookies){
System.out.println(c.getName()+ ":" + c.getValue());
if(c.getName().equals("user")){
user = c.getValue();
break;
}
}
if(user == null){
response.getWriter().println("<h1>not login</h1>");
}else{
response.getWriter().println("user" + user);
}
}
}
- Cookie总结
- Cookie是浏览器保存在本地的文本内容
- Cookie常用于保存登录状态、用户资料等小文本
- Cookie具有时效性,默认为浏览器窗口关闭,Cookie内容会伴随请求发送给tomcat
Session用户会话
刚才看了Cookie,我们知道Cookie信息是存储在客户机上的文本信息,虽然是进行了加密,但是因为其存储在本地,相对来说安全性还是不够高。为此Java Web给我们提供了另外一种用户会话方式-session。
Session有如下特点:
- 用于保存与浏览器串口对应的数据
- 数据存储在Tomcat服务器的内存中,具有时效性(默认为30min)
- Session通过浏览器Cookie的SessionId提取用户数据
- 设置Session
package com.example.web1; /**
* Description:
*
* @Author: kk(专业bug开发)
* DateTime: 2022-01-06 11:06
*/
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "ServletSession", value = "/ServletSession")
public class ServletSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("登录成功!!");
// 获取用户对话Session对象
HttpSession session = request.getSession();
// 添加会话信息
session.setAttribute("name", "kk");
request.getRequestDispatcher("/ServletSessionIndex").forward(request, response);
}
}
- 获取Session
package com.example.web1; /**
* Description:
*
* @Author: kk(专业bug开发)
* DateTime: 2022-01-06 11:07
*/
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "ServletSessionIndex", value = "/ServletSessionIndex")
public class ServletSessionIndex extends HttpServlet {
@Override
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("<h1>这是登陆后的页面,当前用户为"+ name);
}
}
- Session原理
ServletContext对象
ServletContext(Servlet上下文对象),是Web应用全局对象。一个Web应用只会创建一个ServletContext对象,ServletContext随着Web的启动而自动创建。
- 设置ServletContext
package com.example.web1; /**
* Description:
*
* @Author: kk(专业bug开发)
* DateTime: 2022-01-06 11:23
*/
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "ServletCon", value = "/ServletCon")
public class ServletCon extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = request.getServletContext();
context.setAttribute("copyright", "专业bug开发 @2019-2022");
context.setAttribute("title", "专业开发bug20年!");
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("初始化成功!");
}
}
- 获取ServletContext
package com.example.web1; /**
* Description:
*
* @Author: kk(专业bug开发)
* DateTime: 2022-01-06 11:28
*/
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "ServletgetCon", value = "/ServletgetCon")
public class ServletgetCon extends HttpServlet {
@Override
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>" + copyright + "</h1>");
response.getWriter().println("<h1>" + title + "</h1>");
}
}
Web乱码问题解决
通过前面的学习我们发现一个问题,当我们的程序中含有中文的时候会出现乱码问题,这主要是由于Tomcat默认使用的字符集是ISO-8859-1,属于西欧字符集。所以我们解决乱码问题的核心是将ISO-8859-1转换成UTF-8(Servlet的请求响应都需要设置编码格式)。
- POST请求编码处理
package com.example.web1; /**
* Description:
*
* @Author: kk(专业bug开发)
* DateTime: 2022-01-06 12:57
*/
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "ServletCharset", value = "/ServletCharset")
public class ServletCharset extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置请求体中的字符编码格式
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
String address = request.getParameter("address");
System.out.println("name:" + name + "address:" + address);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/web1_war_exploded/ServletCharset" method="post">
姓名:<input name="name">
地址:<input name="address">
<input type="submit" value="提交">
</form>
</body>
</html>
- GET请求编码处理
对于get请求来说,Tomcat8.x以后默认的get字符集就是utf-8,当我们的Tomcat版本是7.x及以下的时候需要这么设置。
解决办法看这里
web.xml常用配置
- 修改默认首页
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
- 通配符映射及初始化参数
<servlet>
<servlet-name>pattern</servlet-name>
<servlet-class>com.example.web1.pattern</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>pattern</servlet-name>
<!-- 所有URL前缀为pattern的都会拦截-->
<url-pattern>/pattern/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>name</param-name>
<param-value>专业bug开发</param-value>
</context-param>
<context-param>
<param-name>title</param-name>
<param-value>专业开发20年!</param-value>
</context-param>
package com.example.web1; /**
* Description:
*
* @Author: kk(专业bug开发)
* DateTime: 2022-01-06 11:28
*/
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "ServletgetCon", value = "/ServletgetCon")
public class ServletgetCon extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = request.getServletContext();
String name = context.getInitParameter("name");
String title = context.getInitParameter("title");
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("<h1>" + name + "</h1>");
response.getWriter().println("<h1>" + title + "</h1>");
}
}
- 设置404、500等状态码默认界面
<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九大内置对象
项目打包war文件
总结
又花费整整一个下午的时间,差不多把相关的知识点都过了一边,过程中大多以代码示例的方式展示,所有的代码都是经过调试的,如果发现问题,欢迎交流~