Servlet——其实就是一个java程序,运行在web服务器上,用于接收和响应客户端的http请求,更多的是配合动态资源的使用,无论访问静态资源还是动态资源,都会用到Servlet,Tomcat是servlet的容器,不过Tomcat里面已经定义好了一个DefalutServlet
1、新建一个类,实现Servlet接口,不过要重写5个方法,可以继承HttpServlet,重写service方法
2、配置Servlet,告诉服务器,我们的应用有这么些个servlet
2.1在web.xml配置以下信息:
向Tomcat报告,我这里有个servlet,名字叫HelloServlet,具体路径就是包名+类名
注册servlet的映射,servlet-name:找到上面注册的具体servlet;
url-pattern:在地址栏上的path,要以/开头
get请求会进入doGet,post请求会进入doPost,还有doPut,doDelete,这个涉及一种叫Rest开发风格,有时间可以深度学习,这里暂时知道
servlet的生命周期:
实例化:当有第一次对应的servlet请求到达时就会实例化,只会创建一次,就是该类的构造函数随着容器启动就创建该servlet对象,可以在Web.xml中配置
初始化:实例化后马上初始化,自动调用init的方法,也是只是运行一次,可以将只加载一次的工作放在init方法里面,例如是配置连接池,init有一个带参数的重载方法,如果调用了带参的方法,系统会默认调用带参的方法,不会调用无参的方法,如果带参函数里面有调用super,则会先调用无参的init的方法
就绪:就绪状态,能够接受请求,准备运行service
1.Servlet被初始化以后就处于能够响应请求的就绪状态。
2.每个对Servlet的请求由一HttpServletRequest对象代表。
3.Servlet给客户端的响应由一个HttpServletResponse对象代表。
4.当客户端有一个请求时,容器就会将请求与响应对象转给Servlet,以参数的形式传给service方法。
销毁:当服务器停止或重新启动时,自动销毁servlet对象,调用destroy方法
1. Servlet容器在销毁Servlet对象时会调用destroy方法来释放资源。
2.通常情况下Servlet容器停止或者重新启动都会引起销毁Servlet对象的动作:
2.1. 该项目从tomcat的里面移除。
2.2. 正常关闭tomcat就会执行 shutdown.bat
ServletConfig——可以获取servlet在配置的一些信息,有以下的方法
getServletName()——获取到的是配置servlet里面servlet-name的文本
getInitParameter("address")——可以获取具体的初始化参数,入参为
getInitParameterNames()——获取所有的param-name,返回的是Enumeration
getServletContext()——返回一个ServletContext对象,该对象包含关于servlet运行环境的信息
作用:
1. 未来我们自己开发的一些应用,使用到了一些技术,或者一些代码,我们不会。 但是有人写出来了。它的代码放置在了自己的servlet类里面。
2. 刚好这个servlet 里面需要一个数字或者叫做变量值。 但是这个值不能是固定了。 所以要求使用到这个servlet的公司,在注册servlet的时候,必须要在web.xml里面,声明init-params
HttpServletRequest——请求对象,封装了客户端提交过来的一切数据
getParameter("name")——获取请求体,简单来说可以获取form表单里面的input输入框对应name值的数据
getHeaderNames()——获取一个枚举集合的请求Enumeration
getHeader(String name)——获取对应的请求头数据
getHeader("User-Agent")——获取客户端类型:火狐:Firefox,
HttpServieResponse——响应对象
setStatus()——设置状态码,302重新定位状态码
setHeader(“Location”,"xxx.html")——设置响应头,Location定位跳转的位置
以上两个方法相当于重定向,不过这种是早期的写法
字符串乱码问题:
接收数据:
如果get请求:username = new String(username.getBytes("ISO-8859-1") , "UTF-8");也可在Tomcat里面设置以下内容:
如果是post请求:request.setCharacterEncoding("UTF-8");不过要在获取数据前
发送数据:response.setCharacterEncoding("UTF-8");
setHeader("Content-Type", "text/html;charset=UTF-8");——设置这份数据使用的码表
getOutputStream().write("中文".getBytes("UTF-8"));——使用字节流的输出的时候设置格式
setContentType("text/html;charset=UTF-8");——不管是字节流还是字符流,直接使用一行代码就可以了。
路径匹配:以 / 开始,如果以 * 开头代表任何请求都进入该方法
转发与重定向:
请求次数、地址栏是否改变、跨域、生成资源问题(是否可以访问WEB-INF下的内容)
转发的方法:
request.getRequestDispatcher("/这里写网页的路径,如:/WEB-INF/mypage/loginsuccess.jsp").forward(request,response);
重定向的方法:
response.sendRedirect("跳转的位置");如果需要跳转到WEB-INF文件外面的网页,直接写网页名即可,如果带了斜杠,则需要加上项目名才可以
转发和重定向不会结束方法,如果想调用了转发和重定向后结束方法,可以补一个return
转发:
1.地址栏不会改变
2.可以直接访问WEB-INF里面的资源
3.转发中的路径项目根目录:http://localhost:8080/webTest2/
4.只发一次请求
5.因为是在项目根目录,所以不能跨域
6.因为只发一次请求,所以速度回比较快
7.共享域 请求对象都是同一个request,所以共用同一个request的作用域
8.行为者 行为者是请求对象requset
重定向:
1.地址栏会改变
2.不可以直接访问WEB-INF里面的资源
3.重定向中的斜杠代表服务器根目录:http://localhost:8080/
4.会发两次请求
5.因为是在项目根目录,所以能跨域,直接访问其他页面
6.因为会发两次请求,所以速度回比较慢,客户端发送了第一次请求,服务器会返回具体的路径给客户端,然后客户端再重新发送一次请求访问具体的路径
7.共享域 请求对象是不同的request,所以不能共用同一个request的作用域
8.行为者,行为者是响应response,所以会丢失之前的请求数据和对象
重定向到转发:
先重定向发送一个请求,匹配到web.xml,web.xml再匹配到一个java类,java里面有转发的方法,转发到WEB-INF里面的资源,实现将所有的页面放到WEB-INF里面受到保护
页面请求的资源:
请求的资源包括图片,jq包等,因为页面请求的资源也相当于是一次重定向,而重定向是以服务器的根目录,相当于是WebContent开始,所以不需要加斜杠,直接写资源所在的位置,例如:jq放在WebContent里面的一个js文件夹里面,直接写js/jquery-1.11.3.js既可以
ServletContext——上下文,每个web工程都只有一个ServletContext对象,在哪里获取到的ServletContext对象都是同一个
全局参数
ServletContext的获取:
1.GenericeServlet(HttpServlet)提供的 getServletContext()
2.ServletConfig提供的 getServletContext()
3.HttpSession提供的 getServletContext()
4.FilterConfig提供的 getServletContext()
5.HttpServletRequest
以上的方法都能获取到上下文的对象、
作用:
1.在Web范围内获取共享的资源:
setAttribute("名字",对象),设置数据在上下文
getAttribute("名字")获取对应的数据
getInitParamater("全局参数的名字");获取web.xml全局参数
2.访问Web应用的静态资源:
getRealPath(String path);
就是访问该项目WebContent里面的资源,path就是路径,如果写空字符,会得到项目在tomcat里面的根目录
getResourceAsStram(String path);直接根据给定的文件的相对路径获取一个流
这里的相对路径:工程在tomcat里面的根目录
ServletContext生命周期:
服务器启动的时候创建,会位托管的每一个web应用程序,创建一个ServletContext对象
从服务器移除托管,或者关闭服务器的时候销毁
ServletContext作用范围:只要在该项目里面,都可以取,
下载:
1、直接以超链接的方式下载,不写任何代码,也能够下载东西下来
让tomcat的默认servlet去提供下载:
aa.jpg
bb.txt
cc.rar
原因是tomcat里面有一个默认的Servlet -- DefaultServlet 。这个DefaultServlet 专门用于处理放在tomcat服务器上的静态资源。
2、手动下载:
//前端:
手动编码提供下载。:
aa.jpg
bb.txt
cc.rar
后端Servlet对应的代码:
//1. 获取要下载的文件名字 aa.jpg --- inputStream String fileName = request.getParameter("filename"); //如果前端的编码格式与后端的编码格式不一致,可以使用下面的代码解决乱码问题
filename = new String(fileName.getBytes("前端编码格式"),"后端编码格式")
//2. 获取这个文件在tomcat里面的绝对路径地址 String path = getServletContext().getRealPath("download/"+fileName);
//让浏览器收到这份资源的时候, 以下载的方式提醒用户,而不是直接展示。 response.setHeader("Content-Disposition", "attachment; filename="+fileName); //3. 转化成输入流 InputStream is = new FileInputStream(path); OutputStream os = response.getOutputStream(); int len = 0 ; byte[]buffer = new byte[1024]; while( (len = is.read(buffer)) != -1){ os.write(buffer, 0, len); } os.close(); is.close();