1.ServletConfig对象
ServletConfig对象主要是用来获取Servlet的一些配置信息,例如Servlet的名称,Servlet的初始化参数等。
这里提到的Servlet的配置信息都是在web.xml文件的<Servlet>标签中配置的。
<servlet>
<servlet-name>ServletDemo4</servlet-name>
<servlet-class>com.itheima.servlet.demo1.ServletDemo4</servlet-class>
<!--配置servlet的初始化参数-->
<init-param>
<param-name>username</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>abc</param-value>
</init-param>
</servlet>
在Servlet的实现类中通过this.getServletConfig方法获取ServletConfig对象。
public class ServletDemo3 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取ServletConfig对象
ServletConfig config = this.getServletConfig();
//通过参数名查看对应的参数值(key:value)
String name = config.getInitParameter("name");
String password = config.getInitParameter("password");
System.out.println(name+"\t"+password);
//查看所有的参数名
Enumeration<String> names = config.getInitParameterNames();
//遍历枚举,通过参数名获取对应的值
while(names.hasMoreElements()){
String name1 = names.nextElement();
String value = config.getInitParameter(name1);
System.out.println(name1+"\t"+value);
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
2.ServletContext对象(重点)
三个功能:获取web项目信息,读取web项目下的文件,最为域对象存储数据
2.1获取web项目信息
1、ServletContext对象又称为Servlet的上下文对象,保存了整个web项目的信息,通过这个上下文对象可以保存或者获取web项目的信息。
一个web项目只有一个ServletContext对象,服务器会为每个项目创建一个ServletContext对象
2、可以获取文件的MIME类型、全局参数、web项目工程名。
①获取文件的MIME类型(文件下载时使用)
//获取ServletContext对象
ServletContext context = this.getServletContext();
String mimeType = context.getMimeType("aa.txt");
System.out.println(mimeType);
②获取web项目请求路径工程名
String getContextPath();
③获取全局初始化参数
全局初始化参数的配置是在web.xml文件中配置在<context-param>标签内(servlet的初始化参数是在<Servlet>标签里的<init-param>标签内,只针对单个的servlet文件)
<context-param>
<param-name>username</param-name>
<param-value>root</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>123</param-value>
</context-param>
ServletContext context = this.getServletContext();
//根据参数名获取全局初始化参数
String name = context.getInitParameter("username");
String password = context.getInitParameter("password");
System.out.println(name+"\t"+password);
//获取全部全局初始化参数
Enumeration<String> names = context.getInitParameterNames();
while(names.hasMoreElements()){
String name1 = names.nextElement();
String value = context.getInitParameter(name1);
System.out.println(name1+"\t"+value);
}
2.2读取web下的文件
在java中我们读取文件用的是IO流,但是对于web项目来说由于web项目需要发布到tomcat中才能访问,所以获取到web项目中的文件如果使用传统的IO流就会出现问题(原因是IO流中的路径使用的是相对路径是相对于JRE环境的。)
① InputStream getResourceAsStream(String path):根据path路径,以流的形式返回文件。
public void test1() throws IOException {
//调用getResourceAsStream方法返回输入流
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/a.txt");//这里的路径从web项目开始
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String readLine = br.readLine();
System.out.println(readLine);
is.close();
②String getRealPath(String Path):根据path相对路径返回文件在硬盘中的真实路径。
public void test2() throws IOException{
String path = this.getServletContext().getRealPath("/WEB-INF/classes/a.txt");//这里的路径是从web项目开始
BufferedReader br = new BufferedReader(new FileReader(path));
String readLine = br.readLine();
System.out.println(readLine);
}
扩充:用Class类读取web工程中的文件
③InputStream getResourceAsStream(String name)
public void test3() throws IOException{
InputStream is = this.getClass().getResourceAsStream("/a.txt");//这里的/a.txt相当于/WEB-INF/classes下这个方法是直接从classes文件夹开始查询
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String readLine = br.readLine();
System.out.println(readLine);
is.close();
}
2.3作为域对象存储数据
1、如果把一个数据存到某个对象身上,在多个地方又能通过这个对象取出来,那么这个对象存的值就有了一定的作用范围,这个对象也就称为域对象。ServletContext作为一个域对象,它的作用范围是整个web项目,因为服务器会为每个web项目创建一个ServletContext对象,只要这个web项目在服务器上没被移除或者服务器没有关闭,那么ServletContext域对象就存在,它身上的数据也就在。
2、存值、取值和移除值的方法
①void setAttribute(String name,Object obj):存值
②Object getAttribute(String name):取值
③void removeAttribute(String name):移除值
域的范围:
Ⅰ:web服务器启动时ServletContext对象就会被创建
II:web服务器停止或者项目从服务器卸载时ServletContext就会销毁
3.Respones(响应)对象
3.1什么是Respones对象?
当用户通过浏览器访问一个服务器的时候,服务器会对浏览器做出一个回答(响应),这个响应里面包含了很多信息,这些信息会封装到Respones对象身上,这个对象也成为了响应对象。
3.2Respones对象的API详解
常用的方法:
①setHeader()方法是设置一个key对应一个value的响应头信息,设置的头信息会替换原来的头信息;addHeader()方法是设置一个key对应多个value的响应头信息,添加的头信息会追加到原来的头信息后面。
void setStatus(int src)//设置响应码
void setHeader(String name,String value)//设置响应头信息
void addHeader(String name,String value)//添加响应头信息
ServletOutputStream getOutputStream()//获取字节输出流向页面输出内容
printWriter getWriter()//获取字符输出流向页面输出内容
void sendRedirect(String location)//设置页面重定向的方法
void setContentType(String Type)//设置浏览器打开页面时候采用的字符集
3.3页面重定向的方式
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//方式一:setStatus(302)+setHeader("Location", "/day10_servlet/index.html")
//设置重定向的响应码,告诉浏览器要重定向
response.setStatus(302);
//设置重定向路径,告诉浏览器要重定向到哪个界面
response.setHeader("Location", "/day10_servlet/index.html");
//方式二:
response.sendRedirect("/day10_servlet/index.html");
}
3.4解决页面输出中文乱码和页面跳转
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决浏览器显示中文乱码
response.setContentType("text/html;charset=utf-8");
//print()方法的底层执行的就是write()方法,页面会把输出的字符串当成html代码解析
response.getWriter().write("<font color = 'red' size = 6>5s后跳转到成功页面</font>");
//定时属性页面
response.addHeader("Refresh", "5;url=/day10_servlet");
}
3.5响应的中文乱码处理
原因:字符流是有缓冲区的, response设计默认的缓冲区编码是ISO-8859-1,这个字符集不支持中文的。所以一定会出现乱码问题,一旦出现乱码问题,我们只需要设置response字符流缓冲区的编码和设置浏览器默认打开时候采用的字符集一致即可。
①使用字节输出流输出中文
ServletOutputStream outputStream = response.getOutputStream();
outputStream.write("你好".getBytes());
当使用上述的代码向浏览器输出中文的时候,是否出现乱码与中文转化成字节数组时采用的字符集和浏览器的打开方式(浏览器采用的默认字符集)有关,如果两个采用的字符集相同,就不会出现乱码。
所以我们需要将代码改写成如下
ServletOutputStream outputStream = response.getOutputStream();
//设置浏览器打开的字符集
response.setHeader("Content-Type", "text/html;charset=utf-8");
//设置中文转成字节数组时候的字符集
outputStream.write("你好".getBytes("utf-8"));
②使用字符输出流输出中文
response.getWriter().write("你好");
当使用上述代码向浏览器输出中文的时候,一定会出现乱码,因为字符输出流是有缓冲区的,而缓冲区默认的编码是ISO-8859-1,这个字符集是完全不支持中文的。我们需要设置字符流缓冲区的编码和浏览器打开时的字符集一致即可。
所以我们需要将代码改写成如下
//设置浏览器打开的字符集
response.setHeader("Content-Type", "text/html;charset=utf-8");
//设置字符流缓冲区的编码
response.setCharacterEncoding("utf-8");
response.getWriter().write("你好");
设置浏览器默认打开字符集和设置字符流缓冲区的编码可以被一个方法代替
response.setContentType("text/html;charset=utf-8");//
总结:在字节流输出中文的时候也需要设置浏览器的默认字符集,所以也可以被该方法替代,所以最后我们将代码简写成
response.setContentType("text/html;charset=utf-8");
//向页面输出中文字符串
response.getWriter().print("你好")
//向页面输出二进制文件
response.getOutputStream().write(byte[]);
4.Request(请求)对象
4.1获取请求参数
String getParameter(String name)//根据name获取一个value
String[] getParameterValues(String name)//根据name获取多个Value值
Map getParameterMap()//获取任意请求参数,将参数的name和对应的value值存入到map集合中 Map<String,String[]>
4.2获取客户机的信息
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("请求方式"+request.getMethod());
System.out.println("客户机IP地址"+request.getRemoteAddr());
System.out.println("请求参数的字符串"+request.getQueryString());
System.out.println("请求路径的URL"+request.getRequestURL());
System.out.println("请求路径的URI"+request.getRequestURI());
System.out.println("获取客户机浏览器类型"+request.getHeader("User-Agent"));
}
4.3接收表单的请求参数(重点)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//接收用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
//获取性别和籍贯
String sex = request.getParameter("sex");
String city = request.getParameter("city");
//获取爱好
String[] values = request.getParameterValues("hobby");
System.out.println(username);
System.out.println(password);
System.out.println(sex);
System.out.println(city);
System.out.println(Arrays.toString(values));
//使用map集合获取请求表单参数
Map<String,String[]> map = request.getParameterMap();
for (String key : map.keySet()) {
String[] values1 = request.getParameterValues(key);
System.out.println(key+"\t"+Arrays.toString(values1));
}
}
4.4接收表单请求参数时的中文乱码问题
①post提交请求乱码
原因:post请求提交的参数是在请求体中传递的,数据会存放在request字符缓冲区里面,而缓冲区默认编码是iso-8859-1编码,所以我们只需要设置缓冲区编码为utf-8即可。
//设置request缓冲区字符集
request.setCharacterEncoding("utf-8");//设置一定要放在获取参数之前
//获取用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
②get提交请求乱码
get请求提交的参数是在地址栏中传递的额,浏览器会对数据进行一次编码,数据发送到服务器之后,服务器默认使用iso-8859-1进行解码,这样乱码就产生了。要知道我们程序是不应该改浏览器和服务器的字符集,所以,我们只能倒着编码和解码一次就可获得原来的字符。
String name = request.getParameter("name");
//先根据iso-8859-1编码获得中文的字节数组,再按照utf-8编码转成字符串
name = new String(name.getBytes("iso-8859-1"),"utf-8");
4.2作为域对象
void setAttribute(String name,Object obj)//存值
Object getAttribute (String name)//取值
void removeAttrivute(String name)//移除值