response.setStatus(302);
response.setHeader("location","/day/1.html");
String data="asdasdasdadasdasdasdasasasasasasa";
ByteArrayOutputStream bout=new ByteArrayOutputStream();
GZIPOutputStream gout=new GZIPOutputStream(bout);
gout.write(data.getBytes());
gout.close();
byte gzip[]=bout.toByteArray();//得到压缩后的数据
//通知浏览器数据采用压缩格式
response.setHeader("Content-Encoding","gzip");
response.setHeader("Content-Length",gzip.length+"");
response.getOutputStream().write(gzip);
response.setHeader("content-type","image/jpeg");//可参看web.xml
InputStream in=this.getServletContext().getSourceAsStream("/1.jpg");
int len=0;
byte buffer[]=new byte[1024];
OutputStream out=response.getOutputStream();
while((len=in.read(buffer))>0){
out.write(buffer,0,len);
}
response.setHeader("refresh","3;url='http://www.sina.com'");
格式:HTTP版本号 状态码 原因叙述
举例:HTTP/1.1 200 OK
用于表示服务器对请求的处理结果,它是一个三位的十进制数,响应状态码分为5类,如下所示:
状态码 | 含义 |
---|---|
100~199 | 表示成功接收请求,要求客户端继续提交下一次请求才能完成整个处理过程 |
200~299 | 表示成功接收请求并完成整个处理过程,常用200 |
300~399 | 为完成请求,客户需要进一步细化请求,例如,请求的资源已经移动到一个新地址,常用302、307 |
400~499 | 客户端的请求有误,常用404 |
500~599 | 服务器端出现请求,常用500 |
何为一次http请求?
过程:Servlet调用init()方法进行初始化,调用service()方法来处理客户端的请求,调用destroy()方法终止,最后Servlet由JVM的垃圾回收器进行垃圾回收。
Servlet配置
<servlet>
<servlet-name>TestServletservlet-name>
<servlet-class>com.wenxue.servlet.TestServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>TestServlet<servlet-name>
<url-pattern>/TestServleturl-pattern>
servlet-mapping>
Servlet文件
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
// 扩展 HttpServlet 类
public class TestWorld extends HttpServlet {
private String message;
public void init() throws ServletException
{
// 执行必需的初始化
message = "Hello World";
}
public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
// 设置响应内容类型
response.setContentType("text/html");
// 实际的逻辑是在这里
PrintWriter out = response.getWriter();
out.println(""
+ message + "");
}
public void destroy(){
// 什么也不做
}
}
init()方法在第一次创建Servlet时被调用,并且只被调用一次,用于初始化。
每次服务器收到一个Servlet请求时,服务器会产生一个新的线程并调用服务,service()方法会检查HTTP请求类型(GET、POST、PUT、DELETE),并在适当的时候调用doGet、doPost、doPut、doDelete等方法。所以不用对service方法进行任何操作,只需重写doGet或doPost方法即可。
destroy()方法在Servlet生命周期结束时被调用,并且只被调用一次,可以用来关闭数据库连接、停止后台进程、把Cookie列表或点击计数器写入到磁盘,并执行其它类似的清理活动。在调用destroy()方法后,servlet对象被标记为垃圾回收。
基本概念:指用户开一个网站,访问一个网站,只要不关闭浏览器,不管用户点击多少超链接,访问多少资源,直到用户关闭浏览器,整个过程我们称为一次会话。
Cookie cookie=new Cookie("name","wenxue");
//设置cookie的生命周期
cookie.setMaxAge(3600);
//把cookie信息回写给浏览器
response.addCookie(cookie);
//读取所有的cookie信息,再选中你要的cookie
Cookie cookies[]=request.getCookies();
cookies[i].getName();
cookies[i].getValue();
我们可以把cookie想象成一张表,名字 值对应。
//存放:
String val=java.net.URLEncoder.encode("文学","utf-8");
Cookie cookie=new Cookie("name",val);
//取出:
String val=java.net.URLDecoder.decode(cookie.getValue(),"utf-8");
session周期是发呆时间,如果我们设置session是10s,是指在10s内,没有访问过session,session中的属性失效,如果在9s时,访问session,则重新计时。cookie的生命周期是指累计时间,不管用户是否访问过该cookie,cookie都会消失。
invalidate()<=>该方法是让session中所有属性失效,通常用于安全退出。
关掉IE,再打开,上次购买的商品还在,涉及到session的销毁时间。
分析: 我们的session生命周期如果是30min,该session不会随浏览器的关闭而自动销毁,而是会到30min后,才才会被服务器销毁。我们可以使用代码实现该功能:
Cookie cookie=new Cookie("JSESSIONID",session.getId());
cookie.setMaxAge(60*30);
response.addCookie(cookie);
关闭tomcat、reload web应用、时间到、invalidate也会让session失效
因为session会占用服务器的内存,因此不要向session存放过多,过大的对象,会影响性能。
ServletContext servletContext=this.getServletContext();
ServletContext servletConfig=this.getServletConfig().getServletContext();
ServletContext.setAttribute(name,value);
servletContext.getAttribute(name);
如果希望所有的servlet都可以访问配置
<context-param>
<param-name>nameparam-name>
<param-value>scottparam-value>
context-param>
访问
String val=this.getServletContext().getInitParameter("name");
//读取资源文件,先创建db.properties文件 name=123 value=123
InputStream is=getServletContext().getResourceStream("db.properties");
Properties pp=new Properties();
pp.load(is);
pp.getProperty("name");
//如果文件放在src目录下,我们应该使用类加载器来读取
is=Servlet.class.getClassLoader().getResourceAsStream("db.properties");
//获取文件全路径
String path=this.getServletContext().getRealPath("/img/sun.jpg");
request.getRequestDispatcher("/servlet").forward(request,response);
response.sendRedirect("login.jsp");
Servlet过滤器用来动态的拦截请求和响应,以变换或使用包含在请求或响应中的信息。
在web.xml文件中进行配置
<filter>
<filter-name>LogFilterfilter-name>
<filter-class>com.wenxue.filter.LogFilterfilter-class>
<init-param>
<param-name>Siteparam-name>
<param-value>菜鸟教程param-value>
init-param>
filter>
<filter-mapping>
<filter-name>LogFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
过滤器操作
import javax.servlet.*;
import java.util.*;
//实现 Filter 类
public class LogFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
// 用来获取web.xml配置文件中的初始化参数
String site = config.getInitParameter("Site");
// 输出初始化参数
System.out.println("网站名称: " + site);
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException {
// 把请求传回过滤链
chain.doFilter(request,response);
}
public void destroy( ){
/* 在 Filter 实例被 Web 容器从服务移除之前调用 */
}
}
request.setCharacterEncoding("utf-8");
//写一个工具类,将字符串转码
public static String getNewString(String str){
String newString="";
try{
newString=new String(str.getBytes("iso-8859-1"),"utf-8");
}catch(Exception e){
e.printStackTrace();
}
return newString;
}
response.sendRedirect("servlet地址?username=文学");
补充:当下载文件时,可能提示框是中文乱码
String temp=java.net.URLEncoder.encode("传奇.mp4","utf-8");
response.setHeader("Content-Disposition","attachment;filename="+temp);
存储到数据库的数据也有可能乱码,在连接字符串中设置编码即可。
介绍:jsp文件被第一次访问时,web服务器会将其翻译成一个servlet,然后将其编译成一个class文件,再将其加载到内存,如果是第二次或者以后,就直接访问内存中的实例,因此jsp也是单例,所以第一次访问jsp文件网站速度会比较慢,如果某个jsp文件被修改了,就相当于重新访问jsp文件,即相当于第一次。
用于从jsp发送一个信息到容器,比如设置全局变量,文字编码,引入包等。
<%@page contentType="text/html;charset=utf-8"%>
page常用属性:contentType和pageEncoding区别?
前者指定网页以什么方式显示,后者指定servlet引擎怎么翻译jsp->servlet,并制定网页以什么方式显示页面。
<%@include file="文件路径"%>
该指令用于静态导入一个文件到本页面。
java片段
<% java代码 %>
<%=1+2 %>//中间写表达式
<% int i=3 %>//该jsp对应的servlet的成员变量
<jsp:forward page="/manage.jsp"/>
在开发jsp的过程中,我们通常把jsp页面放入WEB-INF目录,目的是为了防止用户直接访问jsp页面,在WEB-ROOT下我们有一个入口页面,它的目的主要是转发。
include file=""/>//动态引入文件
引入文件
<%@include file="文件路径"%>
和
比较?
相同点:把一个文件引入到另外一个文件中。
不同点:
静态引入:把两个jsp翻译成一个servlet,所以被引入的文件不要包括。
也可以,最好不包括。 getParameter(String name);//name表示表单的参数名
getParameterValues(String name);//使用得到的是String[]
setAttribute(String name,Object obj);//设置名字为name的obj,值是obj
getAttribute(String name);//返回由name指定的属性值,如果不存在就返回null
getCookie();
addCookie(Cookie cookie);
sendRedirect("welcome.jsp");//重定向
setAttribute(String name,Object obj);
getAttribute(String name);
if test="${salary > 2000}">
"${salary}"/>
if>
forEach var="name" items="expression" varStatus="name" begin="expression" end="expression" step="expression">
body content...
forEach>
var:迭代参数的名称。在迭代体中可以使用的变量的名称,用来表示每一个迭代变量。类型为String。
items:要进行迭代的集合。对于它所支持的类型将在下面进行讲解。
varStatus:迭代变量的名称,用来表示迭代的状态,可以访问到迭代自身的信息。
begin:如果指定了items,那么迭代就从items[begin]开始进行迭代;如果没有指定items,那么就从begin开始迭代。它的类型为整数。
end:如果指定了items,那么就在items[end]结束迭代;如果没有指定items,那么就在end结束迭代。它的类型也为整数。
step:迭代的步长。
标签的items属性支持Java平台所提供的所有标准集合类型。此外,您可以使用该操作来迭代数组(包括基本类型数组)中的元素。它所支持的集合类型以及迭代的元素如下所示:
不论是对整数还是对集合进行迭代,的varStatus属性所起的作用相同。和var属性一样,varStatus用于创建限定了作用域的变量(改变量只在当前标签体内起作用)。不过,由varStatus属性命名的变量并不存储当前索引值或当前元素,而是赋予javax.servlet.jsp.jstl.core.LoopTagStatus类的实例。该类包含了一系列的特性,它们描述了迭代的当前状态,如下这些属性的含义如下所示:
表格隔行背景色变化
forEach var="item" items="${contents}" varStatus="status">
if test="${status.count%2==0}">bgcolor="#CCCCFE"if> align="left">xxx
forEach>
el表达式会依次从Page、Request、Session、Application域中取出数据。
${usernmaea}
<error-page>
<error-code>404error-code>
<location>/WEB-INF/error.jsplocation>
error-page>
<error-page>
<error-code>500error-code>
<location>/WEB-INF/error.jsplocation>
error-page>
<error-page>
<exception-type>java.lang.Exceptionexception-type>
<location>/WEB-INF/error.jsplocation>
error-page>
<%@ page language="java" contentType="text/html;charset=utf-8" pageEncoding="utf-8" isErrorPage="true"%>
<body>
errorMsg:<%=exception.getMessage() %>
body>