servlet:运行在服务端的Java小程序,是sun公司提供一套规范(接口),用来处理客户端请求、响应给浏览器的动态资源
本质上是java代码,通过api动态向客户输出内容
包含三个技术:servlet技术 filter技术 listener技术
实现servlet接口的方式
1、创建实现类实现servlet接口
2、重写方法---重点是service方法(需要重写的方法太多)
3、在xml中进行servlet配置
1、继承httpservlet类
2、重写doget和dopost方法
3、在xml中进行servlet配置
方法
init()方法:servlet对象创建的时候执行
service()方法:包含请求和回应对象,每次请求都会执行,在httpservlet中分为doget()和dopost()方法
destroy()方法:servlet销毁的时候执行
servlet的生命周期:创建-----默认第一次访问servlet时创建该对象,但是在servlet配置时,加上<load-on-startup>,在服务器启动时创建;销毁-----服务器关闭
servlet中的元素url-pattern的配置方式
完全匹配:正常写法;目录匹配:最后目录用*代替;扩展名匹配:扩展名前面用*代替;缺省匹配:只有一个/,所有地址访问都不行时,缺省servlet负责接收
servletcontext:web应用的环境(上下文)对象,只有一个
生命周期:该web应用被加载(服务器启动)时创建,该web应用被卸载(服务器关闭)时销毁
构造方法:getservletcontext()方法,直接使用此方法
使用方式
1、获得全局配置的初始化参数(首先用context-param标签配置全局参数)
//获取ServletContext对象 ServletContext sc = getServletContext(); //获取全局的初始化参数 String init = sc.getInitParameter("driver"); System.out.println(init);
2、获得web应用中任意资源的绝对路径(写一个相对于本web应用的路径,得到绝对路径,这个相对路径是在磁盘中保存的路径,不是eclipse中的路径显示)
//给一个资源的相对路径,获取对应的绝对路径 //a.txt在src下 String patha = sc.getRealPath("WEB-INF/classes/a.txt"); System.out.println(patha); //b.txt在WebContent下的WEB-INF下 String pathb = sc.getRealPath("WEB-INF/b.txt"); System.out.println(pathb); //c.txt在WebContent下 String pathc = sc.getRealPath("c.txt"); System.out.println(pathc); //建在本工程下的没复制到服务器,也获取不到
3、servletcontext是一个域对象(可以存储东西,整个web应用中的资源都可以去里面存取东西)
public class Servlet01 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext context = getServletContext(); context.setAttribute("name", "张三"); }
public class Servlet02 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext context = getServletContext(); String name = (String)context.getAttribute("name"); System.out.println(name); }
httpservletresponse类
定义:doget()方法和dopost()方法中的参数类型,是servletresponse(service方法中的参数类型)的子接口,功能更强大
响应分为响应行 响应头 响应体 ,通过此类可以分别设置
设置响应行:
setstatus()设置状态码
设置响应头:
setheader(String name,String value),一般都是传两个字符串类型的参数
重定向(两次请求,地址会变化)
//设置状态码 //response.setStatus(302); //设置响应头Location //response.setHeader("Location", "/WEB03/Servlet03"); //开发中专门用于重定向的方法 response.sendRedirect("/WEB03/Servlet03");
定时刷新(可以头设置,也可以jsp里设置)
response.setHeader("refresh", "5;url=http://www.baidu.com");
response.getWriter().write("hello dandan...");
var time = 5; window.onload = function(){ var second = document.getElementById("second"); timer = setInterval(function(){ second.innerHTML = time; time--; if(time==0){ clearInterval(timer); location.href="http://www.baidu.com"; } }, 1000); }
恭喜你,注册成功,<span style ="color:red" id ="second">5</span>秒后跳转, 如不跳转,点击<a href ="http://www.baidu.com">这里</a>
中文乱码问题
//设置缓冲区的编码 // response.setCharacterEncoding("UTF-8"); // //告知客户端用utf-8解码 // response.setHeader("Content-Type", "text/html;charset=utf-8"); response.setContentType("text/html;charset=utf-8"); response.getWriter().write("中国");
字节流的获取
getoutputstream():获得字节流,通过此流向response缓冲区写入字节,然后由tomcat把内容组成http响应返回给浏览器
下载图片,视频(直接在浏览器中打开)
//获得字节输出流 ServletOutputStream out = response.getOutputStream(); //确定数据源 String realpath = getServletContext().getRealPath("dameinv.jpg"); FileInputStream fis = new FileInputStream(realpath); byte[] bytes = new byte[1024]; int len =0; while((len=fis.read(bytes))!=-1){ out.write(bytes, 0, len); } fis.close(); }
正确的下载
// 获得下载的文件名 String filename = request.getParameter("filename"); // 解决中文乱码问题 filename = new String(filename.getBytes("ISO8859-1"), "UTF-8"); // 获取请求头 User-Agent String agent = request.getHeader("User-Agent"); String filenameEncoding = ""; // 根据不同的浏览器,进行编码(模板复制,不需要记忆) if (agent.contains("MSIE")) { // IE浏览器 filenameEncoding = URLEncoder.encode(filename, "utf-8"); filenameEncoding = filenameEncoding.replace("+", " "); } else if (agent.contains("Firefox")) { // 火狐浏览器 BASE64Encoder base64Encoder = new BASE64Encoder(); filenameEncoding = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?="; } else { // 其它浏览器 filenameEncoding = URLEncoder.encode(filename, "utf-8"); } // 要下载的文件类型--客户端通过文件的mime类型区分文件的类型 response.setContentType(this.getServletContext().getMimeType(filename)); // 告诉客户端该文件不能直接解析,而是以附件的形式打开 response.setHeader("Content-Disposition", "attachment;filename=" + filenameEncoding); // 获得文件的绝对路径 String path = this.getServletContext().getRealPath("download/" + filename); // 创建输入流 FileInputStream fis = new FileInputStream(path); ServletOutputStream out = response.getOutputStream(); int len = 0; byte[] bytes = new byte[1024]; while ((len = fis.read(bytes)) != -1) { out.write(bytes, 0, len); } fis.close();
setcontenttype(getservletcontext().getmime(filename))
setheader(content-dispositon,attachment;filename=)
response获得的流不需要手动关闭,web容器(tomcat容器)会帮助我们关闭,只需关闭我们自己new的流
getWriter和getOutputStream不能同时调用
重定向语句一般作为终结代码
httpservletrequest类:response中是set,而在request中是get
获得请求行中的数据
获得请求方式
//获得请求方式 String method = request.getMethod(); System.out.println(method);
获得请求资源地址
//获得相对路径 String uri = request.getRequestURI(); //获得绝对路径 StringBuffer url = request.getRequestURL(); System.out.println(uri); System.out.println(url); //获得项目名称 String path = request.getContextPath(); System.out.println(path); //get提交方式 url后面的参数 String query = request.getQueryString(); System.out.println(query); //获取访问者的ip地址 String ip = request.getRemoteAddr(); System.out.println(ip);
获得请求行头的内容
获得某个请求头
String header = request.getHeader("User-Agent");
System.out.println(header);
获得所有的请求头:返回一个enumeration枚举对象
Enumeration<String> en = request.getHeaderNames(); while(en.hasMoreElements()){ String headName = en.nextElement(); String headValue = request.getHeader(headName); System.out.println(headName+":"+headValue); }
referer:监测盗链
String referer = request.getHeader("referer"); if(referer!=null&referer.startsWith("http://localhost:")){ response.setContentType("text/html;charset=utf-8"); response.getWriter().write("擘画新时代"); }else{ response.setContentType("text/html;charset=utf-8"); response.getWriter().write("盗链者,丢人"); }
获取表单中的数据
getparameter():获取单个表单数据 getparametervalues():获得多个表单数据 getparametermap():获取所有表单数据
//获取单个表单数据 String username = request.getParameter("username"); String password = request.getParameter("pwd"); System.out.println(username); System.out.println(password); //获取多个表单数据 String[] hobby = request.getParameterValues("hobby"); for(String str:hobby){ System.out.println("hobby "+str); } //获取所有表单数据 Map<String,String[]> map = request.getParameterMap(); Set<String> set = map.keySet(); for(String str:set){ String key = str; String[] value = map.get(key); System.out.println(key); for(String s:value){ System.out.println(s); } System.out.println("-----------------------"); } }
请求转发(1次请求,地址栏不会变化,对request域的使用,只能访问内部资源,转发效率高)
重定向(2次请求,地址栏变化,可以访问外部资源)
//向request中存值 request.setAttribute("name", "wangrognchen"); //请求转发 request.getRequestDispatcher("/Servlet02").forward(request, response); //response.sendRedirect("/WEB04/Servlet02");
String name =(String)request.getAttribute("name");
response.getWriter().write("hello dandan..."+name);
中文乱码
针对post和get方式有不同的解决办法
request.setCharacterEncoding(“UTF-8”)
parameter = new String(parameter.getBytes(“iso8859-1”),”UTF-8”)
post的解决方式更有效率,一般使用此方法就可,get方式太麻烦