MVC模式修改用户管理系统 对当前网站结构的问题分析 1. 在LoginCl.java 文件和ManageUser.java文件中都去操作了数据库,它们的逻辑相似,有重复代码 2: 整个框架没有清晰的层次关系,显得非常乱. 3:代码一点也不优雅, 可读性差,可维护性差. 解决方法: 指导思想: ① 业务逻辑代码和界面分离 ② 把常用的代码(对数据库的连接和操作) 封装到工具类 具体的方法 ① 每一张表对应 一个 domain类(表示数据) 还要对应一个 Service 类 比如 users 表 对应 Users 类(domain 类) UserService类(该类会封装对users表的各种操作) ,实际上这里体现出 数据 和 操作分离的思想 上机练习: 包登录部分改成mvc模式 ,建议先保存一份项目,再改. ① 完成分页的mvc模式改写 首先在UsersService 类中添加方法 //? 为什么要返回ArrayList ,而不是我们想到 ResultSet //1. ArrayList 中封装 User对象,更加符合面向对象的编程方式 OOP //2.我们通过 Resulst->User 对象->ArrayList 这样ArrayList 和 Resultset没有关系,就可以及时关闭数据库资源. public ArrayList getUsresByPage(int pageNow,int pageSize){ reutrn al; } 练习: 把我们的用户管理系统出了 cookie 和 session 相关的功能不做,其它都做了. 一起完成用户管理系统的crud操作 1. 一个请求对应一个控制器 优点: 逻辑清晰 缺点: 会造成控制器过多 可以这样考虑:一类事务请求,我们做一个控制器,即让该控制器可以处理多个请求,为了让一个控制器去区分,不同的请求,我们可以这样做: 在发出请求的同时,在带一个type=del 或者 type=add 或者 type=update..., 在控制器中我们接收type的值,从而判断用户希望做什么事情! 关于跳转到修改用户界面有两种思路: (1) 传递用户id号的同时,把用户的其它信息一并传递,这样可以减少数据库查询的次数 (缺点: 增加网络开销 100字节*1000000*2 , 优点: 减少对数据库的一次操作) (2) 只传递用户id好,控制器接收到id后,再查询数据库,从而显示. 添加用户 (1) 用户id号,我们做成子增长 在oracle中先建立一个sequece create sequence users_seq start with 11 increment by 1 minvalue 11 nomaxvalue nocycle nocache 课堂练习 添加查询用户功能:安装老师给出网站结构写. 会话技术cookie和session 什么是会话 基本概念: 指用户开一个浏览器,访问一个网站,只要不关闭该浏览器,不管该用户点击多少个超链接,访问多少资源,直到用户关闭浏览器,整个这个过程我们称为一次会话. 比如打电话. 为什么需要cookie技术(会话技术) 如何保存用户上次登录时间 如何显示用户浏览历史? 如何把登录的用户名和密码电脑,下次登录,不需要重新输入: 解决之道—cookie cookie的原理图 cookie的小结 ① cookie 是在服务端创建 ② cookie 是保存在浏览器这端 ③ cookie 的生命周期可以通过 cookie.setMaxAge(2000); 如果不设置setMaxAge则该cookie的生命周期当浏览器关闭时,就消亡. ④ cookie 可以被多个浏览器共享(与session的区别) ⑤ 怎么理解 我们可以把cookie 想成一张表 如果cookie重名会有什么问题? 如果重名就会替换存在的cookie值. ⑥ 一个web应用可以保存多个cookie,但保存在同一个cookie文本在客户端浏览器下 ⑦ cookie存放的时候是以明文方式存放,因此安全较低.,我们可以通过加密后保存. ->补讲md5加密算法 : 请大家注意,以后我们的密码都要使用加密存放,在验证密码的时候,对用户输入密码,进行md5加密,然后该到数据库去验证。 md5算法 package com.hsp; import java.security.*; import java.security.spec.*; class MD5_test { public final static String MD5(String s) { char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; try { byte[] strTemp = s.getBytes(); MessageDigest mdTemp = MessageDigest.getInstance("MD5"); mdTemp.update(strTemp); byte[] md = mdTemp.digest(); int j = md.length; char str[] = new char[j * 2]; int k = 0; for (int i = 0; i < j; i++) { byte byte0 = md[i]; str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } return new String(str); } catch (Exception e) { return null; } } public static void main(String[] args) { // MD5_Test aa = new MD5_Test(); System.out.print(MD5_test.MD5("韩顺平")); } } 保存上次登录时间 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //先获取cookie // 假设我们 保存上次登录时间的cookie "lasttime" "2011-11-11 12:12:12"; // 这里我们要考虑一个情况: 用户第一次登录 '您是第一次登录..' Cookie []cookies=request.getCookies(); boolean b=false;//假设没有lasttime cookie if(cookies!=null){ //保证有cookie,取遍历 for(Cookie cookie: cookies){ //取出名 String name=cookie.getName(); if("lasttime".equals(name)){ //显示 out.println("您上次登录时间是 "+cookie.getValue()); //更新时间 //把当前日期保存cookie SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String nowTime=simpleDateFormat.format(new java.util.Date()); Cookie mycookie=new Cookie("lasttime",nowTime); mycookie.setMaxAge(7*3600*24);//保存一周 response.addCookie(mycookie); b=true; break; } } } if(!b){ //没有找到 out.println("您是第一次登录.."); //把当前日期保存cookie SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String nowTime=simpleDateFormat.format(new java.util.Date()); Cookie cookie=new Cookie("lasttime",nowTime); cookie.setMaxAge(7*3600*24);//保存一周 response.addCookie(cookie); } } *上机练习 cookie自动保存用户密码 打开登录页面的时候,自动填写该用户的用户名和密码【这个要求学员课堂练习(最好单开一个项目)】 cookie保存浏览商品 请自己作为作业考虑实现 cookie的细节 ① 一个浏览器最多放入 300cookie,一个web站点,最多 20cookie,而且一个cookie大小限制子4k ② cookie生命周期的再说明: 1. cookie默认生命周期是会话级别 2. 通过setMaxAge() 可以设置生命周期 setMaxAge(正数) , 即多少秒后该cookie失效 setMaxAge(0) ,删除该cookie setMaxAge(负数), 相当于该cookie生命周期是会话级别. 案例 : //先得到该cookie Cookie cookies[]=request.getCookies(); for(Cookie cookie: cookies){ if(cookie.getName().equals("id")){ System.out.println("id"); //删除 cookie.setMaxAge(0); response.addCookie(cookie);//一定带上这句话,否则不能删除 } } 特别说明: 如果该web应用只有一个cookie ,则删除该cookie后,在浏览器的临时文件夹下没有该cookie文件,如果该web应用有多个cookie,则删除一个cookie后,文件还在,只是该cookie没有 ③ cookie存放中文,怎么处理 存放: String val=java.net.URLEncoder.encode("顺平","utf-8"); Cookie cookie=new Cookie("name",val); 取出: String val=java.net.URLDecoder.decode(cookie.getValue(), "utf-8"); out.println("name ="+val); session为什么有? 问题1: 如何实现在不同的页面,可以去查看信息(比如说购物车),同时还要实现不同的用户看到的信息是自己. session工作原理图 session的生命周期是30分钟 session 小结: ① session是存在服务器的内存中 ② 一个用户浏览器,独享一个session域对象 ③ session中的属性的默认生命周期是30min ,你可以通过 web.xml来修改 ④ 3种session生命周期的设置 (1)一个地方是 tomcat/conf/web.xml <session-config> <session-timeout>30</session-timeout>//表示30分钟的意思 </session-config> 对所有的web应用生效 (2)另外一个地方,就是在单个web应用的下去修改 web.xml <session-config> <session-timeout>30</session-timeout>session精确到分钟,cookie精确到秒 </session-config> 如果发生冲突,则以自己的web应用优先级高 (3)session.setMaxInactiveinterval(60)发呆六十秒后session失效 对session和cookie生命周期小结: ⑤ session中可以存放多个属性 ⑥ session 可以存放对象 ⑦ 如果 session.setAttribute(“name”,val) , 如果名字重复,则会替换该属性. ?如果同一个用户浏览器,向session设置一个属性的时候,如果名字相同了,会出现什么情况? 结论: 会替换该对象值. session的更深入理解: 为什么服务器能够为不同的浏览器提供不同session? 因为每个浏览器去访问web站点的时候,如果发出的http请求头没有带JSESSIONID头就会自动给你创建一个并返回 www.sourceforge.net [开源之祖] 生成验证码案例 使用(原理是使用到java的绘图技术.) 这里最重要的就是生成验证码的servlet package com.hsp; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.PrintWriter; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CreateCode extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 7.禁止浏览器缓存随机图片 response.setDateHeader("Expires", -1); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache"); // 6.通知客户机以图片方式打开发送过去的数据 response.setHeader("Content-Type", "image/jpeg"); // 1.在内存中创建一副图片 BufferedImage image = new BufferedImage(60, 30, BufferedImage.TYPE_INT_RGB); // 2.向图片上写数据 Graphics g = image.getGraphics(); // 设背景色 g.setColor(Color.BLACK); g.fillRect(0, 0, 60, 30); // 3.设置写入数据的颜色和字体 g.setColor(Color.RED); g.setFont(new Font(null, Font.BOLD, 20)); // 4.向图片上写数据 String num = makeNum(); //这句话就是把随机生成的数值,保存到session request.getSession().setAttribute("checkcode", num); 通过session就可以直接去到随即生成的验证码了 g.drawString(num, 0, 20); // 5.把写好数据的图片输出给浏览器 ImageIO.write(image, "jpg", response.getOutputStream()); } //该函数时随机生成7位数字 public String makeNum() { Random r = new Random(); //9999999 可以生成7位 String num = r.nextInt(9999) + ""; StringBuffer sb = new StringBuffer(); //如果不够4位,前面补零 for (int i = 0; i < 4 - num.length(); i++) { sb.append("0"); } num = sb.toString() + num; return num; } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } 如何适用 Login.java <img src=”/验证码的url”/> 练习,请大家把 验证码功能加入到用户管理系统. 过滤器(filter) ①开发过滤器的步骤: 1. 创建 继承HttpServlet 同时实现Filter接口 2. 默认filter不生效,需要配置. <!-- 自己配置的一个filter --> <filter> <filter-name>MyFilter</filter-name> <filter-class>com.zhy.filter.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/*</url-pattern> /*表示对该WEB的所有网页都过滤 </filter-mapping> 3. 在filter的方法中添加业务逻辑. package com.hsp.filter; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.hsp.domain.User; public class MyFilter1 extends HttpServlet implements Filter { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.print("myfilter1..."); //获取session HttpServletRequest httpServletRequest= (HttpServletRequest)request; //看看请求的资源是什么 String uri=httpServletRequest.getRequestURI(); if(uri.startsWith("/UsersManager3/imgs")||uri.startsWith("/UsersManager3/Login")){ //直接放行. chain.doFilter(request, response); }else{ HttpSession session=httpServletRequest.getSession(); User user=(User) session.getAttribute("loginuser"); if(user!=null){ //该用户合法,放行 chain.doFilter(request, response); }else{ request.setAttribute("err", "请好好登陆"); httpServletRequest.getRequestDispatcher("/LoginServlet") .forward(request, response); } } } public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } } 过滤器链 实现方式 : 1. 在创建一个过滤器 (继承HttpServlet 同时还要实现Filter接口) 2. 配置过滤器 配置过滤器的顺序就可以决定调用过滤器的顺序. 控制session的销毁时间 对session的销毁时间的讨论—借助一个案例: 面试题: (应用:关掉IE后,再开IE,上次购买的商品还在。->涉及到session销毁时间) 分析 我们的session 生命周期如果是30min,该session不会随浏览器的关闭,而自动销毁.而会到30min后,才会被服务器销毁. 我们使用代码来实现该功能(session + cookie结合使用) 分析实现的思路: public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); HttpSession session = request.getSession(); session.setAttribute("name", "张辉胤"); out.println("创一个session并放入姓名属性"); Cookie cookie = new Cookie("JSESSIONID", session.getId()); cookie.setMaxAge(60*30); response.addCookie(cookie); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); HttpSession httpSession = request.getSession(); String name = (String) httpSession.getAttribute("name"); out.println("name = "+name); } ie禁用cookie后使用session的方法 如何实现ie禁用cookie后,我们还可以继续使用session. 简易购物车的实例: 思路: 当用户点击购买商品时,我们把该商品保存到session中,该session的结构是 name val mybookds hashMap对象 而hashmap的结构是 key val 书号 书对象. Book.java类; 具体的实现,参看myCart项目 总节我们使用到的相关知识 (1) java基础的集合 ArrayList HashMap LinkedHashmap(有序的) (2) session技术 (3) servlet (4) 单态 (5) 如何选择不同的集合 list 集合都是有序 map 集合是无序 list和map集合都可以放入null list可以放入相同的对象,而map也可以放相同对象 , 但是key不能重复. JSP笔记 1. 为什么需要servletContext 需求1 需求2 解决之道—ServletContext 原理图: 快速入门 ServletContext 1. ServletContext 是在服务器 2. ServletContext 是被所有客户端共享 3. ServletContext 是当web应用启动的时候,自动创建 4. ServletContext 当web应用关闭/tomcat关闭/对web应用reload 会造成servletContext销毁. 对ServletContext的用法小结 获取: this.getServletContext(); this.getServletConfig().getServletContext(); 添加属性: servletcontext.setAttribute(string,object); 取出属性 servletcontext.getAttribute(“属性名”) 删除 setvletContext.removeAttribute(“属性名”); ServletContext的应用 (1) 获取WEB应用的初始化参数 <!-- 如果希望所有的servlet都可以访问该配置. --> <context-param> <param-name>name</param-name> <param-value>scott</param-value> </context-param> 如何获取 String val= this.getServletContext().getInitParameter("name"); (2) 使用ServletContext实现跳转 //目前我们跳转到下一个页面 //1 response.sendRedirect("/web应用名/资源名"); //2 request.getRequestDispatcher("/资源名").forward(request, response); /* * 区别1. getRequestDispatcher 一个跳转发生在web服务器 sendRedirect发生在浏览器 * 2. 如果request.setAttribute("name","顺平") 希望下一个页面可以使用 属性值,则使用 getRequestDispatcher * 3. 如果session.setAttribute("name2","顺平3"), 希望下一个页面可以使用 属性值,则两个方法均可使用,但是建议使用 getRequestDispatcher * 4. 如果我们希望跳转到本web应用外的一个url,应使用sendRedirect */ //3.这种方法和2一样 this.getServletContext().getRequestDispatcher("/资源url").forward(request, response); (3) 读取文件,和获取文件全路径 //首先读取到文件 InputStream inputStream=this.getServletContext().getResourceAsStream("dbinfo.properties"); //创建Properties Properties pp=new Properties(); pp.load(inputStream); out.println("name="+pp.getProperty("username")); *如果文件放在src目录下;则使用类加载器 //如果文件放在src目录下,我们应该使用类加载器来读取 InputStream is=Servlet5.class.getClassLoader().getResourceAsStream("dbinfo.properties") //获取文件全路径 //如果读取到一个文件的全路径 String path=this.getServletContext().getRealPath("/imgs/Sunset.jpg"); out.println("paht = "+path); 网站计数器的思考 分析 : 代码: 我们建立一个文件recoder.txt文件,用于保存访问量,可以可以保证稳定增长. 实现方法 建立InitServlet ,用于初始化我的Servletcontext,和在关闭tomcat时保存访问量 package com.hsp; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class InitServlet extends HttpServlet { /** * Destruction of the servlet. <br> */ public void destroy() { System.out.println("init servlet destory()被调用.."); //把ServletContext值重新保存到文件. //从record.txt文件中,读取浏览量 //1.首先得到该文件真实路径 String filePath=this.getServletContext().getRealPath("record.text"); //2.打开文件 try { FileWriter filewriter=new FileWriter(filePath); //为了读取我们转为BufferedReader BufferedWriter bufferedWriter=new BufferedWriter(filewriter); //从ServletContext读取访问量 String nums=(String) this.getServletContext().getAttribute("nums"); //重新写会文件 bufferedWriter.write(nums); //一定要关闭流 bufferedWriter.close(); filewriter.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ //关闭... } } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } public void init() throws ServletException { // Put your code here //从record.txt文件中,读取浏览量 //1.首先得到该文件真实路径 String filePath=this.getServletContext().getRealPath("record.text"); //2.打开文件 try { FileReader fileReader=new FileReader(filePath); //为了读取我们转为BufferedReader BufferedReader bufferedReader=new BufferedReader(fileReader); String nums=bufferedReader.readLine(); //把nums添加到Servletcontext this.getServletContext().setAttribute("nums", nums); //一定要关闭流 bufferedReader.close(); fileReader.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 当用户登录一次我们取出ServletContext取出,并+1, //向servletContext中添加属性 //1.先取出 String nums=(String) this.getServletContext().getAttribute("nums"); //如果有,则取出+1 this.getServletContext().setAttribute("nums", (Integer.parseInt(nums)+1)+""); 在Mange页面显示 String nums=this.getServletContext().getAttribute("nums").toString(); out.println("该管理页面被访问了 "+nums+" 次"); 问:如果我们的tomcat异常退出,怎么办. 使用线程,定时把ServletContext的值,刷新到recorder.txt 比如10min. 上机练习: 最后说: 针对工具类 SqlHelper.java 1. 我们的链接数据库的变量都是static,这样有一个潜在危险.如果访问量大,可能造成一些用户等待超时.我们可以这样做: 把static变量 改成 非 static 在调用SqlHelper时候,首先创建一个 SqlHelper对象,然后调用相应的方法. 2. 我们的SqlHelper在查询数据的 ResultSet 没有在SqlHelper本类中关闭,不是太好,解决方案入下: public static ResultSet executeQuery(String sql,String []parameters){ try { ct=getConnection(); ps=ct.prepareStatement(sql); if(parameters!=null&&!parameters.equals("")){ for(int i=0;i<parameters.length;i++){ ps.setString(i+1 , parameters[i]); } } rs=ps.executeQuery(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e.getMessage()); // TODO: handle exception }finally{ //close(rs, ps, ct); } return rs; } 上面的代码可以修改成这样: jsp讲解 jsp为什么会出现? 因为在开发web网站时候,发现servlet做界面比较麻烦,于是又有一个新的技术jsp jsp是什么? 1. jsp运行在服务器 2. jsp(java server page) 3. jsp的基础是servlet(相当于对servlet进行一个包装) 4. jsp是综合技术 jsp=html+css+javascript+java代码+jsp标签(servlet) 5. jsp无需配置.直接使用,如果你修改了jsp文件,不需要重新reload web应用. 6. jsp如何方法 http://ip:8088/web应用名/jsp路径 7. jsp是一种动态网页技术. 快如入门案例 讲解jsp的运行原理 Web服务器是如何调用并执行一个jsp页面的? 看上面的原理图 Jsp页面中的html排版标签是如何被发送到客户端的? out.write(" <table border=1>\r\n"); out.write(" <tr><td>apple</td><td>melon</td><td>orange</td></tr>\r\n"); out.write(" <tr><td>apple</td><td>melon</td><td>orange</td></tr>\r\n"); out.write(" <tr><td>apple</td><td>melon</td><td>orange</td></tr>\r\n"); out.write(" <tr><td>apple</td><td>melon</td><td>orange</td></tr>\r\n"); out.write(" </table>\r\n"); Jsp页面中的java代码服务器是如何执行的? 比如jsp是: <% int i=90; int j=i+90; %> <h1>测试.</h1> <% out.println("j="+j); %> 当被翻译成jsp后:java文件 public jspService(){ int i=90; int j=i+90; } 1. 就是有多个<% %> 其实相当于是一个大的 <% %> 2. 在<% %> 中定义的变量,会成为service函数的局部变量. Web服务器在调用jsp时,会给jsp提供一些什么java对象? 供提供了九个: 我们使用了 out 对象 --->Servlet 的 PrintWriter 说 jsp=html+css+js+java代码+jsp语法(标签 ) jsp的语法 ① 指令元素 概念: 用于从jsp发送一个信息到容器,比如设置全局变量,文字编码,引入包 1. page指令 <%@ page contentType="text/html;charset=gb2312"%> 常用的属性: contentType 和 pageEncoding的区别 contentType=“text/html;charset=utf-8” 指定网页以什么方式显示页面 pageEncoding=“utf-8” 指定Servlet引擎以什么方法翻译jsp->servlet 并 指定网页以什么方式显示页面 2. include指令 用法: <%@ include file=”文件路径” %> 3. taglib指令 <mytag:xx 属性 /> ② 脚本元素 java片段: <% java 代码 %> 表达式: <%=表达式 %> <% int i=90; %> <h1>显示</h1> <% out.println("i="+i); %> <%=i*78-23 %> 定义变量 <%! int i=90; %> 定义函数 <%! public int getResult(int a,int b){return a+b;}%> 函数不能在 <% %> 定义. 面试题: ③ 动作元素 <jsp:forward file=””> 的作用 在开发jsp的过程中,我们通常把jsp放入WEB-INF目录,目的是为了防止用户直接访问这些jsp文件. 在WebRoot下我们有一个入口页面,它的主要转发 <jsp:forword file=”/WEB-INF/xx.jsp”></jsp:forword> 写. <jsp:incluce file=””></jsp:inclcue> 动态引入: <%@ include file=””%> 静态引入 <jsp:incluce file=””></jsp:incule> 动态引入 相同点: 把一个文件引入到另外一个文件 区别:静态引入 把两个jsp翻译成一个Servlet,所以被引入的文件不要包含<body><html>.. 动态引入 把两个jsp分别翻译,所以被引入的jsp包含有<html><body>也可以. 修改jsp的模板: mvc (m(model模型) v (view视图) c(controller控制器) mvc 它要求程序员做开发把 数据的输入(使用jsp 视图),数据的处理(使用Servlet 即 Controller 调用model完成.),数据的显示(使用jsp),分开. iso9001 作业: 改写项目成mvc JSP的9个内置对象 对象名 类型 作用域 request:请求对象 javax.servlet.ServletRequest的子类 Request response:响应对象 javax.servlet.ServletResponse的子类 Page pageContext:页面上下文对象 javax.servlet.jsp.PageContext Page session:会话对象 javax.servlet.http.HttpSession Session application:应用程序对象 javax.servlet.ServletContext Application out:输出对象 javax.servlet.jsp.JspWriter Page config:配置对象 javax.servlet.ServletConfig Page page:页面对象 java.lang.Object Page exception:异常对象 java.lang.Throwable Page getParameter getParameterNames getParameterValues |
|