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.在conf\Catalina\localhost创建任意名称的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:\Users\22643\Downloads\AAA\test\out\artifacts\test1_war_exploded\MyServlet

三、获取应用初始化参数

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

我们使用

<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);
posted @ 2020-06-06 20:35  TimothyRasinski  阅读(845)  评论(0编辑  收藏  举报