1 Servlet基础
1.0 常用Servlet类的继承关系
1.1 Servlet中常用对象
- ServletContext:是对当前项目上下文的描述
- ServletRequest:浏览器向服务器的请求
request.getParameter("username"); //获得单个数据
request.getParameterValues("love"); //获得一组数据:用于复选框这种多项数据的情况
request.setCharacterEncoding("UTF-8"); //处理中文乱码,此方法只对POST请求有效,GET需要单独处理
request.setAttribute("login", "true");
其它request的方法
setAttribute(String name,Object) //设置名字为name的request的参数值
getAttributeNames() //返回request对象所有属性的名字集合,结果是一个枚举的实例
getCookies() //返回客户端的所有Cookie对象,结果是一个Cookie数组
getCharacterEncoding() //返回请求中的字符编码方式
getContentLength() //返回请求的Body的长度
getHeader(String name) //获得HTTP协议定义的文件头信息
getHeaders(String name) //返回指定名字的request Header的所有值,结果是一个枚举的实例
getHeaderNames() //返回所以request Header的名字,结果是一个枚举的实例
getInputStream() //返回请求的输入流,用于获得请求中的数据
getMethod() //获得客户端向服务器端传送数据的方法
getParameter(String name)//获得客户端传送给服务器端的有name指定的参数值
getParameterNames() //获得客户端传送给服务器端的所有参数的名字,结果是一个枚举的实例
getParametervalues(String name) //获得有name指定的参数的所有值
getProtocol() //获取客户端向服务器端传送数据所依据的协议名称
getQueryString() //获得查询字符串
getRequestURI() //获取发出请求字符串的客户端地址
getRemoteAddr() //获取客户端的IP地址
getRemoteHost() //获取客户端的名字
getSession([Boolean create]) //返回和请求相关Session
getServerName() //获取服务器的名字
getServletPath() //获取客户端所请求的脚本文件的路径
getServerPort() //获取服务器的端口号
removeAttribute(String name) //删除请求中的一个属性
- ServletResponse:服务器对浏览器做出的响应,将需要发送给浏览器的所有数据全部存放在此对象上。将所需要的数据,存放在指定的流中,数据将显示到浏览器中
response.getWriter(); //一般在程序中发送数据内容
response.getOutputStream(); //字节流一般在程序中使用具有拷贝功能
response.setContentType("text/html;charset=utf-8"); //通知tomcat和浏览器发送数据的编码
response.setHeader("Cache-Control","no-cache"); //设置客户端头信息
response.sendRedirect("new.jsp");//重定向
//在jsp页面实现重定向:<%response.sendRedirect("new.jsp"); %>
Object obj = request.getAttribute("login");
getRequestDispatcher(String path);//服务器:当前程序需要获得请求调度器
//forward:当调度器协调多个servlet时,此方法返回最后一个servlet的页面输出内容
1.2 Servlet代码示例
public class FormServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();//★★获得字符流
//发送数据
out.println("<form action=\"#\" method=\"post\">");
out.println("名称:<input type='text' name='username' value='凤姐'> <br/>");
out.println("密码:<input type='password' name='userpwd'> <br/>");
out.println("<input type='submit' value='提交' />");
out.println(" </form>");
}
///其它代码略
}
1.3 Cookie和Session
- Cookie示例
//1.创建cookie,并将cookie信息通知浏览器【CookieServlet.java】
Cookie cookie = new Cookie("test","itcast");//创建cookie
response.addCookie(cookie); //将cookie信息通知浏览器
//2. 获得浏览器保存的cookie信息【ReadCookieServlet.java】
Cookie[] cookies = request.getCookies();
if(cookies != null){//★没有这句在关闭浏览器再打开时将报空指针异常
for(Cookie c :cookies){
System.out.println(c.getName() + ":" + c.getValue());
}
}
//3.设置cookie的有效时间,使会话级cookie变成持久化cookie
Cookie cookie = new Cookie("gf","fengjie");// * 创建cookie
cookie.setMaxAge(60 * 60 * 24); // * 设置有效时间
response.addCookie(cookie); // * 通知浏览器
//3. 修改cookie的路径, /cookie/addCookieServlet2
//将当前servlet设置的cookie ,只能在cookie目录下的所有servlet以及之后的servlet中可以获得
//想在 /getCookieServlet 中访问?
Cookie cookie = new Cookie("add222","22222222222");// * 创建cookie
cookie.setMaxAge(60*60); // * 设置有效时间
cookie.setPath("/day07/");// * 修改路径
response.addCookie(cookie); // * 通知浏览器
//4. 在cookie中存放中文
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie c : cookies){
System.out.println(c.getName() + ":" + c.getValue());
//获得cn的值,然后解码
if("cn".equals(c.getName())){
String value = URLDecoder.decode(c.getValue(), "UTF-8");
System.out.println(value);
}
}
}
String data = "中文";
String returnData = URLEncoder.encode(data, "UTF-8");//对传输的中文字符进行编码
Cookie cookie = new Cookie("cn",returnData); //创建cookie
response.addCookie(cookie);//发送数据
-}
//5. 设置Cookie的字符最大值
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//拼凑数据,获得4kb字符串,不能超过4kb
StringBuffer buf = new StringBuffer();
for(int i = 0 ; i < 1024 * 4 ; i ++){
buf.append("a");
}
String data = buf.toString();
Cookie cookie = new Cookie("max",data);//创建cookie
cookie.setMaxAge(60*60);//设置有效时间
response.addCookie(cookie); //通知浏览器,发送数据
}
- Session
Session对象由服务器创建,通过request.getSession()方法得到session对象
Session默认的是30分钟有效(在conf目录的web.xml文件中配置:30,注意这里单位是分钟)
示例代码
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//JSESSIONID=DFE75A1E9CCAA1591F900FA3B1AEE9F3:tomcat自动添加cookie,会话级的
//获得session
HttpSession session = request.getSession();//参数默认的是true。没有创建,有返回。
System.out.println(session.isNew());//第一次是true,然后是false
//持久化操作
Cookie cookie = new Cookie("JSESSIONID",session.getId()); //自己创建Cookie
cookie.setMaxAge(60*30);//设置cookie属性:有效时间
response.addCookie(cookie);//指定Cookie行为:通知浏览器
}
2. 其它
2.1 http请求中post和get请求的不同[1]
- 安全性:get地址栏提交,post在html header中提交
- get是从服务器获取数据,post向服务器传送数据
- 提交数据限制:get在1k内,post无限制
依据FORM标签里的method属性,为get时调用doGet(),为post时调用doPost()
2.2 SERVLET API中forward()与redirect()的区别?
- 前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;后者则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。这样,从浏览器的地址栏中可以看到跳转后的链接地址。所以,前者更加高效,在前者可以满足需要时,尽量使用forward()方法,并且,这样也有助于隐藏实际的链接。在有些情况下,比如,需要跳转到一个其它服务器上的资源,则必须使用sendRedirect()方法。
【转发】
【重定向】
2.3 getAttribute()与getParameter的区别
- HttpServletRequest类有setAttribute()方法,而没有setParameter()方法
- 它们取到的值不同。getAttribute取到的是对象(object),而getParameter取到的是String。
- 数据传递路径不同。request.getParameter方法传递的数据是从web客户端传到web服务器,代表http的请求数据,用于表单或url重定向时使用。request.getAttribute方法传递的数据只存在于web容器内部,在具有转发关系的web组件之间共享(servlet和JSP),即在request范围内存在对象。
- 在jsp中,setAttribute是把这个对象放到该页面所对应的一块内存中,当页面服务器转发到另一个页面时,应用服务器会把这块内存拷贝到另一块页面内存中。
总之:request.getAttribute()方法返回request范围内存在的对象,而request.getParameter()方法是获取http提交过来的数据。
2.4 过滤器、监听器、拦截器的区别
- Servlet
servlet流程是短的,url传来之后,就对其进行处理,之后返回或转向到某一自己指定的页面。它主要用来在业务处理之前进行控制 - 过滤器(Filter)
过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码、做一些业务逻辑判断等。其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响应(Request、Response)统一设置编码,简化操作;同时还可进行逻辑判断,如用户是否已经登陆、有没有权限访问该页面等等工作。它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁。filter流程是线性的,url传来之后,检查之后,可保持原来的流程继续向下执行,被下一个filter,servlet接收等,而servlet处理之后,不会继续向下传递。 - 监听器(Listener)
实现了javax.servlet.ServletContextListener 接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。主要作用是: 做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等。servlet/filter都是针对url之类的,而listener是针对对象的操作的,如session的创建,session.setAttribute的发生,在这样的事件发生时做一些事情。 - 拦截器(interceptor)
拦截器是在面向切面编程中应用的,不是针对URL的,而是针对action,当页面提交action时,进行过滤操作。就是在service或者一个方法前调用一个方法,或者在方法后调用一个方法。是基于JAVA的反射机制。拦截器不是在web.xml,比如struts在struts.xml中配置
2.5 Servlet、Filter、listener的执行顺序
在整个项目中(没有任何框架)它们的加载顺序是:context-param -> listener -> filter -> servlet
,其中filter的执行顺序是按照web.xml中定义的顺序进行执行的(当多个filter都匹配的时候),执行顺序如下图表示
-