setMaxAge(int seconds):
-
正数:将Cookie数据写到硬盘的文件中。持久化存储。cookie存活时间。
-
负数:负数就代表默认值。
-
零:服务器端想要删除客户端的cookie信息,就定义为零,就删除cookie信息。
package com.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;
@WebServlet(“/cookieDemo1”)
public class CookieDemo1 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie1 = new Cookie(“msg”,“hello”);
//将Cookie数据写到硬盘的文件中,30秒之内会删除cookie
//cookie1.setMaxAge(30);
//默认
//cookie1.setMaxAge(-1);
//删除cookie信息
cookie1.setMaxAge(0);
resp.addCookie(cookie1);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
this.doGet(req, resp);
}
}
tomcat 8之前,cookie是不能支持存储中文数据的。
- 那么tomcat 8之前,我们一般采用url编码或base64编码来存储中文进行发送。
tomcat 8之后,cookie支持中文数据。
一个tomcat服务器,部署了多个web项目,那么这些web项目中的cookie能不能共享?
默认情况下,cookie是不能共享的。
setPath(String path): 设置cookie的范围取值。默认情况下,设置当前的虚拟目录。
如果要共享,则可以将path设置为" / "(范围大一点),就是http://localhost:8080/ ,以后的路径,都可以共享这个cookie。
不同的tomcat服务器cookie共享问题?
setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享。
setDomain(“.baidu.com”) , 那么tieba.baidu.com和new.baidu.com中cookie可以共享。
=============================================================================
cookie的特点:
-
cookie存储数据在客户端浏览器。
-
浏览器对于单个cookie的大小有限制(4kb)以及对同一个域名下的总cookie数量也有限制(一般20个)。
cookie的作用:
-
cookie一般用于存储少量的不太敏感的数据。
-
在不登录的情况下,完成服务器对客户端的身份识别。
===========================================================================
Session就是一个接口(HttpSession)。
Session就是会话。它是用来维护一个客户端和服务器之间关联的一种技术。
每个客户端都有自己的一个Session会话。
Session会话中,我们经常用来保存用户登录之后的信息,是在服务器端的。
===========================================================================
在Servlet中,我们有request这样的api参数。
因此,我们直接可以使用request.getSession()方法来创建。
主要注意第一次调用是:创建Session会话,以后调用便是获取第一次创建的Session会话了。
如果我们想要判断当前的Session是不是刚刚创建出来的,官方给出了一个isNew()的方法,来判断是不是刚刚创建出来的Session。
每个Session会话都有一个id值,这个id是唯一的!
通过getId()方法来得到Session的会话id值。
package com.test.day02;
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;
@WebServlet(value=“/session1”)
public class HttpSessionTest extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
//创建session会话,一个会话只会创建一次,往后调用都只调用该会话一次。
HttpSession session = req.getSession();
//session.isNew()方法:判断是不是刚刚创建的session会话
boolean new1 = session.isNew();
System.out.println(new1);
String id = session.getId();
System.out.println(id);
System.out.println();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
this.doGet(req, resp);
}
}
================================================================================
既然存域对象数据,肯定调用setAttribute()方法啥的。
package com.test.day02;
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;
@WebServlet(value=“/session1”)
public class HttpSessionTest extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
//创建session会话,一个会话只会创建一次,往后调用都只调用该会话一次。
HttpSession session = req.getSession();
session.setAttribute(“key1”, “value1”);
Object attribute = session.getAttribute(“key1”);
System.out.println();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
this.doGet(req, resp);
}
}
===============================================================================
设置Session的超时时长,超过指定的时长,Session就会被销毁。这里是以秒为单位的
session.setMaxInactiveInterval(1000);
获取Session的超时时长,如果设置超时时长它是有默认时长的(默认时长为1800秒,也就是30分钟,这个是可以修改的可以去tomcat服务器web.xml去配置默认时长)。
int maxInactiveInterval = session.getMaxInactiveInterval();
tomcat默认session超时时长的web.xml配置:
在服务端,如果session在规定的超时时间内,还没有接受到该session的请求,一旦超时它就会被删除。
如果在超时时间内接受到请求了,那么超时时长就会重新计时,原理就这么简单。
再就是如果超时时长设置为负数,那么它就永远不超时。
还有一个invalidate()方法,该方法作用就是让当前session会话马上超时无效。
package com.test.day02;
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;
@WebServlet(value=“/session1”)
public class HttpSessionTest extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
//创建session会话,一个会话只会创建一次,往后调用都只调用该会话一次。
HttpSession session = req.getSession();
//session.isNew()方法:判断是不是刚刚创建的session会话
boolean new1 = session.isNew();
System.out.println(new1);
String id = session.getId();
System.out.println(id);
session.setAttribute(“key1”, “value1”);
Object attribute = session.getAttribute(“key1”);
//设置Session的超时时长,超过指定的时长,Session就会被销毁。这里是以秒为单位的
//session.setMaxInactiveInterval(1000);
//获取Session的超时时长,如果设置超时时长它是有默认时长的(默认时长为1800秒,也就是30分钟,这个是可以修改的可以去tomcat服务器web.xml去配置默认时长)。
int maxInactiveInterval = session.getMaxInactiveInterval();
//让session会话,立刻超时!
session.invalidate();
resp.getWriter().write(“session已经被设置为超时了”);
System.out.println();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
this.doGet(req, resp);
}
}
=======================================================================================
其实,服务器端第一次创建session对象时,它会创建一个cookie对象,对象的键为:JSESSIONID,值为:新创建出来的Session的id值。
换句话说,session技术,底层其实是基于cookie技术来实现的。
============================================================================
Filter过滤器是JavaWeb的三大组件之一。
Filter过滤器它是JavaEE的规范,也就是接口。
Filter过滤器的作用就是: 拦截请求,过滤响应。
常见操作:
-
自动登录
-
统一设置编码格式
-
访问权限控制
-
敏感字符过滤等。
============================================================================
步骤:
-
1.定义一个类,实现接口Filter(javax.servlet.Filter下的)。
-
2.重写方法。
-
3.配置拦截路径。
一次请求中,要经过两次过滤拦截,进来时,过滤一次;发送响应数据过滤一次。
简单注解使用:
package com.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
//注解用法 , " /* "访问所有资源都要执行该过滤器。
@WebFilter(“/*”)
public class FilterDemo01 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println(“Filter被执行了”);
// 放行操作
chain.doFilter(request, response);
//这一步骤的意思就是,如果不执行这句活,客户端访问我们的前端页面是访问不到任何内容的,因为被拦截了
}
@Override
public void destroy() {
}
}
===============================================================================
过滤器的web.xml配置和Servlet配置差不多的:
<?xml version="1.0" encoding="UTF-8"?>FilterTest02
com.filter.FilterTest02
FilterTest02
/*
=============================================================================
过滤器执行流程:
-
执行过滤器
-
执行放行后的资源。
-
回来执行过滤器放行代码下边的代码。
理解一个请求中,经过两次过滤拦截:
过滤器的生命周期:
-
init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次,用于加载资源。
-
doFilter:每一次请求被拦截时,doFilter方法就会被执行,被执行多次。
-
destroy:在服务器关闭后,Filter对选哪个被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次,用于释放资源。
package com.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
@WebFilter(“/*”)
public class FilterTest03 implements Filter{
//在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次,用于加载资源。
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println(“init…”);
}
//每一次请求被拦截时,doFilter就会被执行,被执行多次。
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println(“doFilter…”);
}
//在服务器关闭后,Filter对选哪个被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次,用于释放资源。
@Override
public void destroy() {
System.out.println(“destroy…”);
}
}
================================================================================
拦截路径配置:
-
具体资源路径:/index.jsp 只有访问index.jsp资源时,过滤器才会被执行。
-
拦截目录:/test/* 方位/test下的所有资源时,过滤器都会被执行。
-
后缀名拦截:*.jsp 访问所有资源时,过滤器都会被执行。
-
拦截所有资源:/* 访问所有资源时,过滤器都会被执行。
================================================================================
注解配置:
设置dispatcherTypes属性。
-
request:默认值。浏览器直接请求资源。
-
forward:抓发访问资源。
-
include:包含访问资源。
-
error:错误跳转。
-
async:异步访问资源。(sync:同步,async:异步)
dispatcherTypes = DispatcherType.REQUEST;
浏览器直接请求资源index.jsp时,该过滤器会被执行,像那些请求抓发的操作就不会执行。
dispatcherTypes = DispatcherType.FORWARD;
只有请求抓发访问index.jsp时,该过滤器才会被执行。
请求访问和转发都想被filter拦截处理,那就用数组方式来解决。
16.2 web.xml 配置 和 ServletRequest
web.xml 配置:
doFilter方法中的ServletRequest,一般使用的时候一定强转为HttpServletRequest,因为多数方法都在HttpServletRequest中。
===============================================================================
过滤器还是照常拦截过滤的,主要是顺序需要注意!
首先,先按照顺序执行web.xml配置的过滤器;之后按照字典顺序(0~9, az),就是按照09或a~z的顺序来对注解排顺序。
请求时按照上面顺序来,服务器响应数据经过过滤器时,恰好反着来。
======================================================================
JSON(JavaScirpt Object Notation)是一种轻量级的数据交换格式。
轻量级指的是跟xml作比较,很轻量。
数据交换指的是客户端和服务器之间业务数据的传递格式。
**json定义:
json是由键值对组成,并且由花括号(大括号)包围,键和值之间使用冒号进行分割,多组键值对之间进行逗号进行分割。**
json就是一个对象。
JSON存在两种形式:
-
一种是对象的形式存在,叫做json对象。
-
一种是字符串的形式存在,叫做json字符串。
因此,对应两种方法进行转换:
-
JSON.stringify():把json对象转换成为json字符串。
-
JSON.parse():把json字符串转换为json对象。
一般我们要操作json中的数据的时候,需要json对象的格式。
一般我们要在客户端和服务器之间进行数据交换的时候,使用json字符串。
18.3.1 JavaBean 和 json 的互传
javaBean 和 Json 的转换:
-
1.导入gson的jar包(去maven下载)。
-
2.创建gson实例对象。
-
3.调用gson的toJson方法可以将java对象转换成为json字符串形式。
-
4.调用gson的fromJson把json字符串转换回java对象。
package com.itholmes;
import org.junit.Test;
import com.google.gson.Gson;
public class JsonTest {
//javaBean 和 Json 的转换
@Test
public void test01() {
//我自己定义了person对象,设定id和name值。
Person person = new Person(1,“itholmes”);
//创建gson对象实例
Gson gson = new Gson();
//toJson方法可以将java对象转换成为json字符串形式。
String json = gson.toJson(person);
System.out.println(json);
//fromJson把json字符串转换回java对象:
//第一个参数是json字符串,第二个参数是转换回去的java对象类型
Person fromJson = gson.fromJson(json, Person.class);
System.out.println(fromJson);
}
}
Person类如下:
package com.itholmes;
public class Person {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return “Person [id=” + id + “, name=” + name + “]”;
}
public Person(Integer id, String name) {
super();
this.id = id;
this.name = name;
}
}
18.3.2 List 和 json 的互传
注意TypeToken的作用???要搞清楚!
package com.itholmes;
import java.util.List;
import com.google.gson.reflect.TypeToken;
public class PersonListType extends TypeToken<List>{
}
package com.itholmes;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.google.gson.Gson;
public class JsonTest {
//List 和 json 的互传
@Test
public void test02() {
List list = new ArrayList();
list.add(new Person(1,“itholmes01”));
list.add(new Person(2,“itholmes02”));
Gson gson = new Gson();
//把list集合中的转换为字符串数组
String json = gson.toJson(list);
System.out.println(json);
List fromJson = gson.fromJson(json, new PersonListType().getType());
System.out.println(fromJson);
//我们想要转换为person类型,仅仅是用list.class是不行的,我们要使用gson包中的TypeToken。
Person p = (Person) fromJson.get(0);
System.out.println§;
}
}
18.3.3 Map 和 json 的互换
和集合差不多:
继承TypeToken<Map<Integer,Person>>的类:
package com.itholmes;
import java.util.Map;
import com.google.gson.reflect.TypeToken;
public class PersonMapType extends TypeToken<Map<Integer,Person>>{
}
package com.itholmes;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import com.google.gson.Gson;
public class JsonTest {
//Map 和 json 集合转换
@Test
public void test03() {
Map<Integer,Person> map = new HashMap<Integer, Person>();
map.put(1, new Person(1,“itholmes01”));
map.put(2, new Person(2,“itholmes02”));
Gson gson = new Gson();
String json = gson.toJson(map);
System.out.println(json);
Map<Integer,Person> fromJson = gson.fromJson(json, new PersonMapType().getType());
System.out.println(fromJson);
Person p = fromJson.get(2);
System.out.println§;
}
}
除了上面直接创建对象来获取type类型,我们还可以直接创建匿名类的操作:
Map<Integer,Person> fromJson = gson.fromJson(json, new TypeToken<Map<Integer,Person>>() {}.getType());
上面的方式就不用另外创建类对象去了,很简单!
==========================================================================
国际化的英文:Internationalization。
由于拼写过长,就以i开头,以n结尾,中间18个字母,也就简化为了i18n。
代码内容如下(就是对象上面来的):
package com.itholmes.i18n;
import java.util.Locale;
import java.util.ResourceBundle;
import org.apache.tomcat.jni.Local;
import org.junit.Test;
public class I18nTest {
@Test
public void testLocale() {
//获取你系统默认的语言,国家信息。
Locale locale = Locale.getDefault();
System.out.println(locale);
//查看所有的国家语言信息
for(Locale availableLocale : Locale.getAvailableLocales()) {
System.out.println(availableLocale);
}
//获取中文,中文的常量的locale对象
System.out.println(Locale.CHINA);
//获取英文,美国的常量locale对象
System.out.println(Locale.US);
}
@Test
public void testI18n() {
Locale ch = Locale.CHINA;
Locale us = Locale.US;
ResourceBundle bundle = ResourceBundle.getBundle(“i18n”,ch);
String username = bundle.getString(“username”);
String password = bundle.getString(“password”);
String sex = bundle.getString(“sex”);
String age = bundle.getString(“age”);
ResourceBundle bundle2 = ResourceBundle.getBundle(“i18n”,us);
String username2 = bundle2.getString(“username”);
String password2 = bundle2.getString(“password”);
String sex2 = bundle2.getString(“sex”);
String age2 = bundle2.getString(“age”);
System.out.println();
}
}
通过请求头实现,就是页面发送请求协议携带Accept-Language信息,发送到浏览器。
通过request.getLocale()拿到我们需要发送的格式,进而通过bundle.getString()方法获取。
<%@page import=“java.util.ResourceBundle”%>
<%@page import=“java.util.Locale”%>
<%@ page language=“java” contentType=“text/html; charset=UTF-8”
pageEncoding=“UTF-8”%>
<%
Locale locale = request.getLocale();
System.out.println(locale);
ResourceBundle bundle = ResourceBundle.getBundle(“i18n”,locale);
%>
请求头发送Accept-Language类型是什么就返回响应的:
<%=bundle.getString(“username”) %>
<%=bundle.getString(“password”) %>
<%=bundle.getString(“sex”) %>
<%=bundle.getString(“age”) %>
平时,我们可能遇到这种有个按钮,可以中文转换英文,英文转换中文,可以按照下面代码格式来操作转换:
<%@page import=“java.util.ResourceBundle”%>
<%@page import=“java.util.Locale”%>
<%@ page language=“java” contentType=“text/html; charset=UTF-8”
pageEncoding=“UTF-8”%>
<%
Locale locale = null;
String typeLangu = request.getParameter(“typeLangu”);
if(“cn”.equals(typeLangu)){
locale = Locale.CHINA;
}else if(“usa”.equals(typeLangu)){
locale = Locale.US;
}else{
locale = request.getLocale();
}
System.out.println(locale);
ResourceBundle bundle = ResourceBundle.getBundle(“i18n”,locale);
%>
中文|
请求头发送Accept-Language类型是什么就返回响应的:
<%=bundle.getString(“username”) %>
<%=bundle.getString(“password”) %>
<%=bundle.getString(“sex”) %>
<%=bundle.getString(“age”) %>
我们,平时一般不适用jsp代码格式来写代码,反而使用EL表达式或JSTL标签库来修饰jsp。
JSTL标签库使用:<%@ taglib prefix=“fmt” uri=“http://java.sun.com/jsp/jstl/fmt” %>
步骤如下:
<%@page import=“java.util.ResourceBundle”%>
<%@page import=“java.util.Locale”%>
<%@ page language=“java” contentType=“text/html; charset=UTF-8”
pageEncoding=“UTF-8”%>
<%@ taglib prefix=“fmt” uri=“http://java.sun.com/jsp/jstl/fmt” %>
中文|
<fmt:setLocale value=“${param.locale}”/>
<fmt:setBundle basename=“i18n”/>
<fmt:message key=“username”/>
<fmt:message key=“password”/>
<fmt:message key=“sex”/>
<fmt:message key=“age”/>