zoukankan      html  css  js  c++  java
  • javaweb快速复习笔记

    javaweb详解

    一.Tomcat

    Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。

    Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,当在一台机器上配置好Apache 服务器,可利用它响应HTML(标准通用标记语言下的一个应用)页面的访问请求

    1. javaWeb本体的目录

    bin:该目录下存放的是二进制可执行文件,如果是安装版,那么这个目录下会有两个exe文件:tomcat8.exe、tomcat8w.exe,前者是在控制台下启动Tomcat,后者是弹出UGI窗口启动Tomcat;如果是解压版,那么会有startup.bat和shutdown.bat文件,startup.bat用来启动Tomcat,但需要先配置JAVA_HOME环境变量才能启动,shutdawn.bat用来停止Tomcat;

    conf:这是一个非常重要的目录,这个目录下有四个最为重要的配置文件.
    server.xml:配置整个服务器信息。例如修改端口号,添加虚拟主机等;
    tomcat-users.xml:存储tomcat用户的文件,这里保存的是tomcat的用户名及密码,以及用户的角色信息。可以按着该文件中的注释信息添加tomcat用户,然后就可以在Tomcat主页中进入Tomcat Manager页面了;
    web.xml:部署描述符文件,这个文件中注册了很多MIME类型,即文档类型。这些MIME类型是客户端与服务器之间说明文档类型的,如用户请求一个html网页,那么服务器还会告诉客户端浏览器响应的文档是text/html类型的,这就是一个MIME类型。客户端浏览器通过这个MIME类型就知道如何处理它了。当然是在浏览器中显示这个html文件了。但如果服务器响应的是一个exe文件,那么浏览器就不可能显示它,而是应该弹出下载窗口才对。MIME就是用来说明文档的内容是什么类型的!
    context.xml:对所有应用的统一配置,通常我们不会去配置它。

    lib:存放了Tomcat软件启动运行的依赖jar文件. logs:这个目录中都是日志文件,记录了Tomcat启动和关闭的信息,如果启动Tomcat时有错误,那么异常也会记录在日志文件中。 temp:存放Tomcat的临时文件,这个目录下的东西可以在停止Tomcat后删除! webapps:存放web项目的目录,其中每个文件夹都是一个项目;如果这个目录下已经存在了目录,那么都是tomcat自带的项目。其中ROOT是一个特殊的项目,在地址栏中没有给出项目目录时,对应的就是ROOT项目

    work:工作目录,存放了jsp翻译成Servlet的java文件以及字节码文件.


    1.将目标项目直接打成war包,然后放入webapp中.Tomcat会将war包自动解开.

    i 将一个项目打成zip文件.

    image-20200606095033517

    ii 移动到webapp中

    image-20200606095134968

    我们可以看到已经自动解压缩了.

    2.config目录下的server.xml中设置

    image-20200606100730347

    进入其中,在里面加入这样一个句子

    image-20200606100845023

    • docBase:你 项目所在的地点.

    • path:你项目的外部访问路径,即从浏览器中输入什么内容,可以访问到.

    • ex:

      image-20200606101032449

    这个就是就是因为配置了初始页面,所以会是这个样子.这个到后面再说.你只要知道设path的内容被添加到localh0st:8080之后.

    3.在confCatalinalocalhost创建任意名称的xml文件

    image-20200606102450514i. 在文件中编写 比如 bbb.xml
    此时的path虚拟目录就为xml文件的名称

    image-20200606102601503

    Tomcat和idea融合

    1.我们需要创建javaEE项目

    image-202006061027479712.有红色标记部分,都可以达成下一步目标.

    image-20200606103051187

    3.打开Template

    image-20200606103133848

    4.进行进一步配置(里面的内容可以没用前后顺序)

    image-20200606103614213

    5.配置完后开始加入模块

    image-20200606103733956

    6.对于模块进行配置

    image-20200606103714837

    一顿继续就ok了.

    配置完成.

    有可能出现一个小BUG,就是在更改完

    image-20200606104534301

    如上的URL之后,会导致一启动,就报404错误.

    image-20200606104620771

    其主要原因就在于没有配置另一个部分.

    image-20200606104708046

    如下.这个就是上面我们手动配置时候,输入的那个path,如果他对不上,前面怎么访问都访问不到.

    以上的内容就是配置阶段的内容.比较简略,照着做可能会出现bug.但是不要担心,作为初学阶段,这些BUG大多不会太难.

    可以靠手动重启Tomcat(到bin文件夹中点击start_upshutdowm来完成目标)

    下面这个部分就是关于Servlet的操作.

    Servlet

    入门案例

    servlet实际上是一个接口.

    sun公司定义了一套专门用于开发Servlet程序的类和接口,统称为ServletAPI

    所有的Servlet类都必须实现Servlet接口.

    即如下情况所示.

    import javax.servlet.*;
    import java.io.IOException;
    
    public class MyServlet implements Servlet {
        @Override
        public void init(ServletConfig servletConfig) throws ServletException {
            System.out.println("init()执行");
        }
    
        @Override
        public ServletConfig getServletConfig() {
    
            return null;
        }
    
        @Override
        public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
            System.out.println("service执行");
        }
    
        @Override
        public String getServletInfo() {
            return null;
        }
    
        @Override
        public void destroy() {
            System.out.println("销毁");
    
        }
    }
    
    

    因为Servlet函数实际上是由服务器(实际上是Servlet引擎(容器))调用的,光写一个类可没什么效果,我们还要进行配置.

    如下内容:

    如下的内容再WEB.XML中进行配置.

    要是你没配置WEB.XML,那么就去WEB-INF下面配置一个

    //这个部分配置的是servlet程序得名字和相对路径
    <servlet>
      //一个名字,用来再WEB.XML中使用.他将在WEB.XML代表<servlet-class>中的内容
        <servlet-name>Myservlet</servlet-name>
      //相对路径
        <servlet-class>MyServlet</servlet-class>
    </servlet>
      //servlet映射部分.将servlet映射到一个URL地址上.
     <servlet-mapping>
      //servlet在上面那个部分设置得名字,
            <servlet-name>Myservlet</servlet-name>
       //url地址
            <url-pattern>/Myservlet</url-pattern>
        </servlet-mapping>
    

    img

    这是一个具体的原理.

    从这里引用

    当然,本着操作和实践分离得原则.这里不会具体讲解.

    另外可以用一个<load-on-startup>对servlet程序进行设置.

    负数第一次访问时创建
    正数服务器启动时创建

    当然,默认得话还是第一次访问的时候才创建得.

    ServletConfig类

    首先一个ServletConfig类对应着一段web.xml中配置的Servlet信息;也就是说我们配置的Servlet信息都会被Tomcat解析后,将配置信息的数据保存在ServletConfig类中.所以一个ServletConfig类只对应一段Servlet信息.

    在这里插入图片描述

    因为只传入init()方法中,所以也只能在init()方法中使用.

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        //这个再服务器启动的过程中只会执行一次
        System.out.println("init()执行");
        //servletConfig对象会在Tomcat调用service时被传入.这个里面时各种各样的内容
        //得到<servlet-name>
        String servletName = servletConfig.getServletName();
        System.out.println(servletName);
        //得到初始化配置,按照值获取
        String namespace = servletConfig.getInitParameter("namespace");
        System.out.println("servletConfig.getInitParameter("namespace");"+namespace);
        //得到初始化配置,全部获取
        Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
     while (initParameterNames.hasMoreElements())
         System.out.println(initParameterNames.nextElement());
     //
        }
    

    这是整个句子.

    另外我们再WEB.XML中的代码也有了一部分改变.

    
    <servlet>
        <servlet-name>Myservlet</servlet-name>
        <servlet-class>MyServlet</servlet-class>
      //增加的部分
        <init-param>
            <param-name>namespace</param-name>
            <param-value>1234</param-value>
        </init-param>
    </servlet>
        <servlet-mapping>
            <servlet-name>Myservlet</servlet-name>
            <url-pattern>/Myservlet</url-pattern>
        </servlet-mapping>
    

    执行结果如下

    init()执行  <---init方法部分
    
    
    
    MyServlet  <---getServletName();
    1234  <--getInitParameter("namespace")
    namespace  <---getInitParameterNames();
    
    ----------------------------service方法部分
    service执行 <--service
    

    当然这么配置明显太过于费事,我们可以用简单一点的方式解决这个问题

    注解

    @WebServlet(value = "/Myservlet",initParams = {
      //value等同于  <servlet-mapping>中<servlet-name>配置的东西.
      //类名可以直接获取...不必映射,所以这个配置就可以了
            @WebInitParam(name="namespace",value = "1234")
      //WebInitParam等同于<init-param>内容,里面的name和value必须写
    })
    public class MyServlet implements Servlet {
        @Override
        public void init(ServletConfig servletConfig) throws ServletException {
            //这个再服务器启动的过程中只会执行一次
            System.out.println("init()执行");
            //servletConfig对象会在Tomcat调用service时被传入.这个里面时各种各样的内容
            //得到<servlet-name>
            String servletName = servletConfig.getServletName();
            System.out.println(servletName);
            //得到初始化配置,按照值获取
            String namespace = servletConfig.getInitParameter("namespace");
            System.out.println("servletConfig.getInitParameter("namespace");"+namespace);
            //得到初始化配置,全部获取
            Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
         while (initParameterNames.hasMoreElements())
             System.out.println(initParameterNames.nextElement());
         //
            }
    

    有了注解之后XML文件就可以不用了.

    当然,加入注解后要在XML文件中进行一个小设置,才会生效.

    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0"
             
             <--如下这句-->
        metadata-complete="false"
          false的意思是不忽略注解
          true的意思是忽略注解
    >
    

    ServletContext

    ServletContext对象,tomcat为每一个web项目单独创建的一个(ServletContext)上下文(知上知下贯穿全文)对象。服务器启动的时候,为每个WEB应用创建一个单独的ServletContext对象,我们可以使用这个对象存取数据,用这个对象存取的数据,可以在整个WEB应用中获取.

    服务器会为每个应用创建一个ServletContext对象:

    ServletContext对象的创建是在服务器启动时完成的;
    ServletContext对象的销毁是在服务器关闭时完成的。

    版权声明:本文为CSDN博主「White Camel」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/m0_37989980/java/article/details/104088452

    在这里插入图片描述

    这样的话就可以在不同的Servelt之间进行传递操作.

    1.多个servlet之间共享数据

    setAttribute(String name,Object object) 向ServletContext中存数据
    getAttribute(String name) 从ServletContext中取数据
    removeAttribute(name) 从ServletContext中移除数据

    这个例子会有两个Servlet程序,用来完成在两个Servlet之间传递的模拟.

    发送的servlet程序

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        //每次访问都会执行一次
        System.out.println("service执行");
           servletRequest.getServletContext().setAttribute("name",1);
    
    }
    

    接收的servlet程序

    @WebServlet("/ScopeServlet")
    public class ScopeServlet extends HttpServlet {
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            super.service(req, resp);
            //获取ServletContext得到其中的name属性
            int name =(Integer) req.getServletContext().getAttribute("name");
            System.out.println(name);
            //删除name属性
            req.getServletContext().removeAttribute("name");
            //再次寻找,看是否找得到
            Object name1 = req.getServletContext().getAttribute("name");
            System.out.println(name1);
        }
    }
    

    返回的结果是

    1   <--值就是1
    null <--因为以前删掉了,所以找不到
    

    二、获取当前WEB项目中的指定资源(文件)

    既然 ServletContext 是 贯穿全文 的对象 ,所以项目中的资源 它都能访问到 , 主要用它获取web项目中文件.

    文件保存的位置 :
    1.src下 : 发布到 /WEB-INF/classes/文件名
    2.web目录下 : 发布到/文件名
    3.WEB-INF目录下 : 发布到 /WEB-INF/文件名

    例子:

     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        super.doPost(req, resp);
            ServletContext servletContext = req.getServletContext();
            String realPath = servletContext.getRealPath("/MyServlet");//获取绝对路径
            //在这里我们用的都是相对路径
            System.out.println(realPath);
    
    
        }
    

    结果如下:

    C:Users22643DownloadsAAA	estoutartifacts	est1_war_explodedMyServlet
    

    三、获取应用初始化参数

    注意这个和上面我们配置的那个参数不是一码事.所以...

    我们使用

    <context-param>
    

    来进行设置.这个是每个servlet都可以使用的一个属性

    servletContext.getInitParameter

      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        super.doPost(req, resp);
            ServletContext servletContext = req.getServletContext();
            String namespace = servletContext.getInitParameter("namespace");
            System.out.println(namespace);
        }
    

    转发重定向

    这里只讲解一下实现方式,对于其原理并不讲解.(将来会补上)

    接收端

        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
            System.out.println("到了本页");
            req.setAttribute("name","yan");
          //req域,调用getRequestDispatcher("/目标地址").forward(req,resp);req是自己这个
            req.getRequestDispatcher("/ScopeServlet").forward(req,resp);
    
        }
    

    发送端

     protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //        super.service(req, resp);
    
            String name = (String)req.getAttribute("name");
            System.out.println(name);
        }
    

    还有就是重定向

    发送端

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
      //可以跳转到另一个界面.
        resp.sendRedirect("ScopeServlet");
    
    }
    

    接收端

        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
            System.out.println("到了本页");
            String name = (String)req.getAttribute("name");//没效果
            System.out.println(name);//null
    }
    

    request

    request的方法个人认为分为两个部分

    一个部分是是对于url?前的部分进行操作.

    另一个是对url?后的部分进行操作

    http://localhost:8080/Myservlet ?   username=123&password=321
    对于前面那个部分的操作                 对于后面这个部分的操作
    
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     String getMethod(): 返回请求方式(GET/POST)
    String getRequestURI():返回请求行中资源名字部分: 如/test/index.html
    StringBuffer getRequestURL():返回浏览器地址栏的内容
    String getContextPath():获取上下文路径(虚拟目录),
      <Context path=“上下文” …/>
    String getRemoteAddr():返回请求服务器的客户端的IP地址
    String getHeader(String headName):根据指定的请求头获取对应的请求头的值.
        System.out.println(req.getMethod());
        System.out.println(req.getRequestURL());
        System.out.println(req.getRequestURL());
        System.out.println(req.getContextPath());
        System.out.println(req.getRemoteAddr());
        System.out.println(req.getHeader("User-Agent"));
    }
    
    GET
    http://localhost:8080/test1/Myservlet
    http://localhost:8080/test1/Myservlet
    /test1
    0:0:0:0:0:0:0:1
    Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36 Edg/83.
    

    然后是后面那个部分

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
     String getParameter(String name):根据参数名称,获取对应参数的值.
    String[] getParameterValues(String name):根据参数名称,获取该参数的多个值.
    Enumeration<String> getParameterNames(): 获取所有请求参数的名字
    Map<String,String[]> getParameterMap():返回请求参数组成的Map集合.
    key:参数名称
    value:参数值,封装在String数组中.
    
        //String getParameter(String name):根据参数名称,获取对应参数的值.
        System.out.println(req.getParameter("username"));
      //String[] getParameterValues(String name):根据参数名称,获取该参数的多个值.
        String[] usernames = req.getParameterValues("username");
        System.out.println(usernames[0]);
      //Enumeration<String> getParameterNames(): 获取所有请求参数的名字
        Enumeration<String> parameterNames = req.getParameterNames();
        while(parameterNames.hasMoreElements()){
            String s = parameterNames.nextElement();
            System.out.print(s+"    ");
        }
      //Map<String,String[]> getParameterMap():返回请求参数组成的Map集合.
        Map<String, String[]> parameterMap = req.getParameterMap();
    
        String[] passwords = parameterMap.get("password");
        System.out.println(passwords[0]);
    
    }
    

    其中如果使用post方法就会出现乱码错误.那么最好的办法就是

    如下处理办法.

     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //正常获取  
       String username = req.getParameter("username");
            System.out.println(username);
       //将其转换为"ISO-8859-1"的字节码.
            byte[] bytes = username.getBytes("ISO-8859-1");
            System.out.println(bytes);
       //将其翻译成"UTF-8"的String类型
             String username2=new String(bytes,"UTF-8");
            System.out.println(username2);
    
        }
    
    

    还有更简单的

     // 对于POST请求 可以设置请求的编码
     req.setCharacterEncoding("UTF-8");
     String username = req.getParameter("username");
     System.out.println(username);
    
  • 相关阅读:
    消息摘要算法示例(python和go)
    试设计代码生成器模式[初步]
    Webb.WAVE.Controls.Upload2已经完成,正在测试中。
    QuickGuide for AJAX[简译AJAX快速指南]以及对现有WebService的扩展。
    WebbUpload2测试版--HTTP协议下,用IE上传大文件解决方案,[附源码]
    [转]在APACHE上运行asp.net
    一段比较经典的多线程学习代码
    Catch the star that will take you to your dream摘取命运的启明星
    ASP.net页面上的默认Submit按钮!
    [转]Ajax在Sun上的理论
  • 原文地址:https://www.cnblogs.com/yanzezhong/p/13056293.html
Copyright © 2011-2022 走看看