JavaWeb--Servlet
JavaWeb--Servlet
Servlet是JavaWeb的三大组件之一,是用来处理浏览器和服务器之间的数据传输和参数获取等工作的。
Servlet程序可以通过实现Servlet类来创建新的Servlet,也可以通过继承HttpServlet程序来创建Servlet程序
Servlet的生命周期
实现Servlet类实现,在实现Servlet类创建Serlvet后,要实现它的三个方法,init()在服务器启动时被调用生成Servlet对象,service()是在servlet被访问时会被调用,destory()是Servlet被销毁或服务器关闭时会被调用,这也是Servlet的生命周期
SerlvetConfig可以用来获取servlet的init-param参数,这个参数是在servlet的配置文件内部设置的
init-param参数是key-value形式的,name对应value值
<servlet> <servlet-name>HelloServlet2</servlet-name> <servlet-class>ccr.servlet.HelloServlet2</servlet-class> <init-param> <param-name>username</param-name> <param-value>Mr_qing</param-value> </init-param> <init-param> <param-name>url</param-name> <param-value>http://localhost:mysql:3306/test</param-value> </init-param> </servlet>
public class HelloServlet2 implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException { System.out.println("初始化"); // 使用servletConfig对象的方法时直接对象名调用就可以使用 // servlet程序是在第一次访问时创建,servletConfig对象是在每创建一个servlet时都会生成。 // 在继承了Httpservlet类的类中也能使用servletConfig方法,但是如果想在那个类中使用init()方法就要使用super方法重新调用 System.out.println("servletconfig对象获取servelt-name值:"+ servletConfig.getServletName()); System.out.println("servletconfig对象获取servletContext对象的值:"+ servletConfig.getServletContext()); System.out.println("servletconfig对象获取init-param参数值:"+ servletConfig.getInitParameter("username")); System.out.println("servletconfig对象获取init-param参数值:"+ servletConfig.getInitParameter("url")); } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("hello"); } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
ServletContext的使用
servletContext可以获取web.xml文件中的init-param参数,这个参数是name=value形式的,通过getInitParameter( name )方法获取value值
<context-param> <param-name>username</param-name> <param-value>Ms_jin</param-value> </context-param> <context-param> <param-name>root</param-name> <param-value>fan</param-value> </context-param>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 在使用ServletContext对象时通过ServletConfig对象调用它 javax.servlet.ServletContext context = getServletConfig().getServletContext(); System.out.println("context.getInitParameter(\"username\") = " + context.getInitParameter("username")); System.out.println("context.getInitParameter(\"root\") = " + context.getInitParameter("root")); //获取工程在磁盘上的绝对路径,目录对应web工程下的目录,可以添加如:"/css/..."形式的修改 System.out.println("context.getRealPath(\"/\") = " + context.getRealPath("/")); //获取工程路径 System.out.println("context.getContextPath() = " + context.getContextPath()); }
通过ServletContext调用getServlet方法,ServletContext中可以存放数据,在本工程的其他Servlet中也可以查找到这个保存的数据
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //通过直接调用getServletContext也可以直接使用这个方法,因为在GenericServlet中是这么写的this.getServletConfig().getServletContext(); ServletContext context = getServletContext(); System.out.println("存放之前从servletcontext对象里获取user的数据:"+context.getAttribute("user")); context.setAttribute("user","Ms_ber"); // 在这个web工程其他的servlet里也可以获取到这个context存储的数据 System.out.println("存放后从servletcontext对象中获取user的数据:"+ context.getAttribute("user")); // 一个web工程只会有一个ServletContext对象 System.out.println(context); }
一个Web工程只会有一个ServletContext对象
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 只要context对象创建后在整个web工程里都能获取到里面存储的数据,当创建对象后没有存入数据就会读取不到数据 // 当对项目进行重新部署或重启服务器就一样会销毁context对象 ServletContext context = getServletContext(); System.out.println("在一个web工程里只会有一个ServletContext对象:"+ context); System.out.println("在创建完成web工程后,创建完ServletContext对象后,获取user的值:"+ context.getAttribute("user")); }
继承HttpServlet实现,继承后实现doGet或doPost方法进行工作处理请求
public class HelloServlet extends HttpServlet { @Override // 在IDEA中会自动重新调用config对象,如果没有的话就要自己手写super方法重新调用config对象,不然就会报出空指针异常错误 public void init(ServletConfig config) throws ServletException { super.init(config); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("get请求"); ServletConfig servletConfig = getServletConfig(); System.out.println("servletConfig.getServletName() = " + servletConfig.getServletName()); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("post请求"); } }
Get和Post请求
Get请求可以在请求地址中看见参数的内容,有长度限制
Post请求不能在请求地址栏中看见请求参数的内容,长度比get请求长
Get请求在Servlet中由doGet方法处理请求参数,Post请求在Servlet中由doPost方法处理请求参数
使用request.getParameter( name )获取页面提交的参数,name是页面中组件的name值
public class HelloServlet extends HttpServlet { @Override // 在IDEA中会自动重新调用config对象,如果没有的话就要自己手写super方法重新调用config对象,不然就会报出空指针异常错误 public void init(ServletConfig config) throws ServletException { super.init(config); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("get请求"); ServletConfig servletConfig = getServletConfig(); System.out.println("servletConfig.getServletName() = " + servletConfig.getServletName()); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("post请求"); } }
request的用途
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("获取请求的资源路径: " + req.getRequestURI()); System.out.println("获取请求统一资源路径(绝对路径): " + req.getRequestURL()); // 使用localhost请求获取到就是0:0:0:0:0:0:0:1 // 使用127.0.1.1进行请求就会获取到127.0.0.1 // 使用真实ip访问请求时就会得到真实ip System.out.println("获取请求客户端ip地址: " + req.getRemoteHost()); System.out.println("获取请求头: "+ req.getHeader("User-Agent")); System.out.println("获取请求方式 method: " + req.getMethod()); }
response的使用
resp是服务器向客户端相应信息,通过流来进行信息传播,使用getWriter()和getOutputStream()进行获取流对象,两个API只能选择一个使用
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 解决中文乱码问题使用setCharacterEncoding设置服务器的字符集,使用setHeader规定浏览器的字符集 // resp.setCharacterEncoding("UTF-8"); // Content-Type是请求头 // resp.setHeader("Content-Type","text/html;charset=UTF-8"); //使用setContentType能够直接规定服务器和客户端的字符集格式,但是这个方法要在获取流对象之前调用,否则还是会乱码 resp.setContentType("text/html;charset=UTF-8"); //resp是服务器向客户端相应信息,通过流来进行信息传播,使用getWriter()和getOutputStream()进行获取流对象,两个API只能选择一个使用 // getWriter()比较常用,getWriter()是字符流,getOutputStream()是字节流 PrintWriter writer = resp.getWriter(); writer.println("response响应成功!!!!");
请求转发和请求重定向
请求转发
是通过getRequestDispatcher()方法实现的页面跳转,参数要以 / 打头,执行完getRequestDispatcher方法后,要加forward将Servlet的参数传到转发资源中
请求转发能访问WEB-INF目录下的文件资源,只有一个请求
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username"); System.out.println("username1 = " + username); // 作为获取到参数并通过验证的凭据,通过的标记 req.setAttribute("key","Servlet1"); // getRequestDispatcher方法使用是必须用“/”打头,里面写的是要跳转的资源路径 /** * 请求转发是能够访问WEB-INF目录下的html文件 * 不能访问工程外部的html文件 * 浏览器地址并不会跳转,一直都是servlet1 * 虽然访问了两个资源,但是是一个请求 */ RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2"); // 请求指向servlet2 requestDispatcher.forward(req,resp); }
请求重定向
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("这个responseServlet1已经不行了,将要跳转到responseServlet2上!!"); req.setAttribute("username","Ms_xu"); //使用setHeader方法告诉浏览器下一个跳转地址,先使用setStatus方法高所浏览器302状态码,表示重定向 // resp对象设置有关客户端的内容 // resp.setStatus(302); // resp.setHeader("Location","Http://localhost:8080/servlet/responseServlet2"); /** * 请求重定向的特点 * 会在过程中产生两个请求 * 不能共享request域中的资源,因为在创建一个servlet就会产生一个request,请求重定向会产生两个servlet.req并不相同,就不会共享数据 * 可以访问工程外部的资源 * 不能访问WEB-INF目录下的文件,因为请求重定向的过程是先访问一个网址 * ,服务器告知你请求重定向和请求重定向地址.之后再次重新访问服务器,过程不在服务器内部 * */ // 直接使用也可以实现请求重定向 resp.sendRedirect("http://localhost:8080/servlet/responseServlet2"); }