7.6 HttpServletResponse
4实现重定向
B一个web资源收到客户端A请求后,B会通知A客户端去访问另外一个web资源C,这个过程叫重定向。
常见常见:
-
用户登录
void sendRedirect(String location) throws IOException;
测试:
package com.kuang.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/* resp.setHeader("Location","/r2/img");
resp.setStatus(302);
*/
resp.sendRedirect("/r2/img");//重定向
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
面试题:请你描述一下重定向和转发的区别
相同点:
-
页面都会实现跳转
不同点:
-
请求转发的时候,url不会产生变化
-
重定向时候,url地址栏会发生变化
出现的问题:JSP页面显示乱码
解决方法:
这种乱码的原因是应为没有在页面里指定使用的字符集编码,解决方法:只要在页面开始地方用下面代码指定字符集编码即可:
<%@ page contentType="text/html;charset=utf-8" language="java" %>
请求测试:
package com.kuang.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RequestTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// System.out.println("进入这个请求了");
//处理请求
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username+":"+password);
//重定向的时候一定要注意,路径问题,否则404
resp.sendRedirect("/r2/success.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
success.jsp:
<%--
Created by IntelliJ IDEA.
User: HP
Date: 2021/3/17
Time: 9:55
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Success</h1>
</body>
</html>
添加的jsp依赖:
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
</dependency>
7.7HttpServletRequest
HttpServletRequest:代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息。
1.获取前端传递的参数 请求转发
package com.kuang.servlet;
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.util.Arrays;
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");//解决中文乱码
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbies = req.getParameterValues("hobbies");
System.out.println("==========================");
//后台接收中文乱码问题
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.toString(hobbies));
System.out.println("===============");
System.out.println(req.getContextPath());
//通过请求转发
//("/hello/success.jsp") 这样写会报错404 因为hello前面的/代表当前的web应用
req.getRequestDispatcher("success.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<h1>登录</h1>
<%--居中--%>
<div >
<%-- 这里表单表示的意思是:以post方式提交表单,提交到外面的login请求--%>
<form action="${pageContext.request.contextPath}/login" method="post">
用户名: <input type="text" name="username"><br>
密码: <input type="password"name="password"><br>
爱好:
<%-- checkbox多选框--%>
<input type="checkbox" name="hobbies" value="女孩">女孩
<input type="checkbox"name="hobbies" value="代码">代码
<input type="checkbox"name="hobbies" value="唱歌">唱歌
<input type="checkbox"name="hobbies" value="电影">电影
<br>
<input type="submit">
</form>
</div>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>登录成功</h1>
</body>
</html>
面试题:请你描述一下重定向和转发的区别
相同点:
-
页面都会实现跳转
不同点:
-
请求转发的时候,url不会产生变化 307
-
重定向时候,url地址栏会发生变化 302
-
出现的问题:
每次导入servlet包都会出错:显示未导入
此时在extends后面加javax.servlet.http.HttpServlet然后点击alt+enter就会导入
代码错报500 正常错报404
8. Cookie Session
8.1会话
会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话。
有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学,曾经来过。称之为有状态会话。
你能怎么证明你是西开的学生?
你 西开
1.发票 西开给你的发票
2.学校登记,西开标记你来过
一个网站,怎么证明你来过?
客户端 服务端
1.服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了:cookie
2.服务器登记你来过了,下次你来的时候我来匹配你;seesion
8.2保存会话的两种技术
cookie
-
客户端技术(响应,请求)
session
-
服务器技术,利用这个技术,可以保存用户的会话信息。我们可以把信息或者数据放在Seesion中!
常见场景:网站登录之后,你下次不用再登录了,第二次访问直接就上去了!
8.3 . Cookie
1.从请求中拿到cookie信息
2.服务器响应给客户端cookie
Cookie[] cookies = req.getCookies();//获得cookie
cookie.getName();//获得cookie中的key
cookie.getValue();//获得cookie的value
new Cookie("lastloginTime", System.currentTimeMillis()+"");//新建一个cookie
cookie.setMaxAge(24*60*60);//设置cookie的有效期
resp.addCookie(cookie);//响应给客户端一个cookie
cookie:一般会保存在本地的用户目录下的appdata;
一个网站cookie是否存在上限!聊聊细节问题
-
一个Cookie只能保存一个信息;
-
一个web站点可以给浏览器发送多个cookie, 最多存放20个cookie
-
浏览器上限300个cookie
-
Cookie大小有限制4kb
删除Cookie:
-
不设置有效期,关闭浏览器,自动失效;
-
设置有效期时间为0;
编码解码:
URLEncoder.encode("秦疆","utf-8")编码
URLDecoder.decode(cookie.getValue(),"utf-8")package com.kuang.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
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.Date;
//保存用户上一次访问的时间
public class CookieDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//服务器,告诉你,你来的时间,把这个时间封装成为一个信件,你下次带来,我就知道你来了
//解决中文乱码
//resp.setContentType("Text/html;charset=utf-8");这句也必须加 不然也会乱码
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("Text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
//Cookie服务器端从客户端获取的
Cookie[] cookies = req.getCookies();//这里返回数组,说明Cookie可能存在多个
//判断Cookie是否存在
if (cookies!=null){
//如果存在怎么办
out.write("你上一次访问的时间是:");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
//获取cookie的名字
if (cookie.getName().equals("lastloginTime")){
//获取cookie中的值
long lastloginTime = Long.parseLong(cookie.getValue());//强转long
Date date = new Date(lastloginTime);
out.write(date.toString());
}
}
}else{
out.write("这是您第一次访问本站");
}
//服务器给客户端响应一个cookie;
//以后想要一个什么样的参数直接new出来
Cookie cookie = new Cookie("lastloginTime", System.currentTimeMillis()+"");
//cookie有效期为一天
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
package com.kuang.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
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.Date;
//保存用户上一次访问的时间
public class CookieDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建一个cookie,名字必须要和要删除的名字一致
Cookie cookie = new Cookie("lastloginTime", System.currentTimeMillis() + "");
//设置cookie有效期为0,立马过期
cookie.setMaxAge(0);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
-
package com.kuang.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
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.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Date;
//中文数据传递
public class CookieDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("Text/html;charset=utf-8");
//Cookie服务器端从客户端获取的
Cookie[] cookies = req.getCookies();//这里返回数组,说明Cookie可能存在多个
PrintWriter out = resp.getWriter();
//判断Cookie是否存在
if (cookies!=null){
//如果存在怎么办
out.write("你上一次访问的时间是:");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
//获取cookie的名字
if (cookie.getName().equals("name")){
//获取cookie中的值
// System.out.println(cookie.getValue());
// URLDecoder.decode(cookie.getValue(),"utf-8");解码
out.write(URLDecoder.decode(cookie.getValue(),"utf-8"));
}
}
}else{
out.write("这是您第一次访问本站");
}
//URLEncoder.encode("秦疆","utf-8")编码
Cookie cookie = new Cookie("name", URLEncoder.encode("秦疆","utf-8"));
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
-
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
<servlet>
<servlet-name>CookieDemo01</servlet-name>
<servlet-class>com.kuang.servlet.CookieDemo01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CookieDemo01</servlet-name>
<url-pattern>/c1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>CookieDemo02</servlet-name>
<servlet-class>com.kuang.servlet.CookieDemo02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CookieDemo02</servlet-name>
<url-pattern>/c2</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>CookieDemo03</servlet-name>
<servlet-class>com.kuang.servlet.CookieDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CookieDemo03</servlet-name>
<url-pattern>/c3</url-pattern>
</servlet-mapping>
</web-app>
8.4 Session(重点)
什么是Session:
-
服务器会给每一个(浏览器)创建一个Seesion对象
-
一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在;
-
用户登录之后,整个网站它都可以访问!---->保存用户的信息;保存购物车的信息
Session和Cookie的区别:
-
Cookie是把用户的数据写给用户的资源,浏览器保存(可以保存多个)
-
Session把用户的数据写到用户独占的Session中,服务端保存(保存重要的信息,减少资源的浪费)
-
Session对象由服务器创建;
使用场景:
-
保存一个登录用户的信息
-
购物车信息
-
在整个网站中经常会使用的数据,我们将它保存起来
使用Session:
package com.kuang.servlet;
import com.kuang.pojo.Person;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
public class SessionDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("Text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
//给Session中存东西
session.setAttribute("name",new Person("秦疆",1));
//获取Session的ID
String sessionId = session.getId();
//判断Session是不是新创建的
if (session.isNew()){
resp.getWriter().write("session创建成功,ID:"+sessionId);
}else{
resp.getWriter().write("session已经在服务器中存在了,ID:"+sessionId);
}
// //Session创建的时候做了什么事情
// Cookie cookie = new Cookie("JSESSIONID",sessionId);
// resp.addCookie(cookie);
//
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
package com.kuang.servlet;
import com.kuang.pojo.Person;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class SessionDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("Text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
Person person = (Person) session.getAttribute("name");
System.out.println(person.toString());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
package com.kuang.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class SessionDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.removeAttribute("name");
//手动注销Session
session.invalidate();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
package com.kuang.pojo;
import java.util.Objects;
public class Person {
private String name;
private int age;
public Person(){
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
会话自动过期:web.xml配置
<!-- 设置Session默认的失败时间-->
<session-config>
<!-- 1分钟后Session自动失效 以分钟为单位-->
<session-timeout>1</session-timeout>
</session-config>
9JSP
8.1 什么是JSP
Java Server Pages:Java服务器端页面,也和Servlet一样,用于动态Web技术
最大的特点:
-
写JSP就像在写HTML
-
区别
-
HTML只给用户提供静态数据
-
JSP页面可以嵌入JAVA代码,为用户提供动态数据
-
8.2 JSP原理
思路:JSP到底怎么执行的!
-
代码层面没有任何问题
-
服务器内部工作
-
tomcat中有一个work目录;
-
IDEA中使用Tomcat的会在IDEA的tomcat中产生一个work目录
-
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet
JSp最终也会被转换成为一个Java类
JSP本质就是一个Servlet
public abstract class HttpJspBase extends HttpServlet implements HttpJspPage
//初始化
public void _jspInit(){
}
//销毁
pubilc void _jspDestroy(){
}
//JSPService
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
1 判断请求
2 内置一些对象
final javax.servlet.jsp.PageContext pageContext;//页面上下文
javax.servlet.http.HttpSession session=null; //session
final javax.servlet.ServletContext application;//applicationContext
final javax.servlet.ServletConfig config;//config 配置
javax.servlet.jsp.JspWriter out = null;//out
final java.lang.Object page = this;//page:当前页面
HttpServletRequest request //请求
HttpServletResponse response //响应
3 输出页面前增加的代码
response.setContentType("text/html; charset=UTF-8");//设置响应的页面类型
pageContext = _jspxFactory.getPageContext(this, request, response,
null, false, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
4.以上的这些对象我们可以在JSP页面中直接使用
在JSP页面中:
只要是JAVA代码就会原封不动的输出;
如果是HTML代码,就会 被转换为:
out.write("<html>\r\n");
这样的格式,输出到前端!
遇见的问题在IDEA中无法导入tomcat的lib目录
解决办法:
在弹出的窗口中选择tomcat所在的目录,进入里面的lib目录,点击ok