笔记整理自狂神说JavaWeb
把实现了Servlet接口的Java程序叫做Servlet
Servlet接口sun公司提供了两个默认的实现类: HttpServlet,GenericServlet
构建一个普通的Maven项目,删掉里面的src目录,在这个项目里面建立Moudel(模块),这个空的工程就是Maven主工程
在Maven父子工程中
父项目的pom.xml中自动生成
<!--读pom文件时,要去读modules下的子pom文件--> <modules> <module>HelloServlet</module> </modules>
子类项目的pom.xml自动生成
<!--使子项目继承父项目的设置,避免导入重复依赖 eg:son extends parent--> <parent> <artifactId>javaweb-02-servlet</artifactId> <groupId>com.servlet</groupId> <version>1.0-SNAPSHOT</version> </parent>
编写一个Servlet程序
编写一个普通类,实现Servlet接口,这里我们直接继承HttpServlet(HttpServlet实现了Servlet接口
)
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter();//获取响应流 //响应流输出信息 writer.print("hello servlet"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
编写servlet映射
我们编写的java程序需要被浏览器访问,而浏览器需要访问web服务器,所以我们需要在web服务器中部署servlet,给他一个访问的具体路径。所以我们在web.xml中注册servlet和servlet-mapping
<!--注册servlet--> <servlet> <servlet-name>helloServlet</servlet-name> <servlet-class>com.thomas.HelloServlet</servlet-class> </servlet> <!--每一个servlet对应一个映射--> <servlet-mapping> <servlet-name>helloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
配置tomcat
启动项目
一个Servlet可以指定一个映射路径
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
一个Servlet可以指定多个映射路径
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello2</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello3</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello4</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello5</url-pattern> </servlet-mapping>
一个Servlet可以指定通用映射路径
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello/*</url-pattern> </servlet-mapping>
默认请求路径
<!--默认请求路径--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
指定一些后缀或者前缀等等….
<!--可以自定义后缀实现请求映射 注意点,*前面不能加项目映射的路径 --> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>*.cxd</url-pattern> </servlet-mapping>
优先级问题
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求
<!--404--> <servlet> <servlet-name>error</servlet-name> <servlet-class>com.thomas.servlet.ErrorServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>error</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
当web容器启动时,会创建一个servletContext对象,可以通过这个对象让servlet之间进行通信,代表当前的web应用
共享数据
我们在一个Servlet中通过servlerContext对象保存(set)的数据,可以在另一个servlet通过servlerContext对象get到
public class SetServletContext extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = this.getServletContext(); String name = "thomas冯"; resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); servletContext.setAttribute("username",name); } }
public class GetServletContext extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = this.getServletContext(); String username = (String) servletContext.getAttribute("username"); resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); resp.getWriter().print("username : " + username); } }
获取初始化参数
web.xml
<!--配置一些web应用初始化参数--> <context-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:3306/mybatis</param-value> </context-param>
获取
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); String url = context.getInitParameter("url"); resp.getWriter().print(url); }
请求转发
请求转发和重定向的区别
forward(转发):
是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,因为这个跳转过程实在服务器实现的,并不是在客户端实现的所以客户端并不知道这个跳转动作,所以它的地址栏还是原来的地址
redirect(重定向):
是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL
转发是服务器行为,重定向是客户端行为
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); System.out.println("进入了sd4"); RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//转发的请求路径 requestDispatcher.forward(req,resp);//调用forward实现请求转发 //合并写 context.getRequestDispatcher("/gp").forward(req,resp); }
读取资源文件
##properties文件内容 username=root12312 password=zxczxczxc
public class ServletDemo05 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/kuang/servlet/aa.properties"); Properties prop = new Properties(); prop.load(is); String user = prop.getProperty("username"); String pwd = prop.getProperty("password"); resp.getWriter().print(user+":"+pwd); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
web服务器接收了web client的请求,生成两个对象:HttpServletResponse和HttpServletRequest
使用HttpServletResponse让浏览器下载文件
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取文件路径 String filePath = "D:\\ForStrong_java\\javaweb\\javaweb-02-servlet\\ServletHttpResponse\\target\\classes\\1.jpg"; //获取文件名 String fileName = filePath.substring(filePath.lastIndexOf("\\") + 1); //获取文件输入流 BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath)); //获取向浏览器的输出流 BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(resp.getOutputStream()); //让浏览器知道我们要下载文件,需要设置头,让浏览器支持。中文文件名URLEncoder.encode编码,否则有可能乱码 resp.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName,"utf-8")); //向浏览器输出数据 byte[] buffer = new byte[1024]; int len = 0; while ((len = bufferedInputStream.read(buffer))>0){ bufferedOutputStream.write(buffer,0,len); } //关闭流 bufferedInputStream.close(); bufferedOutputStream.close(); }
response实现验证码,三秒刷新一次
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //写一张图片 BufferedImage bufferedImage = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);//需要一张画板 Graphics graphics = bufferedImage.getGraphics();//需要一只画笔 //设置背景 graphics.setColor(Color.white);//设置颜色 graphics.fillRect(0,0,80,20); //设置内容 graphics.setColor(Color.blue); graphics.setFont(new Font(null,Font.ITALIC,20)); graphics.drawString(Objects.requireNonNull(makeNum()),0,20); //告诉浏览器,这个请求用图片的方式打开 resp.setContentType("image/jpeg"); //网站存在缓存,不让浏览器缓存 resp.setDateHeader("expires",-1); resp.setHeader("Cache-Control","no-cache"); resp.setHeader("Pragma","no-cache"); //给这个响应设置三秒刷新一次,且把缓存机制关掉 resp.setHeader("refresh","3"); //将这张图片写入浏览器 ImageIO.write(bufferedImage,"jpg",resp.getOutputStream()); }
response实现重定向
//参数为:项目名/地址名 resp.sendRedirect("/ServletHttpResponse/getImage");
<%--action:这里提交的路径,需要寻找到项目的路径--%> <%--${pageContext.request.contextPath}代表当前的项目--%> <form action="${pageContext.request.contextPath}/redirect" method="get"> username <input name="username" type="text"> <br> password: <input name="password" type="password"> <br> <input type="submit"> </form>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username"); String password = req.getParameter("password"); System.out.println(username +": "+password); //参数为:项目名/地址名 resp.sendRedirect("/ServletHttpResponse/success.jsp"); }
HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息
request获取请求的数据,并请求转发
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); //获取表单数据 String username = req.getParameter("username"); String password = req.getParameter("password"); String[] hobbies = req.getParameterValues("hobbies"); System.out.println(username); System.out.println(password); System.out.println(Arrays.toString(hobbies)); //请求转发 req.getRequestDispatcher("/success.jsp").forward(req,resp); }
<form action="${pageContext.request.contextPath}/login" method="post"> username <input name="username" type="text"> <br> password: <input name="password" type="password"> <br> hobbies: <input name="hobbies" type="checkbox" value="女孩">女孩 <input name="hobbies" type="checkbox" value="代码">代码 <input name="hobbies" type="checkbox" value="电影">电影 <input name="hobbies" type="checkbox" value="爬山">爬山 <input type="submit"> </form>
cookie
session
从请求中拿到cookie信息
服务器响应给客户端cookie
Cookie[] cookies = req.getCookies(); //获得Cookie cookie.getName(); //获得cookie中的key cookie.getValue(); //获得cookie中的vlaue new Cookie("lastLoginTime", System.currentTimeMillis()+""); //新建一个cookie cookie.setMaxAge(24*60*60); //设置cookie的有效期 resp.addCookie(cookie); //响应给客户端一个cookie
cookie:一般会保存在本地的 用户目录下 appdata
一个网站cookie是否存在上限
删除Cookie
编码解码
URLEncoder.encode("测试","utf-8") URLDecoder.decode(cookie.getValue(),"UTF-8")
什么是Session:
使用Session
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //解决乱码问题 req.setCharacterEncoding("UTF-8"); resp.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;charset=utf-8"); //得到Session HttpSession session = req.getSession(); //给Session中存东西 session.setAttribute("name",new Person("测试",1)); //获取Session的ID String sessionId = session.getId(); //判断Session是不是新创建 if (session.isNew()){ resp.getWriter().write("session创建成功,ID:"+sessionId); }else { resp.getWriter().write("session以及在服务器中存在了,ID:"+sessionId); } //Session创建的时候做了什么事情; // Cookie cookie = new Cookie("JSESSIONID",sessionId); // resp.addCookie(cookie); }
获得Session
HttpSession session = req.getSession(); Person person = (Person) session.getAttribute("name"); System.out.println(person.toString()); HttpSession session = req.getSession(); session.removeAttribute("name"); //手动注销Session session.invalidate();
会话自动过期:web.xml配置
<!--设置Session默认的失效时间--> <session-config> <!--15分钟后Session自动失效,以分钟为单位--> <session-timeout>15</session-timeout> </session-config>