理解Servlet及其对象
一.ServeltConfig对象
在Servlet的配置文件中,可以使用一个或多个<init-param>标签为Servlet配置一些初始化参数。而不当Servlet配置了初始化参数后,web容器在创建Servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在Servlet的init方法时,将ServleConfig对象传递给Servlet。
在开发程序中,可以通过ServletConfig对象得到当前Servlet初始化的参数信息。
具体方法如下:
在web应用下配置web.xml文件
<servlet> <servlet-name>Demo1</servlet-name> <servlet-class>cn.itcast.web.servlet.Demo1</servlet-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>driver</param-name> <param-value>com.mysql.jdbc.Driver</param-value> </init-param> <init-param> <param-name>url</param-name> <param-value>jdbc:mysql://127.0.0.1:3306/test</param-value> </init-param> <init-param> <param-name>username</param-name> <param-value>root</param-value> </init-param> <init-param> <param-name>password</param-name> <param-value>root</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
实现方法:
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { ServletConfig config = this.getServletConfig(); String driver = config.getInitParameter("driver"); String url = config.getInitParameter("url"); String username = config.getInitParameter("username"); String password = config.getInitParameter("password"); if(driver!=null && url!=null && username!=null && password!=null){ System.out.println("driver="+driver); System.out.println("url="+url); System.out.println("username="+username); System.out.println("password="+password); } }
ServletConfig对象的作用:
1)获取字符集编码(中文)
2)获得数据库连接的信息
3)获取配置文件,查看struts案例的web.xml文件
ServletContext 是配置Servlet环境变量的类。
当工程部署时,就创建了ServletContext对象,同一个工程中的ServletDemo类都共享同一个
二、ServletContext对象
ServletContext对象在web服务器停止或web应用重新部署时,原有的ServletContext对象被销毁。
如何获取ServletContext对象?
1)ServletContext context = this.getServletContext();
2)ServletContext context = this.getServletConfig().getServletContext();
3)ServletContest context = request.getSession().getServletContext();
获取Servlet中的配置参数,则使用到的Servlet对象为ServletConfig
获取WEB应用中的配置参数,则使用到的Servlet对象为ServletContext
在Servlet开发中,需要加载文件,则需要使用SevletContext对象。
代码如下:
Public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { //传统方法是基于tomcat/bin/目录下 //BufferedReader br = new BufferedReader(new FileReader("src/config.txt")); //System.out.println(br.readLine()); //br.close(); ServletContext context = this.getServletContext(); InputStream is = context.getResourceAsStream("/config.properties");//斜杠表示当前web应用工程下,即day06工作 Properties props = new Properties(); props.load(is); String email = props.getProperty("email"); response.getOutputStream().write(email.getBytes()); }
扩展知识1:
在Servlet开发中,除了使用ServletContext对象加载项目中需要的资源文件外(如.xml文件、.properties文件),还可以通过类加载器加载或读取文件,使用此方法,需要注意以下几个方面:
- 代码如下:
InputStream is = Demo6.class.getClassLoader().getResourceAsStream("config.properties");
“confing.properites”是类路径,路径与Class.forName("cn.itcast.web.servlet.Demo1")相似,以/分隔。
- 有具只能加载类路径下的资源;
- 文件位置只能位于类路径下,即IDE工具的src/目录下;
- 将整个文件,无论多在,加载到内存;
扩展知识2:
关于路径的问题:
- 客户端:以浏览器发送请求为基础,例如:<form action=""/>或<a href=""/>或response.sendRedirect("/day06/fail.html");都以/开头,这里/表示"webapps"目录;
- 服务端:以服务器内部转发为基本,浏览器不可见。
这里/表示"当前web应用"的目录,即day06。
Servlet开发中转发代码:
//转发到success.html页面 ServletContext context = this.getServletContext(); //取得转发对象 RequestDispatcher rd = context.getRequestDispatcher("/success.html"); //真实转发 rd.forward(request,response); 或者: RequesttDispatcher rd = this.getServletContext.getRequsetDispatcher.forward(request,response);
扩展知识3:
设置缓存问题及乱码问题:
1)浏览器默认有缓存,但缓存内容无期,对于刷新直接向服务端请求资源。
response.setDateHeader("expires",end);
2)高级缓存[304]
3)Servlet开发中,解决中文乱码问题:
使用代码: response.setContentType(“text/html”,”charset=UTF-8”);
或者:response.setHeader(“content-type”,”text/html;charset=UTF-8”);
下载中文名文件,代码如下:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext context = this.getServletContext(); String path = context.getRealPath("/爱.JPG"); File file = new File(path); response.setHeader("content-disposition","attachment;filename="+URLEncoder.encode(file.getName(),"UTF-8")); InputStream is = new FileInputStream(file); OutputStream os = response.getOutputStream(); byte[] buf = new byte[1024]; int len = 0; while((len=is.read(buf))>0){ os.write(buf, 0, len); } is.close(); os.close(); }
三、 response对象
1) response向浏览器输出信息,字符方式或字节方式输出问题
要么使用字节方式输出:
response.getOutputStream().write(“你好!”.getBytes) ;
要么使用字符方式输出:
Response.getWriter().write(“你好!”);
2) 对于response输出,内存和响应头一同输出到浏览器
即将response.setContentType(“text/html”,”charset=UTF-8”);设置完成后,会一直在整个的response对象中存在,不需要再设置。
3) 在response对象中,使用到一些流操作的时候,可以不用关闭流,这时web服务器在销毁response之前,会自动将所涉及的流关闭。
例如:PrintWriter pw = response.getWriter();
pw.write(“你好!”);
// pw.flush(); 不需要写这两句
// pw.close();
四、 request对象
1) request对象主要是获取客户端信息时使用的,例如获取客户端form表单信息、IP地址、主机名、web服务器的IP地址等信息。
如下代码:
String clientIP = request.getRemoteAddr();
String ServiceIP = request.getLocalAddr();
System.out.println(“clientIP=”+clientIP);
System.out.println(“ServiceIP=”+ServiceIP);
2) request对象可以获取浏览器请求头信息
String accept = request.getHeader(“accept-encoding”);
String host = request.getHeader(“Host”);
3) request对象最重要的方法是获取参数信息
例如:获取表单中的参数信息
<form ation=”ServletDemo” method = “post”>
用户名:<input type = “text” name=”username “/>
密码: <input type = “text” name=”password “/>
<input type = “submit” value = “提交”/>
</form>
代码如下:
String username = request.getParameter(“username”);
String password = request.getParameter(“password”);
4)request细节
1)如果在forward()之前已经向浏览器输出内容,并且关闭了流对象此时forword()代码转发到的那个页面的代码不执行
如下代码:
PrintWriter pw = response.getOutputStream();
pw.write("aaa");
pw.flush();//
pw.close();//关闭了流对象
request.getRequestDispach().forward(request,response);
2)如果在forward()之前已经向浏览器输出内容,没有关闭流对象,但是输出到缓存中,此时forward()代码转发到的那个页面代码会执行,原来输出到缓存的代码不执行,即忽略。
3)如果在forward()之后向浏览器输出内容,忽略。
4)如果在forward()之前写的响应头会保留。即只要在Servlet中设置了一处响应头,
如request.setContentType("text/html;charset=utf-8");
在request转发或者转发之后都不需要重新设置
4)使用request对象进行转发
代码如下:
request.getRequestDispatcher(“/success.html”).forward(request,response) ;
//注意:这里的”/”代表day06
5)获取请求参数
//浏览器地址栏只有一个请求参数时,则使用
String username = request.getParameter(“username”);
//浏览器地址栏中有一个请求参数但有多个不同的值时,则使用
String[] liles = request.getParameterValues(“likes”);
For(String like:lies){
System.out.println(like);
}
//浏览器地址栏中有多个请求参数不同值时,则使用
Enumeration enums = request.getParameterNames();
While(enmus.hasMoreElements()){
String key = (String) enums.nextElement();
System.out.println(key);
}
扩展知识:
实现网站中的防盗链问题
五、重定向和转发区别?
1)重定向可以在不同的web应用中导航,但转发仅限于当前web应用中导航。
2)重定向中的/表示webapps目录,即tomcat中web应用的根目录,而转发中的/表示当前的web应用,即day07。
3)重定向地址栏会变化,而转发地址栏不会变化。
4)重定向会通知浏览器,但转发是服务器内部行为,项目中,以减少HTTP请求为原则,尽可能使用转发。
5)重定向不会共享request域对象,但转发可以共享request域对象。
注意:HttpServletRequest有二层含义:
- 表示客户端向服务端的请求
- 表示request容器/对象/域对象(set/getAttribute())
常用的方法:
Request.getParameter(String str);//请求体的参数信息
Request.getParameterValues(String []);
Request.getParameterNames(Enumeration enums);
Request.getHeader();//请求头中的参数信息
Request.set/getAttribute();//从域对象中设置/获取对应的信息
六、 Request.getRequestDispach(“”).forword(request,response)
与request.getRequestDispach(“”).include(request,response)区别
使用include进入转发时,页面会包含其它的web资源(html/jsp/servlet),include代码转发到的那个页面执行完代码后,会返回到原来包含include代码页面继续执行它下面的代码。而forword()刚好相反。
注意:
Request.getMethod();//获取客户端以什么方式提交(GET/POST方式)
Request.getContextPath();//获取当前web应用名(/day07)
理解Servlet及其对象的更多相关文章
- 详细理解servlet实现的几种方式和生命周期
现在很多的开发都是用的框架,然后很多同学学习的时候又是直接接触的框架,对于底层的一些开发,完全没有任何的了解.虽然对于业务上面来说,没有什么问题.但是很多时候当你被面试问到,或者是想要了解框架底层原理 ...
- 详细理解servlet实现的三种方式和生命周期
阅读目录 开发servlet的三种方式 理解实现servlet接口的方式,理解servlet生命周期 Servlet接口有五个方法 继承GenericServlet 继承HttpServlet 现在很 ...
- JavaWeb -- 服务器传递给Servlet的对象 -- ServletConfig, ServletContext,Request, Response
1. ServletConfig 有一些东西不合适在程序中写死,应该写在web.xml中,比如 文字怎么显示, 访问数据库名 和 密码, servlet要读取的配置文件 等等.. l在Servle ...
- Servlet配置对象、上下文对象、多线程问题
一.Servlet配置对象(ServletConfig):Servlet初始化时,容器调用其init(ServletConfig)方法,传递该对象. 1.获得对象方法: (1).直接使用getServ ...
- 完全理解 Python 迭代对象、迭代器、生成器(转)
完全理解 Python 迭代对象.迭代器.生成器 本文源自RQ作者的一篇博文,原文是Iterables vs. Iterators vs. Generators » nvie.com,俺写的这篇文章是 ...
- 完全理解 Python 迭代对象、迭代器、生成器
完全理解 Python 迭代对象.迭代器.生成器 2017/05/29 · 基础知识 · 9 评论 · 可迭代对象, 生成器, 迭代器 分享到: 原文出处: liuzhijun 本文源自RQ作者 ...
- 深入理解Javascript window对象
首先看我们的源代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> ...
- JavaWeb基础—Servlet重要对象
一.ServletConfig对象 当servlet配置了初始化参数后(<init-param> <param-name> <param-value>),web容器 ...
- springmvc中将servlet api对象作为处理方法的入参使用
在springmvc中,控制器不依赖任何servlet api对象,也可以将servlet api对象作为处理方法的入参使用,非常方便,比如需要使用HttpSession对象,那么就可以直接将Http ...
随机推荐
- C++: int和string相互转换
假设在一个C++的程序中常常会用到int和string之间的互换.个人建议能够写成一个函数,下次用的时候直接调用就可以. #include <iostream> #include < ...
- Golang性能调优入门
如何利用golang自带的profile工具进行应用程序的性能调优,前一段时间我做的日志分析系统在线上遇到了一个问题,就是分任务的系统down机了,日志处理延迟了10几个小时,这个时候任务分发系统重启 ...
- 无法登陆mysql服务器
解决 .#2002 无法登录 MySQL 服务器 将config.sample.inc.php复制成config.inc.php 出现这个错误,表示没有连接到数据库.修改config.inc.php文 ...
- js数组去重,并统计最多项算法
从事了一段时间的前端开发,今天写了一个数组去重,并统计最多项的方法,目前只支持数组的项都是数字. 由于本人能力有限,希望能得到网友的指正!如有问题或者更好的实现思路,也欢迎大家和我讨论!代码如下: f ...
- C#.NET 各种连接字符串
C#.NET 各种连接字符串 近期连接数据库时,经常忘记连接字符串是如何的格式,现在此备注 此文章引用http://www.cnblogs.com/zhiqiang-imagine/archive/2 ...
- iOS 实现毛玻璃效果
话说苹果在iOS7.0之后,很多系统界面都使用了毛玻璃效果,增加了界面的美观性,比如下图的通知中心界面; 但是其iOS7.0的SDK并没有提供给开发者实现毛玻璃效果的API,所以很多人都是通过一些别人 ...
- 使用Spring JDBCTemplate简化JDBC的操作
使用Spring JDBCTemplate简化JDBC的操作 接触过JAVA WEB开发的朋友肯定都知道Hibernate框架,虽然不否定它的强大之处,但个人对它一直无感,总感觉不够灵活,太过臃肿了. ...
- Java IO5:管道流、对象流
前言 前面的文章主要讲了文件字符输入流FileWriter.文件字符输出流FileReader.文件字节输出流FileOutputStream.文件字节输入流FileInputStream,这些都是常 ...
- 极客”一词,来自于美国俚语“geek”的音译,一般理解为性格古怪的人
起源 “ 极客”一词,来自于美国俚语“ geek”的音译,一般理解为性格古怪的人.数学“极客”大多是指,并不 一定是数学专业但又对数学等技术有狂热的兴趣并投入大量时间钻研的人.又 译作“ 奇客”.以前 ...
- YII Framework学习教程-YII的Model-开发规范-路径别名-命名空间
到这里,大概的YII开发已经基本可以,但是下面要将的所有课程,学完之后可以让你更爱YII.下面的教程是讲的MVC的M,model.数据,业务,代码的集中地区.所以开始之前,学学开发规范-路径别名-命名 ...