JavaWeb
Servlet
sun公司开发动态web的一门技术,开发一个Servlet程序有两步:
- 编写一个类继承Servlet接口
- 将开发好的Java类部署到服务器上
Servlet接口有两个默认的实现类:HttpServlet和GenericServlet
重写doGet()和doPost方法即可,要先导入servlet-api.jar包
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); } }
然后在web.xml中配置servlet映射
<!--注册Servlet--> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.deng.HelloServlet</servlet-class> </servlet> <!--Servlet请求路径映射--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
在Tomcat配置war包并启动Tomcat即可访问
Servlet原理
步骤:
- 浏览器向服务器发出请求
- 服务器上的容器逻辑接收url,根据url判断为Servlet请求,此时容器逻辑产生两个对象:请求对象(HTTPServletRequest)和响应对象(HttpServletResponse)
- 容器逻辑根据url找到对应的目标Servlet,并且创建线程,将请求对象和响应对象传给线程
- 线程调用service()方法,根据请求类型判断是调用doGet()还是调用doPost()
- doGet()执行完成后,将结果返回给容器逻辑
- 线程销毁或放到线程池中
ServletContext
web容器启动时,会为每一个web程序创建一个ServletContext对象,代表当前web应用
共享数据
同一个war包中,两个servlet,在HelloServlet里设置ServletContext对象,GetServlet也可以拿到
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context=this.getServletContext(); String username="dwx"; context.setAttribute("username",username); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
public class GetServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context=this.getServletContext(); String username=(String) context.getAttribute("username"); resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); resp.getWriter().print("名字"+username); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }
获取初始化参数
在web.xml里设置初始化参数
<context-param> <param-name>url</param-name> <param-value>www.baidu.com</param-value> </context-param>
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context=this.getServletContext(); //获取初始化参数 String url=context.getInitParameter("url"); resp.getWriter().print(url); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
实现请求转发
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context=this.getServletContext(); context.setAttribute("username","dengwenxiong"); context.getRequestDispatcher("/getc").forward(req,resp); }
读取配置文件
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context=this.getServletContext(); InputStream is=context.getResourceAsStream("/WEB-INF/classes/user.properties");//编译后的文件所在的地址 Properties properties=new Properties(); properties.load(is); String username=properties.getProperty("username"); String password=properties.getProperty("password"); resp.getWriter().print(username+":"+password); }
HttpServletResponse
web服务器接收客户端的http请求时,会创建一个代表请求的HttpServletRequest对象和一个代表请求的HttpServletResponse对象
- 获取客户端请求过来的参数:使用HttpServletRequest
- 给客户端响应信息:HttpServletResponse
向浏览器发送数据
ServletOutputStream getOutputStream() throws IOException; PrintWriter getWriter() throws IOException;
下载文件
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //下载文件的路径 String path="C:\\Users\\邓文( ̄(工) ̄)\\Pictures\\Java语言类型.png"; //下载的文件名 String fileName="java.png"; //设置编码,让其支持中文 resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8")); //获取下载文件输入流 FileInputStream fis=new FileInputStream(path); //获取输出流 ServletOutputStream out=resp.getOutputStream(); //创建缓冲区 int len=0; byte[] buffer=new byte[1024]; while((len=fis.read(buffer))>0){ out.write(buffer,0,len); } fis.close(); out.close(); }
生成验证码
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //浏览器三秒刷新一次 resp.setHeader("refresh","3"); //在内存中创建一张图片 BufferedImage image=new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB); //得到图片 Graphics g=image.getGraphics(); //设置图片 g.setColor(Color.white); g.fillRect(0,0,80,20); //给图片写数据 g.setColor(Color.BLUE); g.setFont(new Font(null,Font.BOLD,20)); g.drawString(makeNum(),0,20); //告诉浏览器该请求使用图片的方式打开 resp.setContentType("image/jpeg"); //关闭缓存 resp.setDateHeader("expires",-1); resp.setHeader("Cache-Control","no-cache"); resp.setHeader("Pragma","no-cache"); //将图片写给浏览器 ImageIO.write(image,"jpg",resp.getOutputStream()); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } private String makeNum(){ Random random=new Random(); String num=random.nextInt(9999999)+""; StringBuffer stringBuffer=new StringBuffer(); //保证验证码有七位 for(int i=0;i<7-num.length();i++){ stringBuffer.append("0"); } num=stringBuffer.toString()+num; return num; } }
实现重定向
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.sendRedirect("/getc");//重定向 }
HttpServletRequest
HttpServletRequest代表客户端请求,用户通过Http协议访问服务器,Http请求中的所有信息都被封装到HttpServletRequest中,可以通过它获取客户端的所有信息
可以实现请求转发
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.getRequestDispatcher("/getc").forward(req,resp); }
Cookie,Session
Cookie
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //从请求中获取Cookie Cookie[] cookies=req.getCookies(); for (Cookie cookie:cookies) { cookie.getName();//获取cookie中的key cookie.getValue();//获取cookie中的value } Cookie cookie1=new Cookie("lastLonginTime",System.currentTimeMillis()+"");//新建Cookie cookie1.setMaxAge(60*60);//设置cookie有效期 resp.addCookie(cookie1);//响应给客户端一个cookie }
Cookie一般会保存在本地的用户目录下的appdata里
Cookie的上限:
- 一个Cookie只能保存一个信息
- 一个Web站点可以给浏览器发送多个Cookie,最多存放20个
- Cookie的大小限制在4kb
- 浏览器的所有Cookie总数限制在300个
删除Cookie:
- 不设置有效时间,关闭浏览器自动失效
- 设置有效时间为0
Session
服务器给每一个用户(浏览器)创建一个Session对象,一个Session独占一个浏览器
Session与Cookie区别:
- Cookie是把用户的数据写给用户的浏览器,浏览器保存
- Session是把用户的数据写到Session中,由服务端保存,由服务器创建
使用Session
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","dwx"); //获取sessionid String sessionId=session.getId(); //判断是否是新建的session if(session.isNew()){ resp.getWriter().print("新的啊"+sessionId); }else{ resp.getWriter().print("旧的"+sessionId); } }
可以在web.xml里设置会话过期时间
<!--设置Session默认的失效时间--> <session-config> <!--15分钟后Session自动失效,以分钟为单位--> <session-timeout>15</session-timeout> </session-config>
JSP
浏览器向服务器发送请求时,不管访问什么资源,其实都是在访问Servlet
JSP最终也会转换成一个java类,其本质就是一个Servlet
在JSP页面中:
- java代码就原封不动的输出
- HTML代码转换为out.write("\r\n");输出到前端
JSP语法格式
<%--注释--%> <%代码片段%> <%=表达式%> <%!声明%> <%@指令%>
JSP九大内置对象
- pagecontext
- request
- response
- session
- application
- config
- out
- page
- exception
pageContext.setAttribute("name1","秦疆1号"); //保存的数据只在一个页面中有效 request.setAttribute("name2","秦疆2号"); //保存的数据只在一次请求中有效,请求转发会携 带这个数据 session.setAttribute("name3","秦疆3号"); //保存的数据只在一次会话中有效,从打开浏览器 到关闭浏览器 application.setAttribute("name4","秦疆4号"); //保存的数据只在服务器中有效,从打开服 务器到关闭服务器
JavaBean
实体类,一般用来个数据库字段做映射ORM(对象关系映射):
- 表<-->类
- 字段<-->属性
- 行记录<-->对象
Filter
过滤器,过滤网站数据
自定义过滤器,实现Filter接口,重写方法
public class ZdyFilter implements Filter { //Web服务器启动就已经初始化,等待过滤对象出现 @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("自定义的过滤器正在初始化"); } //chain是过滤器链request -> filter1 -> filter2 ->filter3 -> …. -> request resource //chain.doFillter()就是将请求转发给过滤器链的下一个过滤器 @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=UTF-8"); System.out.println("过滤器执行前"); chain.doFilter(request,response); System.out.println("过滤器执行后"); } @Override public void destroy() { System.out.println("销毁自定义过滤器"); } }
在web.xml中配置Filter
<!--注册过滤器--> <filter> <filter-name>ZdyFilter</filter-name> <filter-class>com.deng.ZdyFilter</filter-class> </filter> <!--配置映射--> <filter-mapping> <filter-name>ZdyFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
监听器
实现监听器接口(有多种监听器),重写对应方法即可
//统计网站在线人数 public class ZdyListener implements HttpSessionListener { //创建Session触发 @Override public void sessionCreated(HttpSessionEvent se) { ServletContext context=se.getSession().getServletContext(); Integer onlineCount=(Integer) context.getAttribute("OnlineCount"); if(onlineCount==null){ onlineCount=new Integer(1); }else{ int count=onlineCount.intValue(); onlineCount=new Integer(count+1); } context.setAttribute("OnlineCount",onlineCount); System.out.println("在线人数"+onlineCount); } //销毁Session时触发 @Override public void sessionDestroyed(HttpSessionEvent se) { ServletContext context=se.getSession().getServletContext(); Integer onlineCount=(Integer)context.getAttribute("OnlineCount"); if(onlineCount==null){ onlineCount=new Integer(0); }else{ int count=onlineCount.intValue(); onlineCount=new Integer(count-1); } context.setAttribute("OnlineCount",onlineCount); System.out.println("在线人数"+onlineCount); } }
在web.xml中注册监听器
<!--注册监听器--> <listener> <listener-class>com.deng.ZdyListener</listener-class> </listener>