zoukankan      html  css  js  c++  java
  • Java Web

    Java Web

    一、使用Tomcat部署Java web应用

    Tomact:

    Web应用服务器:Tomcat、JBoos、Weblogic、Jetty

    • 安装Tomcat

      1. 下载压缩文件

      2. 解压缩

        bin:存放各个平台下启动和停止的Tomcat服务的脚本

        bonf:存放各种Tomcat服务器的配置文件

        lib:存放Tomcat服务器所需要的jar

        logs:存放Tomcat服务运行的日记

        temp:Tomcat运行时的临时文件

        webapps:存放允许客户端访问的资源(Java程序)

        work:存放Tomcat将JSP转换之后的Servlet文件

    IDEA集成Tomcat

    1. 创建Java Web文件

    2. 配置Tomcat文件

    Servlet

    • 什么是Servlet?

      Servlet是JavaWeb开发的基石,与开发平台无关,他是运行在Servlet容器/web应用服务器/Tomcat服务器,负责与客户端进行通信。

      Servlet的功能:

      1. 创建并返回基于客户请求的动态HTML页面

      2. 与数据库进行通信

      • 如何使用Servlet?

        Servlet本身是一组接口,(javax.serlvet、jiava.lang、java.util、java.sql),自定义一个类,并且实现servlet接口,这类就具备了接收客户端的请求以及做出响应的功能。

      • 浏览器不能直接访问Servlet是文件,只能通过映射的方式来间接访问Servlet,映射需要开发者手动配置,有两种配置方式

        1. 基于XML文件配置方式

              <servlet>
                  <servlet-name>MyServlet</servlet-name>
                  <servlet-class>com.gopan.servlettest.MyServlet</servlet-class>
              </servlet>
              <servlet-mapping>
                  <servlet-name>MyServlet</servlet-name>
                  <url-pattern>/myservlet</url-pattern>
              </servlet-mapping>
          
        2. 基于注解的方式 代替XML文件很简单

          @WebServlet("/demo01")
          public class MyServlet implements Servlet {
              
          }
          

          两种配置一样,将demo1与Myservlet进行映射,就是在浏览器地址中直接访问Demo1就可以映射到Myservlet

    • Servlet的生命周期

      1. 当浏览器访问Servlet的时候,Tomcat会查询当前的Servlet的实例化对象是否存在,如果不存在,则通过反射机制动态创建对象,如果存在,直接执行第三步
      2. 调用init方法完成初始化操作
      3. 调用service方法完成业务逻辑操作
      4. 关闭Tomcat时,会destory方法,释放当前对象所占用的资源

      Servlet的生命周期方法:无参构造函数、init、service、destory

      1. 无参构造只调用一次,创建对象
      2. init只调用一次,初始化对象
      3. service调用N次,执行业务方法
      4. destory只调用一次,卸载对象

      ServletConfig

      该接口是用来描述Servlet的基本信息的。

      servletConfig.getServletName();//返回Servlet的名称,
      getInitParameter(String key); //获取init参数的值(web.xml)
      getInitParameterNames(); //返回所有的Paramter所有的值,一般用循环
      getServletContext();//返回ServletContext对象,他是Servlet的上下文,整个服务的信息
      

      ServletConfig 和 ServletContext
      SercletConfig作用于某个Servlet实例,每个Servlet都有对应的ServletConfig,ServletContext作用于整个Web应用,一个Web应用对应一个ServletContext,多个Servlet实例对应一个ServletContext

      一个是局部对象,一个是全局对象

    Servlet的层次结构

    • Servlet --> GenericServlet --> HttpServlet

    • HTTP请求有很多种类型,常用的有四种:

      • GET 读取
      • POST 保存
      • PUT 修改
      • DELETE 删除

      GenericServlet实现Servlet接口,同时为他的子类屏蔽掉不常用的方法,子类只需要重写service方法即可。

      HTTPServlet继承GenericServlet,根据请求类型进行分发处理,GET进入doGET方法,POST进入doPOST方法。

      开发者自定义的Servlet类只需要继承HttpServlet即可,重新doGET和doPost

      package com.gopan.servlet;
      
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      
      @WebServlet("/demo02")
      public class TestServlet extends HttpServlet {
      
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              resp.getWriter().write("GET...");
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              resp.getWriter().write("POST...");
          }
      }
      

    JSP

    • JSP本质上就是一个Servlet,JSP主要是负责与用户交互,将最终的界面呈现给用户,HTML+JS+CSS+Java混合文件。

    • 当服务器接收到一个后缀是JSP的请求时,将该请求交给JSP引擎去处理,每一个JSP页面第一次被访问的时候,JSP引擎会将它翻译成一个Servlet文件,由WEB容器调用Servlet完成响应。

      单纯从开发的角度看,JSP就是在HTML中嵌入Java程序

      具体嵌入方式有3种:

      1. JSP脚本

        <% //Java代码    %>
        
      2. JSP声明:定义Java方法

        <%!
        	声明方法
        %>
        
      3. JSP表达式:把Java对象直接到输出到HTML页面中

        <%=Java变量%>
        
        <%!
          	public String test(){
           		return "world...";
        	}
            %>
        
            <%
              String str = test();
              //
            %>
        
            <%=str%>
        

    JSP内置对象 9个

    • resqust:表示一次请求,HttpServletRequst
    • response:表示一次响应,HttpServlerResponse
    • pageContext:页面上下文,获取页面信息,PageContext
    • session:表示一次会话,保存用户信息,HttpSession
    • application:表示当前的Web应用,全局对象,保存所有用户共享信息,ServlerContext
    • config:当前JSP对应的Servlet的ServletConfig对象,获取当前的Servlet的信息
    • out:向浏览器输出数据,JSPWriter
    • page:当前JSP对象的Servlet对象,Servlet
    • excerption:表示JSP页面发生的异常,Exception

    常用的是:requst、response、session、appliction、pageContext

    1. requst的常用方法:

      1. String getParameter(String key)获取客户端传来的参数 客户端传来服务器

      2. void setAttribute(String key.Object value)通过键值对的形式保存数据。 服务器内部资源传递

      3. Object getAttribute(String key) 通过key取出value。

      4. RequstDispatcher getRequstDispatcher(String path)返回一个RequstDispatcher,该对象的forward方法用于请求转发。

      5. String[] getParameterValues()获取客户端传来的多个同名参数

      6. void setCharacterEncoding(String charset) 指定每个请求的编码。

        HTTP请求状态码:200 正常 404资源找不到 400请求类型不匹配 500java程序抛出异常

    2. response

      1. sendRedirect(String path)重定向 页面之间的跳转

        转发getRequestDispatcher和重定向sendRedirect区别:

        ​ 转发就是将同一个请求下传给下一个页面,重定向是创建一个新的请求传给下一个页面。

        转发:同一个请求在服务之间传递,地址栏不变,也叫服务器跳转。

        重定向:由客户端发送一次新的请求来访问跳转后的目标资源,地址栏改变,也叫客户端跳转

        如果两个页面之间需要通过request来传值,则必须要转发,不饿能使用重定向

        • 用户登录,如果用户名和密码正确,则跳转到首页(首页),并展示用户名,否则重新回到登陆页面(重定向)
    3. Session

      • 用户会话

        服务器无法识别每一次HTTP请求的出处(不知道来自哪个终端),他只会接受一个请求信号,所以就存在一个问题:将用户的响应发送给别人,必须有一种技术来让服务器知道请求来自哪里,这就是会话技术。

        会话:就是客户端和服务器之间发生的一系列连续的请求和响应的过程,打开浏览器进行操作到关闭浏览器的过程。

        会话状态:指服务器和浏览器在会话过程中产生的状态信息,借助于会话状态,服务器能够把属于同一次会话的一系列请求和响应关联起来。

        实现会话两种方式

        • session
        • cookie

        属于同一次会话的请求都有一个相同的标识符,sessionID

        session常用的方法:

        1. String getID()获取到当前的sessionID
        2. void setMaxINactiveInterval(int interval)设置session的失效时间单位为秒
        3. int getMaxIncativeInterval() 获取session的失效时间
        4. void invalidate() 设置session立即失效
        5. void serAttribute(String key,Object value) 通过键值对的形式来存储数据
        6. Object getAtrribute(String key) 通过键值获取对应的数据
        7. void removeAtrribute(String key) 通过键值删除对应的数据
    • Cookie是服务端在HTTP响应中附带传给浏览器的一个小文本文件,一旦浏览器保存了某个Cookie,在之后的请求和响应过程中会将Cookie来回传递,这样就可以通过Cookie这个载体完成客户端和服务器的数据交互。

      Cookie

      • 创建Cookie
      Cookie cookie = new Cookie("name", "lisi");
      response.addCookie(cookie);
      
      • 读取Cookie

        Cookie[] cookies = request.getCookies();
                for (Cookie cookie : cookies) {
                    out.write(cookie.getName() +": " + cookie.getValue() + "<br/>");
                }
        

      Cookie常用方法

      void setMaxAge(int age) 设置Cookie的有效时间,单位为秒

      int getMaxAge() 获取Cookie的有效时间

      String getName() 获取Cookie的name

      String getValue 获取Cookie的value

      Session和Cookie的区别

      Session:保存在服务器中

      ​ 保存的数据Object

      ​ 会随着会话的结束而销毁

      ​ 保存重要信息

      cookie:保存在浏览器中

      ​ 数据是String

      ​ 可以长期保存在浏览器中,与会话无关

      ​ 保存不重要的信息

      存储用户信息:

      session:setAttribute(name,"admin") 存

      ​ getAttribute(name)取

      ​ 声明周期:服务器:只要web引用重启就会销毁,客户端:只要浏览器关闭就销毁

      ​ 退出登录:session.invalidate();

      cookie:response.addCookie(new Cookie("name","admin")) 存

      Cookie[] cookies = request.getCookies();
              for (Cookie cookie : cookies) {
                  //out.write(cookie.getName() + ":" + cookie.getValue());
                  if(cookie.getName().equals("name")){
                      out.write("欢迎回来!" + cookie.getValue());
                  }
              }
      

      生命周期:不随服务端的重启而销毁,客户端:默认是只要关闭浏览器就销毁,我们通过setMaxage()方法设置有效期,一旦设置了有效期,则就不会随浏览器关闭而销毁,而是由设置时间来决定

      退出登录:setMaxAge(0)

    JSP内置对象作用域

    ​ 4个

    ​ page、request、session、application

    ​ setAttribute、getAttribute

    ​ page作用域:对应的内置对象是PageContext

    ​ request作用域:对应的内置对象request

    ​ session作用域:对应的内置对象是session

    ​ allication作用域:对应的内置对象是application

    • page<request<session<appllication

      page只在当前的页面上有效

      request在一次请求内有效

      session在一次会话有效

      application对应整个web应用的

      • 网站的访问量统计

        Integer count = (Integer) application.getAttribute("count");
                if(count == null){
                    count = 1;
                    application.setAttribute("count", count);
                }else{
                    count++;
                    application.setAttribute("count", count);
                }
        您是当前网页的第<%=count%>位访客
        

    EL表达式

    ​ Expression Language表达式语言,可以替代JSP页面中数据访问时的负责编码,可以非常便携的取出域对象(pageContext、request、session、application)中保存的数据,前提是一定先setArribute,EL就相当于在简化getArrtibute()

    ​ ${变量名} 变量名就是setAttrribute对应的key值.

    ​ 1. EL对于4种域对象的默认查找顺序:

    ​ pageContext->request->session->application

    ​ 按照上述的顺序进行查找,找到就立即返回,在application中无法找到,则返回null

    1. 指定作用域进行查找

      ${内置对象Scope.name}

      例如:${sessionScope.name}

      数据级联:

      <%
      //        pageContext.setAttribute("name", "page");//优先级最高,最先查找
      //        request.setAttribute("name", "request");
      //        session.setAttribute("name","session");
      //        application.setAttribute("name","application");
      //        //request.getRequestDispatcher("el2.jsp").forward(request,response);
      
              User user = new User(1,"张三",98.5,new Address(1,"欻大"));
              pageContext.setAttribute("user",user);
      
          %>
          <table>
              <tr>
                  <th>编号</th>
                  <th>姓名</th>
                  <th>成绩</th>
                  <th>地址</th>
              </tr>
              <tr>
                  <td>${user.id}</td>
                  <%
                      //((User)pageContext.getAttribute("user")).getId();
                  %>
                  <td>${user.name}</td>
                  <td>${user.score}</td>
                  <td>${user.address.value}</td>
              </tr>
          </table>
      

      $(user["id"])

    ​ EL执行表达式

    ​ &&||! < > <= >=

    &&and ||or ! not == eq !=ne  <lt >gt  <=le   >=ge  
    empty变量为null,长度为0的string,size为0的集合
    

    JSTL

    JSP Standard Tag LibraryJSP标准标签库,JSP为开发者提供一系列的标签,使用这些标签可以完成一些逻辑处理,比如循环遍历集合,让代码更加简洁,不再出现JSP脚本穿插的情况。

    实际开发中EL和JSTL结合使用,JSTL侧重于逻辑处理,EL负责展示数据

    JSTL的使用

    1. 需要导入jar包(两个jstl,jar standard.jar)

      存放的位置是web/WEB-INF/lib

    2. 在JSP页面开始的地方导入JSTL标签库

      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
      
    3. 在需要的地方使用

            <c:forEach items="${list}" var="user">
              <tr>
                <td>${user.id}</td>
                <td>${user.name}</td>
                <td>${user.score}</td>
                <td>${user.address.value}</td>
              </tr>
      
            </c:forEach>
      

    JSTL优点

    1. 通过了统一的标签
    	2. 可以用于编写各种动态功能
    
    • 常用核心的标签:

    set、out、remove、catch

    set:向域对象添加数据

    <%
    	reuqest.setAttribute(Key,value)
    %>
    
    <c:set var="name" value="tom" scope="request"></c:set>
    
        <%
            User user = new User(1,"张三",56.2,new Address(1, "科技路"));
            request.setAttribute("user",user);
        %>
        ${user.name}
        <hr/>
        <c:set target="${user}" property="name" value="李四"></c:set>
        ${user.name}
    

    out:输出域对象中的数据

        <c:set var="name" value="tom"></c:set>
        <c:out value="${name}" default="未定义"></c:out>
    

    remove:删除域对象的对象

        <c:remove var="name" scope="page"></c:remove>
        <c:out value="${name}" default="未定义"></c:out>
    

    catch:捕获异常

        <c:catch var="error">
            <%
                int a = 1/0;
            %>
        </c:catch>
        ${error}
    
    • 条件标签

      • if choose

            <c:set var="num1" value="1"></c:set>
            <c:set var="num2" value="2"></c:set>
            <c:if test="${num1>num2}">ok</c:if>
            <c:if test="${num1<num2}">fail</c:if>
            <hr/>
            <c:choose>
                <c:when test=" ${num1>num2}">ok</c:when>
                <c:otherwise>fail</c:otherwise>
            </c:choose>
        
      • forEach迭代器

            <c:forEach items="${list}" var="str" begin="1" step="2" end="5" varStatus="sta">
                <%--{sta.index} - ${str}<br/>--%>
                ${sta.count} - ${str}<br/>
            </c:forEach>
        

        格式化标签库常用的标签:

            <%
                request.setAttribute("data", new Date());
        
            %>
            <fmt:formatDate value="${data}" pattern="yyyy-MM-dd HH:mm:ss"></fmt:formatDate>
        
            <fmt:formatNumber value="32145.23434" maxFractionDigits="3" maxIntegerDigits="2"></fmt:formatNumber>
        

        函数标签库

            <%
                request.setAttribute("ignfo", "Java,C");
            %>
            ${fn:contains(ignfo, "Python") }<br/>
            ${fn:startsWith(ignfo, "Java")}<br/>
            ${fn:endsWith(ignfo, "C")}<br/>
            ${fn:indexOf(ignfo, "va")}<br/>
            ${fn:replace(ignfo,"C", "Python")}<br/>
            ${fn:substring(ignfo, 2,3 )}<br/>
            ${fn:split(ignfo, "," )[0]}-${fn:split(ignfo, ",")[1]}<br/>
        

    过滤器

    • Filter

      功能:

      1. 用来拦截传入的请求和传出的响应
      2. 修改或以某种方式处理正在客户端和服务端之间交换的数据流

      如何使用?

      与使用Servlet类似,Fiter是Java WEB提供的一个几口,开发者只需要自定义一个类并且实现该接口即可。

    public class CharacterFilter implements Filter {
        
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            servletRequest.setCharacterEncoding("UTF-8");
            filterChain.doFilter(servletRequest,servletResponse);
        }
    }
    

    web.xml进行配置Filter

        <filter>
            <filter-name>character</filter-name>
            <filter-class>com.gopan.filter.CharacterFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>character</filter-name>
            <url-pattern>/login</url-pattern>
            <url-pattern>/text</url-pattern>
        </filter-mapping>
    

    注意:Filter处理完业务逻辑之后,一定要添加filterChain.doFilter(servletRequest,servletResponse);

    Filter生命周期

    当Tomcat启动时,通过反射机制调用Filter的无参构造函数创建实例化对象,同时调用init实现初始化,doFilter方法调用多次,当Tomcat服务关闭的时候,调用destroy来销毁Filter对象

    无参构造函数:只调用一次,当Tomcat启动时调用(Filter一定要进行配置)

    init方法:只调用一次Filter实例化对象创建完成后调用

    doFilter:调用多次,访问Filter的业务逻辑都写在Filter中

    destory:只调用一次mTomcat关闭时调用

    同时配置多个Filter,Filter的调用顺序由web.xml中的配置顺序来决定,写在上面的配置先调用,因为web.xml是由上到下读取数据的

        <filter>
            <filter-name>character</filter-name>
            <filter-class>com.gopan.filter.CharacterFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>character</filter-name>
            <url-pattern>/login</url-pattern>
            <url-pattern>/text</url-pattern>
        </filter-mapping>
        <filter>
            <filter-name>myfilter</filter-name>
            <filter-class>com.gopan.filter.MyFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>myfilter</filter-name>
            <url-pattern>/login</url-pattern>
            <url-pattern>/text</url-pattern>
        </filter-mapping>
    

    也可以通过注解的方式来简化web.xml的配置

    @WebFilter("/login")
    public class Myfilter implements Filter{
        
    }
    

    实际开发中的Filter的使用场景

    1. 统一处理中文乱码

    2. 屏蔽,敏感词

      @WebFilter("/test")
      public class WordFilter  implements Filter {
          @Override
          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
              servletRequest.setCharacterEncoding("UTF-8");
              //将敏感词替换成****
              String name = servletRequest.getParameter("name");
              System.out.println(name);
              name = name.replaceAll("敏感词","***");
              System.out.println(name);
              servletRequest.setAttribute("name", name);
              filterChain.doFilter(servletRequest,servletResponse);
          }
      }
      @WebServlet("/test")
      public class TestServlet extends HttpServlet {
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              String name = (String) req.getAttribute("name");
              System.out.println(name);
          }
      }
      
    3. 控制资源的访问权限

    文件上传下载

    • JSP

      1. input的type设置为file
      2. form表单的method设置为post,get请求会将文件名传给服务端,而不是文件本身
      3. form表单的enctype值设置为multipart/form-data,以二进制的形式传输数据
    • Servlet

      fileupload组件可以将所有的请求信息都解析成FileIteam对象,可以通过FileItem对象的操作完成上传,面向对象的思想。

          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      /*        //输入流
              req.setCharacterEncoding("UTF-8");
              ServletInputStream inputStream = req.getInputStream();//字节流
              Reader reader = new InputStreamReader(inputStream);//字符流
              BufferedReader bufferedReader = new BufferedReader(reader);//缓冲字符流
      
              //输出流将数据流输出到本地
              //获取文件绝对路径
              String path = req.getServletContext().getRealPath("file/copy.txt");
              OutputStream outputStream = new FileOutputStream(path);
              Writer writer =new OutputStreamWriter(outputStream);
              BufferedWriter bufferedWriter = new BufferedWriter(writer);
              String str="";
              while((str = bufferedReader.readLine())!=null){
                  System.out.println(str);
                  bufferedWriter.write(str);
              }
              bufferedWriter.close();
              writer.close();
              outputStream.close();
              bufferedReader.close();
              reader.close();
              inputStream.close();*/
      
      
              /*int temp = 0;
              while ((temp = inputStream.read())!=-1){
                  System.out.println(temp);
              }*/
      
              DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
              ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
              try {
                  List<FileItem> list = servletFileUpload.parseRequest(req);
                  for (FileItem fileItem : list) {
                      if(fileItem.isFormField()){
                          String name = fileItem.getFieldName();
                          String value = fileItem.getString("UTF-8");
                          System.out.println(name + ":" + value);
                      }else {
                          String fileNmae = fileItem.getName();
                          long size = fileItem.getSize();
                          System.out.println(fileNmae+ ":"+size+"Byte");
                          InputStream inputStream = fileItem.getInputStream();
      
                          String path = req.getServletContext().getRealPath("file/"+fileNmae);
                          OutputStream outputStream =new FileOutputStream(path);
      
                          int temp = 0;
                          while((temp = inputStream.read())!=-1){
                              outputStream.write(temp);
                          }
                          outputStream.close();
                          inputStream.close();
      
                          System.out.println("上传成功...");
                      }
                  }
      
              } catch (FileUploadException e) {
                  e.printStackTrace();
              }
      
      
          }
      
          <form enctype="multipart/form-data" action="/upload" method="post">
              <input type="text" name="desc"><br/>
              <input type="file" name="file"><br/>
              <input type="submit" value="上传">
      
          </form>
      

    文件下载

        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
            String type= req.getParameter("type");
            String fileName = "";
            switch (type){
                case "png":
                    fileName = "123.png";
                    break;
                case "txt":
                    fileName = "test.txt";
                    break;
            }
            //设置响应方式
            resp.setContentType("application/x-msdownload");
    
    
            //设置下载之后的文件名
            resp.setHeader("Content-Disposition", "attachment;filename="+fileName);
            //获取输出流
            OutputStream outputStream = resp.getOutputStream();
            String path = req.getServletContext().getRealPath("file/"+fileName);
            InputStream inputStream = new FileInputStream(path);
            int temp = 0;
            while ((temp = inputStream.read())!=-1){
                outputStream.write(temp);
            }
            inputStream.close();
            outputStream.close();
        }
    

    Ajax

    asnchronous javascript and XML 异步的JavaScript和XML

    AJAX不是新的编程,指的是一种交互方式,异步加载,客户端和服务器的数据交互更新在局部页面的技术,不需要刷新整个页面(局部刷新)

    优点:

    1. 局部刷新,效率更高
    2. 用户体验更好

    基于jQuery的AJAX

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
        <script type="text/javascript" src="js/jquery-1.7.2.js"></script>
        <script type="text/javascript">
            $(function () {
                var btn = $("#btn");
                btn.click(function () {
                    $.ajax({
                        url:'/test',
                        type:'post',
                        data:'id=1',
                        dataType:'text',
                        success:function (data) {
                            $("#id").val(data.id);
                            $("#name").val(data.name);
                            $("#score").val(data.score);
                        },
                        error:function () {
                            alert("服务器正在维护中...")
                        },
                        complete:function () {
                            alert("请求完成!")
                        }
                    });
                });
            })
    
    
        </script>
    </head>
    <body>
        编号:<input type="text" id="id"/><br/>
        姓名:<input type="text" id="name"/><br/>
        成绩:<input type="text" id="score"/><br/>
        <input type="button" value="提交" id="btn">
    </body>
    </html>
    

    不能用表单的提交方式,改用JjQuery方式动态绑定事件来提交。

    Servlet不能跳转到JSP,只能将数据返回

        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {     
            String id =req.getParameter("id");
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            String str = "HRllo";
            resp.getWriter().write(str);
        }
    

    传统的WEB数据交互 VS AJAX的数据交互

    • 客户端请求方式不同

      • 传统:浏览器发送同步请求(Form,a)
      • AJAX:异步引擎对象发送异步请求
    • 服务器响应方式不同

      • 传统:响应一个完整的JSP页面
      • JAJAX:响应需要的数据
    • 客户端处理方式不同

      • 传统:需要等待服务器完成响应并且重新加载整个页面之后,用户才能进行后续的操作
      • AJAX:动态更新页面中的局部内容,不影响用户的其他操作

    AJAX原理

    1591902727930

    基于jQuery的AJAX语法

    $.ajax({属性})

    • 常用的属性参数:
      • url 请求的后端服务地址
      • type请求的范式,默认get
      • data请求的参数
      • dataType服务器返回的数据类型text/json
      • success请求成功的回调函数
      • error请求失败的回调函数
      • complete请求完成的回调函数(无论成功还是失败,都会调用)

    JSON

    JavaScript Object Notion 一种轻量级数据交互格式,完成js与Java等后端开发语言对象数据之间的转换

    客户端和服务器之间传递对象数据,需要用到JSON格式

    public class User {
        private Integer id;
        private String name;
        private Double score;
    
        public User(Integer id, String name, Double score) {
            this.id = id;
            this.name = name;
            this.score = score;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Double getScore() {
            return score;
        }
    
        public void setScore(Double score) {
            this.score = score;
        }
    }
            User user = new User(1, "张三", 56.2);
    
    var user = {
    	id:1,
    	name:"张三",
    	score:45.5
    }
    
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            User user = new User(1, "张三", 56.2);
            resp.setCharacterEncoding("UTF-8");
    //        resp.getWriter().write(user.toString());
            //需要将Java对象转换成JSON格式
            JSONObject jsonObject = JSONObject.fromObject(user);
            resp.getWriter().write(jsonObject.toString());
        }
    
    
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
        <script type="text/javascript" src="js/jquery-1.7.2.js"></script>
        <script type="text/javascript">
            $(function () {
                var btn = $("#btn");
                btn.click(function () {
                    $.ajax({
                        url:'/test',
                        type:'post',
                        data:'id=1',
                        dataType:'json',
                        success:function (data) {
                            $("#id").val(data.id);
                            $("#name").val(data.name);
                            $("#score").val(data.score);
                        },
                        error:function () {
                            alert("服务器正在维护中...")
                        },
                        complete:function () {
                            alert("请求完成!")
                        }
                    });
                });
            })
    
    
        </script>
    </head>
    <body>
        编号:<input type="text" id="id"/><br/>
        姓名:<input type="text" id="name"/><br/>
        成绩:<input type="text" id="score"/><br/>
        <input type="button" value="提交" id="btn">
    

    AJAX

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
        <script type="text/javascript" src="js/jquery-1.7.2.js"></script>
        <script>
            $(function () {
    
                //修改城市
                $("#province").change(function () {
                    var id = $(this).val()
                    $.ajax({
                        url:"location",
                        type:"POST",
                        data:"id="+id+"&type=province",
                        dataType:"JSON",
                        success:function (data) {
                            console.log(data)
                            var content = "";
                            var cities = data.cities;
                            for (var  i=0; i<cities.length;i++){
                                content += "<option>"+ cities[i] + "</option>";
                            }
                            $("#city").html(content);
    
                            var content = "";
                            var areas = data.areas;
                            for (var  i=0; i< areas.length;i++){
                                content += "<option>"+ areas[i] + "</option>";
                            }
                            $("#area").html(content);
    
                        }
                    });
    
                });
    
    
                //修改城市
                $("#city").change(function () {
                    var id = $(this).val()
                    $.ajax({
                        url:"location",
                        type:"POST",
                        data:"id="+id+"&type=city",
                        dataType:"JSON",
                        success:function (data) {
                            var content = "";
                            for(var i=0;i<data.length;i++){
                                content += "<option>"+ data[i] + "</option>";
                            }
                            $("#area").html(content);
                        }
                    });
                });
            });
    
        </script>
    </head>
    <body>
        省:<select id="province">
            <option value="陕西省">陕西省</option>
            <option value="河南省">河南省</option>
            <option value="江苏省">江苏省</option>
        </select>
        市<select id="city">
            <option value="西安市">西安市</option>
            <option value="宝鸡市">宝鸡市</option>
            <option value="渭南市">渭南市</option>
        </select>
        区<select id="area">
            <option>雁塔区</option>
            <option>莲湖区</option>
            <option>新城区</option>
        </select>
    
    </body>
    </html>
    
    @WebServlet("/location")
    public class LocationServlet extends HttpServlet {
        private static Map<String, List<String>> cityMap;
        private static Map<String, List<String>> procinceMap;
    
        static {
            cityMap = new HashMap<>();
            List<String> areas = new ArrayList<>();
            areas.add("雁塔区");
            areas.add("莲湖区");
            areas.add("新城区");
            cityMap.put("西安市",areas);
            areas = new ArrayList<>();
            areas.add("陈仓区");
            areas.add("渭滨区");
            areas.add("新城区");
            cityMap.put("宝鸡市", areas);
            areas = new ArrayList<>();
            areas.add("高新区");
            areas.add("临渭区");
            areas.add("新城区");
            cityMap.put("渭南市", areas);
            areas = new ArrayList<>();
            areas.add("高新A区");
            areas.add("临渭B区");
            areas.add("新城C区");
            cityMap.put("惠州市", areas);
            areas = new ArrayList<>();
            areas.add("陈仓A区");
            areas.add("渭滨B区");
            areas.add("新城C区");
            cityMap.put("潮州市", areas);
    /*        areas = new ArrayList<>();
            areas.add("雁塔A区");
            areas.add("莲湖B区");
            areas.add("新城C区");
            cityMap.put("宝鸡市",areas);*/
    
            procinceMap = new HashMap<>();
            List<String> cites = new ArrayList<>();
            cites.add("西安市");
            cites.add("宝鸡市");
            cites.add("深圳市");
            procinceMap.put("陕西省",cites);
            cites = new ArrayList<>();
            cites.add("南宁市");
            cites.add("广州市");
            cites.add("珠海市");
            procinceMap.put("河南省",cites);
            cites = new ArrayList<>();
            cites.add("惠州市");
            cites.add("潮州市");
            cites.add("香港市");
            procinceMap.put("江苏省",cites);
    
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setCharacterEncoding("UTF-8");
            String type = req.getParameter("type");
            String id = req.getParameter("id");
            switch (type){
                case "city":
                    List<String>  areas = cityMap.get(id);
                    JSONArray jsonArray = JSONArray.fromObject(areas);
                    resp.getWriter().write(jsonArray.toString());
                    break;
                case "province":
                    List<String>  citis = procinceMap.get(id);
                    String  city = citis.get(0);
                    List<String> cityAreas = cityMap.get(city);
                    Location location =new Location();
                    location.setAreas(cityAreas);
                    location.setCities(citis);
                    JSONObject jsonObject = JSONObject.fromObject(location);
                    resp.getWriter().write(jsonObject.toString());
                    int i = 0;
                    break;
            }
        }
    }
    

    JDBC

    Java Database Connectivity 是一个独立于特定数据库的管理系统,通用的SQL数据库存取和操作的公共接口。

    定义了一组标准,为访问不同的数据库提供了不同数据库提供了统一的途径。

    1591903568331

    JDBC体系结构

    JDBC接口包括两个层面:

    • 面向应用的API,提供程序员调用
    • 面向数据库API,供厂商开发数据库的驱动程序

    1591903683341

    JDBC API

    提供者:Java官方

    内容:共开发者调用的接口

    java.sql和jjavax.sql

    • DriverManager类
    • Connection接口
    • Statement接口
    • ResultSet接口

    DriverManager

    提供者:Java官方

    作用:管理不同的JDBC驱动

    JDBC驱动

    提供者:数据库厂商

    作用:负责连接不同的数据库

    JDBC的使用

    1. 加载数据库驱动,Java程序和数据库之间的桥梁
    2. 获取Connection,Java程序与数据库的一次链接
    3. 创建Statement对象,由Connection产生,执行SQL语句
    4. 如果需要接收返回值,创建ResultSet对象,保存Statement执行之后的所查询到的结果。

    PreparedStatement

    Statement的子类,提供了SQL占位符的功能

    使用Statement进行开发有两种问题:

    1. 需要频繁拼接String字符串,出错频率较高
    2. 存在SQL注入的风险

    SQL注入:利用某些系统没有对用户输入的信息进行充分检测,在用户输入的数据中注入非法的SQL语句,从而利用系统的SQL引擎完成恶意行为的做法

    数据库连接池

    JDBC开发流程:

    • 加载驱动(只需要加载一次)
    • 建立数据库连接(Connection)
    • 执行sql语句(Statement)
    • ResultSet接收结果集(查询)
    • 断开连接,释放资源

    数据库连接对象是通过DriverManager来获取的,每次获取都需要向数据库申请获取连接,验证用户和密码

    执行完SQL语句后断开连接,这种方式会造成资源的浪费,数据库资源没有得到很好的重复利用。

    可以用数据库连接池解决这一问题

    数据库连接池,就是为数据库建立一个缓冲池,预先向缓冲池中放入一定数量的连接对象,当需要获取数据库链接的时候,只需要从缓冲池取出一个对象,用完之后再放回到缓冲池中,供下一次请求使用,做到了资源的重复利用,允许程序重复使用一个现有的数据库连接对,而不需要重新创建。

    当数据库连接池中没有空闲的连接时,新的请求就会进入等待队列,等待其它线程释放连接。

    数据库连接池

    JDBC的数据库连接池使用java.sql.DataSourse接口来完成的,DataSourse是Java官方提供的接口,使用的时候开发者并不需要自己来实现该接口,可以用第三方工具,C3P0是一个第三方实现,实际开发中直接,使用C3P0ji'wan'cheng2是菊科连接池的操作。

    1. 导入jar架包。

      传统方式拿到的Connection

      com.mysql.cj.jdbc.ConnectionImp1@557caf28
      

      C3P0拿到的Connection

      com.mchange.v2.c3p0.impl.NewPeoxyConnection@4988d8b8
      
    2. public class DataSourceTest {
          public static void main(String[] args) {
      
              try {
                  //创建C3P0
                  ComboPooledDataSource dataSource = new ComboPooledDataSource();
                  dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
                  dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8");
                  dataSource.setUser("root");
                  dataSource.setPassword("123456");
                  Connection conn = dataSource.getConnection();
                  System.out.println(conn);
                  //返回到数据库池中
                  conn.close();
              } catch (PropertyVetoException e) {
                  e.printStackTrace();
              } catch (SQLException e) {
                  e.printStackTrace();
              }
          }
      }
      

      实际开发中,将c3p0的配置信息定义在xml文件中,Java程序只需要加载配置文件即可完成数据库连接池的初始化操作

      1. 配置文件的名字必须是c3p0-config.xml
      2. 初始化ComboPooledDataSource,传入的参数的必须是c3p0-config.xml中的named-config标签的name属性值。
      <?xml version="1.0" encoding="UTF-8" ?>
      <c3p0-config>
          <named-config name="testc3p0">
              <property name="user">root</property>
              <property name="password">123456</property>
              <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
              <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/test</property>
      
              <!-- 初始化连接池连接数量 -->
              <property name="initialPoolSize">5</property>
              <!-- 数据库连接池最小的数据库连接数 -->
              <property name="minPoolSize">5</property>
              <!-- 数据库连接池最大的数据库连接数 -->
              <property name="maxPoolSize">10</property>
              <!-- 连接数不足,一次向数据库服务器申请多少个链接 -->
              <property name="acquireIncrement">5</property>
      
          </named-config>
      </c3p0-config>
      
      public class DataSourceTest {
      public static void main(String[] args) {
          try {
              //创建C3P0
              ComboPooledDataSource dataSource = new ComboPooledDataSource("testc3p0");
              Connection conn = dataSource.getConnection();
              System.out.println(conn);
              //返回到数据库池中
              conn.close();
          } catch (SQLException e) {
              e.printStackTrace();
          }
      }
      }
      

    DBUtils

    DBUtils可以帮助开发者完成数据的封装(结果集到Java对象的映射)

    1. 导入架包

      ResultHandler接口是用来处理结果集,可以将查询到的结果集转换成java对象,提供了4

      中实现类

      • BeanHander 讲结果集映射成java对象Student
      • BeanListHandler 将结果集映射成List集合List
      • MapHandler 将结果集映射成Map对象
      • MapListHandler 将结果集映射成MapLsit结合
  • 相关阅读:
    MyBatis简介
    JDBC报错:Cannot find class: com.mysql.jdbc.Driver
    进程,线程,协程
    mamp提示 more elements...
    获取html页面的参数
    php基础函数
    返回接口
    生成订单号
    xml转数组
    判断是否是微信浏览器
  • 原文地址:https://www.cnblogs.com/itgopan/p/13932607.html
Copyright © 2011-2022 走看看