Tomcat乱码、请求转发、响应重定向、ServletConfig、ServletContext、Cookie、Session
1. 五种乱码问题
1.1 Tomcat乱码
在安装好Tomcat之后,点击start.bat启动Tomcat,发现在命令行log乱码
这是因为,Tomcat的log默认解码字符集为utf-8,而中文win10默认字符集为gbk
所以,修改Tomcat默认字符集即可修正乱码问题(修改Tomcat安装目录下conf>logging.properties的java.util.logging.ConsoleHandler.encoding = gbk)
1.2 IDEA中Tomcat控制台乱码
在IDEA中部署Tomcat之后,运行Tomcat发现在IDEA的控制台中Tomcat日志乱码
解决一:如上文所示,修改Tomcat安装目录下conf>logging.properties的java.util.logging.ConsoleHandler.encoding为IDEA项目设定的字符集
解决二:点击IDEA的菜单栏Help>Edit Custom VMOptions选项,进入idea.exe.vmoptions文件,在文件末尾添加 -Dfile.encoding=uft-8 ,重启生效
1.3 前端乱码
在web目录下的页面文件,如果没有指定浏览器解析的字符集,那么浏览器默认使用本机的字符集
下面不指定浏览器使用何种字符集解析,但项目文件的字符集为utf-8
结果显示
这里出现乱码是因为index.jsp使用的utf-8编码,而浏览器使用的是gbk
解决办法是在jsp文件中指定浏览器的解析字符集
1.4 Request乱码
在网页中填写中文,发送请求到服务器端会出现乱码
对于请求乱码,有以下三种解决方式
1.4.1重构编码
对于中文系统的浏览器的编码字符集一般为iso-8859-1,所以对于请求乱码,可以先用对应的字符集编码,再用项目的字符集解码
1.4.2 get方法乱码
对于get方法,由于其传输是将数据混合到url中,所以,可以指定Tomcat的server.xml配置文件的Connector标签的URIEncoding为项目字符集
1.4.3 post方法乱码
对于post方法,可以手动指定传输数据包的字符集
1.5 Response乱码
对于服务器响应回的中文出现乱码,一种是前端乱码(网页乱码),其情况及解决如上
另一种是服务器直接调用打印流的乱码
这里问题如前端乱码,是因为打印流的字符集为项目字符集,而浏览器解析字符集为gbk,所以需要告知浏览器以何种字符集解析
2. 请求转发与响应重定向
2.1 比较
比较 | 请求转发 | 响应重定向 |
---|---|---|
相同点 | 第一个servlet无法解决请求,需要借助其他servlet完成 | |
不同点1 | 属于服务器行为,对浏览器是屏蔽的,所以浏览器地址栏不会发生变化 | 属于浏览器行为,所以浏览器地址栏会发生变化 |
不同点2 | 请求参数可以传递 | 请求参数无法传递 |
不同点3 | 可以请求WEB-INF目录下的资源,但不能请求外部资源 | 不可以请求WEB-INF目录下的资源,但可以请求外部资源 |
不同点4 | 浏览器与服务器之间请求一次 | 浏览器与服务器之间请求多次 |
类比:张三找李四借钱,但李四没钱 | 李四找王五借钱,然后再借给张三 | 李四让张三找王五借钱 |
2.2 实现
- 请求转发
public class Servlet1 extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
req.getRequestDispatcher("王五").forward(req, resp);
}
}
- 响应重定向
public class Servlet1 extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
resp.sendRedirect("王五");
}
}
3. ServletConfig与ServletContext
3.1 比较
比较 | ServletConfig | ServletContext |
---|---|---|
相同点 | 初始化Servlet的某些对象 | |
不同点1 | 所初始化的对象只能作用于该Servlet | 所初始化的对象作用于整个项目(域对象) |
不同点2 | 访问只能使用this或super关键字 | 访问可使用this或super或req |
不同点3 | 不能在java代码中添加属性 | 可以调用setAttribute方法添加属性 |
类比 | 一个类中的成员对象 | 一个类中的全局对象 |
3.2 实现
- ServeltConfig
<?xml version="1.0" encoding="utf-8" ?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<init-param>
<param-name>Servlet初始化属性名</param-name>
<param-value>Servlet初始化属性值</param-value>
</init-param>
</servlet>
</web-app>
public class Servlet1 extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
//获取单个ServletConfig配置的参数值
this.getServletConfig().getInitParameter("Servlet初始化属性名");
super.getServletConfig().getInitParameter("Servlet初始化属性名");
//获取所有ServletConfig配置的参数值
Enumeration<> pnames=this.getInitConfigNames();
for(pnames.hasMoreElements()){
this.getInitParameter(pnames.nextElement());
}
}
- ServletContext
<?xml version="1.0" encoding="utf-8" ?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<context-param>
<param-name>Servlet初始化属性名</param-name>
<param-value>Servlet初始化属性值</param-value>
</context-param>
</web-app>
public class Servlet1 extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
//获取单个ServletContext配置的参数值
this.getServletContext().getInitParameter("Servlet初始化属性名");
super.getServletContext().getInitParameter("Servlet初始化属性名");
req.getServletContext().getInitParameter("Servlet初始化属性名");
//获取所有ServletConfig配置的参数值
Enumeration<> pnames=this.getInitConfigNames();
for(pnames.hasMoreElements()){
this.getInitParameter(pnames.nextElement());
//向域对象添加属性
this.setAttribute("Servlet初始化属性名","Servlet初始化属性值");
//获取添加的属性值
this.getAttribute("添加的属性名");
}
}
4. Cookie与Session
4.1 比较
比较 | Cookie | Session |
---|---|---|
相同点 | 记录并存储浏览器与服务器之间的交互数据 | |
联系 | 当浏览器第一次访问服务器时,服务器会生成一个session对象,并将该session对象的地址以set-cookie的属性发送给浏览器,浏览器会将这些数据临时保存下来,当浏览器再次访问服务器时,会将当时保存的临时数据又以cookie请求头的方式发送给服务器,服务器再根据cookie中JSESSIONID属性值找到对应的session对象 | |
不同点1 | 保存信息至浏览器 | 保存信息至服务器 |
不同点2:失效的情况 | 浏览器关闭、手动清除、达到最大存活时间 | 项目重启或关闭、达到最大不活动时间 |
不同点3 | cookie失效会导致session内容清理 |
4.2 手动设置失效时间
- 手动设置cookie最大存活时间
public class Servlet1 extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
//手动创建cookie
Cookie c1=new Cookie("cookie1","my cookie");
//手动设置cookie最大存活时间
c1.setMaxAge(10);//无访问活动,10秒之后c1失效
//更改c1的内容
c1.setValue("changed cookie");
//设置提交路径,使c1在浏览器访问指定资源路径时才提交
c1.setPath("/checked");
//添加
resp.addCookie(c1);
//获取某个指定cookie
String c2=req.getHeader("c4");
//获取所有cookie
Cookie[] cookies=req.getCookies();
}
}
- 手动设置session最大不活动时间
在java代码中实现
public class Servlet2 extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
//1. 获取session
HttpSession session=req.getSession();
//2. 手动设置其最大不活动时间
session.setMaxInactiveInterval(10);//无访问活动,10秒之后session失效
}
}
在Tomcat的web.xml配置文件中实现