Tomcat部署

1.客户端和服务器端的交互过程

客户端发送请求给服务器 由服务器中的服务器软件拦截请求 根据请求调动相应的Java业务逻辑执行相关的处理 我们前面知道Java代码的运行势必提前将其装载在JVM上 而服务器软件一般都是由Java代码编写 所以两者都要装载在JVM上 而Java业务逻辑装载在服务器软件上
在这里插入图片描述

2.Tomcat的下载、安装

Tomcat开源、免费 所以我们选择他作为我们的服务器软件
可以Tomcat官网上下载
注意:Tomcat版本应和jdk版本相对应 否则到时候Tomcat启动会出现闪退现象 比如我的jdk是8版本的 那么我就得下载10.0.x的tomcat版本
在这里插入图片描述
找到对应的Tomcat版本进行下载 有两样东西需要下载 分别为
在这里插入图片描述
只要你将Core中的zip文件解压完成 就表示Tomcat安装好了
接下来就要完成Tomcat启动的必要条件 就是一些环境变量的配置 由于我们启动Tomcat的文件为Tomcat安装路径下的bin目录中的startup.bat 而startup.bat中访问了CATALINA_HOME(本质上就是调用了同bin目录下的catalina.bat) 而catalina.bat中又访问了JAVA_HOME(具体就是调用了JAVA_HOME下bin目录中的javaw来启动JVM 由于Tomcat服务器是由Java编写 而Java程序的启动前提是启动JVM) 所以这两个基路径我们都得配置到环境变量中
而具体的配置操作就是在用户变量中设置JAVA_HOME(变量值为Java的安装路径)和CATALINA_HOME(变量值为Tomcat的安装路径) 然后在Path中配置javaw和catalina.bak安装路径(通过例如%CATALINA_HOME%\bin的格式进行路径的书写)
在这里插入图片描述
在这里插入图片描述

这些路径都配置好了以后 我们接下来就要开始启动Tomcat服务器软件了

3.Tomcat的启动、关闭

启动Tomcat:
1.双击bin目录下的startup.bat
2.通过cmd窗口先切换到bin目录 然后打开startup.bat
3.startup本质上是调用的catalina 所以可以通过cmd窗口先切换到bin目录 然后打开catalina.bat 但是这个和startup.bat的打开方式稍微有点不同的是 他需要run参数 也就是在具体路径之后添加run参数
关闭Tomcat:
1.双击bin目录下的shutdown.bat
2.通过cmd窗口先切换到bin目录 然后打开shutdown.bat
3.startup本质上是调用的catalina 所以我们可以先通过cmd窗口切换到bin目录 然后访问catalina.bat 但是这个依旧和shutdown.bat的打开方式有所不同 他需要stop参数 也就是在具体路径之后添加stop参数
(以上操作需要注意的是:1.bat等后缀名可以省略 2.cmd窗口支持自动补全操作 也就是面对一些长路径可以通过补全功能来自动补齐 3.我们可以通过向服务器发送localhost:8080请求 如果服务器返回指定的tomcat页面 就证明我们的Tomcat启动成功 反之就是启动失败或者关闭)

4.Tomcat的集成

但是如果向上述操作那样每次都要依靠双击或者命令行窗口启动或者关闭Tomcat的话 未免有些麻烦 所以我建议就是将Tomcat集成到idea中 这样就不要每次都如此麻烦的进行启动和关闭操作了
具体的集成步骤就是:
在创建项目界面打开Configuration->settings->Application Servers->±>Tomcat Server->选择你的Tomcat安装路径->ok->创建新项目(Java Enterprise 记得勾选Web Application)
在这里插入图片描述

5.模拟客户端和服务器之间的数据传输

在模拟之前 我们要明白一些事情
在Java EE中 src一般用于存放Java文件 而web则用于存放一些资源文件 比如:html文件、css文件、图片等等
热部署就是我们修改部署在服务器软件上的Java代码 然后该份代码就会自动重新加载到我们的服务器软件上 而我们的idea并非热部署 所以我们需要手动重新加载我们所修改的文件

我们可以先行在web创建一个login.html文件 里面写上一些文字
在这里插入图片描述
然后建议将Application context修改一下 默认的名字过长
在这里插入图片描述
接着我们就可以开始测试 建议通过debug模式运行
在这里插入图片描述
运行之后 他默认会打开我们部署项目的路径 然后我们就通过该路径打开项目中的指定文件即可
在这里插入图片描述
在这里插入图片描述
如果我们的代码修改了 idea并非热部署 所以我们在点击debug运行按钮时 他会有四个力度的选项以供选择 帮助我们重新加载代码
在这里插入图片描述
在这里插入图片描述

6.路径解析

我们作为客户端向服务器发送的网址为localhost:8080/hello/login.html 然后服务器就会返回一个登陆界面给我们
现在我们来解析一下这个网址
localhost/127.0.0.1:本机地址 这一部分表示服务器软件所在的主机地址 由于服务器软件在本机 所以这边填的是本机地址 他用于定位服务器
8080:端口号 一台服务器上有多个服务器软件 这时候需要端口号来定位服务器软件
hello:一个服务器软件上有多个项目 hello用于定位项目
login.html:就是项目中的某个文件

7.一个窗口存放多个项目

如果按照普通的方式 那么一个窗口只能存放一个项目
如果想要一个窗口存放多个项目的话 那么就可以通过新建空项目->创建子模块的方式实现(注意:创建下一模块的时候 不要选中前一个模块 选中其他文件即可)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这样就实现了同一窗口中存放多个项目的目的了 接着我们可以去修改一下他们的Application context 使得访问路径更为简便
在这里插入图片描述
接着我们通过debug运行 为了检测客户端和服务器之间数据传输是否稳定 我们可以在两个项目中各自创建html文件 然后在浏览器中访问指定的html文件 如果返还指定界面 则说明数据传输成功
在这里插入图片描述
成功
通过以下界面 我们可以知道 其实我们的debug/正常运行都是调用的tomcat bin目录下的catalina.bat run 而关闭则调用的是bin目录下的catalina.bat stop
我们可以到
我们可以看到 无论是通过idea还是tomcat打开的服务器软件 都有中文乱码现象 这是因为编解码不一致导致的问题
我们查看tomcat的日志文件可以发现该服务器软件的编码方式采用的是UTF-8 而解码方式采用的则是GBK 因此出现了中文乱码现象 我们只需要将日志文件中的UTF-8改成GBK即可
日志文件为logging.properties
在这里插入图片描述
我们在重新启动一下 中文乱码现象消除了

8.注意

1.对于一个模块 如果你点击默认的删除 那么他仅仅只是删除项目外层的模块 并没有删除项目 如果想要真正删除项目的话 得到其所在的文件去删除才行
2.我们在idea中开启tomcat以后默认打开的文件为web文件夹下的index.jsp

9.处理表单数据

我们刚才讲的客户端和服务器之间的交互是比较简单的操作 即客户端发送请求 服务器返还一个页面
当然客户端也可以提交表单 让服务器判断 并且返回判断结果(如果我们发送的是get请求 那么服务器就会执行doGet操作去处理我们的get请求 post也一样)
在Java EE中我们的Java类一般都为Servlet类 并且我们可以通过WebServlet对Java文件进行定位(Java文件可能有多个)

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
// 这是对该Java文件的一个定位
@WebServlet("/login")
public class LoginServlet extends HttpServlet {// 继承自HttpServlet表明这个逻辑处理的是http请求
	// 以下是对两种不同的请求方式的处理逻辑
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("LoginServlet - doGet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("LoginServlet - doPost");
    }
}

类型为submit的按钮点击以后 才能够将表单数据提交给服务器 其他类型不能完成类似操作 提交的对象由form元素的action属性决定 其属性值为ip地址/端口号+显式的属性值 如果action只写作/login的话 那么就会404

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/hello3/login">
    <div>账号 <input type="text"></div>
    <div>密码 <input type="text"></div>
    <div><button type="submit">登录</button></div>
</form>
</body>
</html>

在这里插入图片描述
在这里插入图片描述
刚才我们完成的是对于客户端的请求我们在控制台中作出反应 接下来我们就要由服务器对客户端进行一个响应操作了 也就是拿到客户端的表单数据 根据不同的判断做出不同的响应(表单数据有多个 可以通过name属性来定位表单数据)
我们可以为所调用的方法快速生成变量进行接收 修改其快捷键 我这边设置的为alt + s

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("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if(username.equals("123") && password.equals("123")){
            resp.getWriter().write("Login Success");
        }else{
            resp.getWriter().write("Login Failed");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("LoginServlet - doPost");
    }
}

通过name属性可以定位表单数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/hello3/login">
    <div>账号 <input type="text" name="username"></div>
    <div>密码 <input type="text" name="password"></div>
    <div><button type="submit">登录</button></div>
</form>
</body>
</html>

运行结果如下所示(可见 他将我们的表单数据以name属性值的形式拼接到发送的请求之后 并且服务器成功将反馈会先到客户端的页面上)
在这里插入图片描述

我们的debug运行也有快捷键 我们可以将默认的快捷方式修改为alt + d
我们的edit configuration也存在快捷键 我们可以将默认的快捷方式修改为alt + e
由于我们的debug打开以后默认的选项为第二个 而第三个我觉得是最合适的重新加载方式 所以我将默认的打开方式修改为redeploy

10.请求和响应的数据为中文的四种情况

1.请求数据为中文、请求方式为get

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("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username + "_" + password);
        if(username.equals("123") && password.equals("123")){
            resp.getWriter().write("Login Success");
        }else{
            resp.getWriter().write("Login Failed");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/hello3/login" method="get">
    <div>账号 <input type="text" name="username"></div>
    <div>密码 <input type="text" name="password"></div>
    <div><button type="submit">登录</button></div>
</form>
</body>
</html>

在这里插入图片描述
在这里插入图片描述
结果是不会出现中文乱码

2.请求数据为中文、请求方式为post

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("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username + "_" + password);
        if(username.equals("123") && password.equals("123")){
            resp.getWriter().write("Login Success");
        }else{
            resp.getWriter().write("Login Failed");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/hello3/login" method="post">
    <div>账号 <input type="text" name="username"></div>
    <div>密码 <input type="text" name="password"></div>
    <div><button type="submit">登录</button></div>
</form>
</body>
</html>

在这里插入图片描述
在这里插入图片描述
可以看到 结果出现了中文乱码现象
为了解决中文乱码 我们需要通过setCharacterEncoding来设置解析请求数据的编码方式(浏览器的默认编码方式为UTF-8 所以这里我们设置的解码方式应为UTF-8)

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("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username + "_" + password);
        if(username.equals("123") && password.equals("123")){
            resp.getWriter().write("Login Success");
        }else{
            resp.getWriter().write("Login Failed");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

这样就能够解决请求数据为中文、请求方式为post时的中文乱码现象了

3.响应数据为中文、请求方式为get

该情况下响应数据显示返还给客服端出现了中文乱码现象 通过setContentType避免乱码

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/hello3/login" method="get">
    <div>账号 <input type="text" name="username"></div>
    <div>密码 <input type="text" name="password"></div>
    <div><button type="submit">登录</button></div>
</form>
</body>
</html>
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("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username + "_" + password);
        resp.setContentType("text/plain;charset=utf-8");
        if(username.equals("123") && password.equals("123")){
            resp.getWriter().write("登录成功");
        }else{
            resp.getWriter().write("登录失败");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

在这里插入图片描述

4.响应数据为中文、请求方式为post

这种情况依旧出现了中文乱码现象 我们仍然通过setContentType方式进行乱码现象的规避

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/hello3/login" method="post">
    <div>账号 <input type="text" name="username"></div>
    <div>密码 <input type="text" name="password"></div>
    <div><button type="submit">登录</button></div>
</form>
</body>
</html>
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("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username + "_" + password);
        resp.setContentType("text/plain;charset=utf-8");
        if(username.equals("123") && password.equals("123")){
            resp.getWriter().write("登录成功");
        }else{
            resp.getWriter().write("登录失败");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

在这里插入图片描述

5.注意

1.doGet和doPost的逻辑相近 所以可以让其中一个调用另外一个
2.设置编码方式的时机都是在发送/接收数据之前(浏览器默认的编解码方式都是UTF-8)
3.两种请求方式
get:会将请求参数拼接到请求路径之后 有请求头
post:会将请求参数放在请求体中 有请求头
get会将请求参数暴露出来 而post不会 post方式较为安全
4.setContentType接收的参数为text/plain;charset=utf-8 前面部分为MINEType(文本的MINEType就为text/plain 图片的MINEType为image/png) 后面部分则是编码方式
我们通过setCharacterEncoding设置请求数据的编码方式 通过setContentType设置响应数据的内容类型(MINEType + 编码方式)
5.idea中resume program可以恢复代码的执行 直到遇到下一个断点为止
在这里插入图片描述
6.上述四种情况的统一代码如下所示(把resp.getWriter抽取出来提高复用率)

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;
import java.io.PrintWriter;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username + "_" + password);
        resp.setContentType("text/plain;charset=utf-8");
        PrintWriter out = resp.getWriter();
        if(username.equals("123") && password.equals("123")){
            out.write("登录成功");
        }else{
            out.write("登录失败");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

11.响应数据为html界面

前面我们的案例中响应数据为文本 但是真实的情况中 响应数据为html界面 所以我们要实现一下这个效果
如何实现呢 其实就是将原来输出流输出的内容改成html的内容 并且一行行输出 注意MINEType要设置为html对应的类型 这是在告诉浏览器我的响应数据是什么 让其以什么方式解析 html的MINEType为text/html

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;
import java.io.PrintWriter;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        outHtml(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
    private void outHtml(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 在接收请求数据之前要先设置编码方式
        req.setCharacterEncoding("UTF-8");
        // 通过name属性定位到指定表单数据
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        // 设置输出流、发送响应数据之前先设置内容类型(MINEType+编码方式)
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        // 判断表单数据是否合理 不同的判断执行不同的操作
        if(username.equals("123") && password.equals("123")){
            out.write("<h1>登录成功</h1>");
            out.write("<ul>");
            out.write("<li>个人信息</li>");
            out.write("<li>修改密码</li>");
            out.write("<li>退出登录</li>");
            out.write("</ul>");
        }else{
            out.write("<h1>登录失败</h1>");
            out.write("<ul>");
            out.write("<li>重新登录</li>");
            out.write("</ul>");
        }
    }
    private void outText(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username + "_" + password);
        resp.setContentType("text/plain;charset=utf-8");
        PrintWriter out = resp.getWriter();
        if(username.equals("123") && password.equals("123")){
            out.write("登录成功");
        }else{
            out.write("登录失败");
        }
    }
}

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

axihaihai

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值