idea 与 Tomcat 有一个美妙的约定

  • IntelliJ IDEA 2020.1.2
  • Tomcat 9.0.37

文章目录

  • 一:Web 容器
  • 二:下载 Tomcat
    • Tomcat 容器的文件夹结构
  • 三:将 Tomcat 和 IDEA 集成在一起
  • 四:运行Tomcat后,IDEA控制台出现乱码
    • 方法一
    • 方法二
  • 五:用idea创建第一个Web项目
    • 编写与访问静态资源
    • 编写与访问操作资源
  • 六:其余设置
    • 发送请求的时候,如果只写项目名,不写资源名会怎么样
    • idea通过Tomcat创建web项目,导包时要注意的问题
    • 将idea项目真正部署到Tomcat文件夹下的操作
  • 七:Tomcat9容器对get和post请求的字符集处理

一:Web 容器

  • Tomcat
    Apache 组织开源免费容器,管理 web 项目资源(文件内容,操作资源结果)
  • Jetty
  • Resin
    Caucho公司一个产品
  • JBoss,WebLogic,WebSphere

Web项目主要有三种:

  1. Servlet
  2. JSP
    在响应信息的时候做拼装和组装,是一个模板模型,本质上还是Servlet
  3. HTML+CSS+Javascript

二:下载 Tomcat

Tomcat下载,选择所需版本点击 Download 即可
idea 与 Tomcat 有一个美妙的约定_第1张图片
注意:Tomcat下载下来,解压之后,是不需要安装的,是绿色版

我都下载了,下面那个(-src)是包含源码的
在这里插入图片描述

Tomcat 容器的文件夹结构

idea 与 Tomcat 有一个美妙的约定_第2张图片

  • bin文件夹(服务器启动相关的配置)
  • conf文件夹(configuration配置文件,例如:web.xml(请求相关) ,server.xml(容器自身的信息 比如端口))
  • java文件夹(Tomcat的源码,如果下载的是带有源码的Tomcat,会带有这个文件)
  • lib文件夹(jar形式的包)
  • logs文件夹(日志信息)
  • temp文件夹(临时文件)
  • webapps文件夹(用来存放部署在容器内的项目资源的)
    即:将我们写的项目的所有资源都存放在Tomcat容器中(eclipse是这么做的);
    如果使用的开发环境是idea,那么有一点不一样(idea部署过去的不是真实的项目资源,部署过去的是一个引用路径,告诉Tomcat容器通过这个路径来找项目资源)
  • work文件夹(用来存放解析JSP后形成的java文件)
    JSP(本质上就是Servlet)里面包含的是Java代码和HTML,即同时包含了静态资源和动态资源,浏览器是不认识的,所以Tomcat要把JSP做一个解析,然后把解析后的文件传给浏览器

三:将 Tomcat 和 IDEA 集成在一起

  • 如果集成了该插件:打开idea > Run > Edit Configurations > + > Tomcat Server > Local
    idea 与 Tomcat 有一个美妙的约定_第3张图片
    idea 与 Tomcat 有一个美妙的约定_第4张图片
    idea 与 Tomcat 有一个美妙的约定_第5张图片
  • 若IDEA中缺少相关的插件(上面的选项没有找到),去安装即可
    打开idea > File > Settings > Plugins > Installed > 勾选Tomcat and TomEE Integrationidea 与 Tomcat 有一个美妙的约定_第6张图片

四:运行Tomcat后,IDEA控制台出现乱码

基本上大家安装的windows系统本地语言都是选择中文(也就是GBK编码)
而IDEA或者Tomcat日志使用的是UTF-8编码,这就导致了中文显示乱码。

首先确定一下idea的字符集有没有问题:打开idea > File > Settings > Editor > File Encodings
idea 与 Tomcat 有一个美妙的约定_第7张图片
确认idea项目的编码字符集没有问题后,
有两种方法,但是他们是互相冲突的,请不要一起设置!!!

方法一

  • 修改IDEA安装目录bin文件夹中的配置文件
    1. idea安装根路径\bin 路径下找到两个文件:idea.exe.vmoptions文件、idea64.exe.vmoptions
    2. 这两个文件都使用记事本打开,添加一行内容 -Dfile.encoding=UTF-8,如果没有解决问题,再添加一行 -Dconsole.encoding=UTF-8
  • 如果不行,继续:配置Tomcat容器的时候做参数处理
    1. 打开 idea > Run > Edit Configurations > server > VM options > 添加一行内容-Dfile.encoding=UTF-8
    2. 打开 idea > Run > Edit Configurations > Startup/Connection> 勾选 Pass environment variables
      idea 与 Tomcat 有一个美妙的约定_第8张图片

方法二

如果方法一没有彻底解决问题,请先将方法一的设置清除,然后

  • Tomcat根路径\conf> 记事本打开 logging.properties 文件,将UTF-8全部改为GBK
    idea 与 Tomcat 有一个美妙的约定_第9张图片

补充:经过实践证明,与请求相关的字符集问题,无论是哪种请求,只要在控制层的方法中请求与响应都使用 setCharacterEncoding("UTF-8"); 方法可以解决99%的问题。有兴趣的可以看看本文目录七

五:用idea创建第一个Web项目

(1)使用idea创建Web项目
idea 与 Tomcat 有一个美妙的约定_第10张图片
(2)项目结构的变化
idea 与 Tomcat 有一个美妙的约定_第11张图片

  • 这个web文件夹是用来存储所有跟网页相关的资源的
  • Java代码还是放在src文件夹中

(3)在运行前,首先确定一下配置:Run > Edit Configurations > Deployment,顺便改一下服务器项目名称
idea 与 Tomcat 有一个美妙的约定_第12张图片

编写与访问静态资源

在web文件夹中创建一个html文件,随便写点东西进去:
idea 与 Tomcat 有一个美妙的约定_第13张图片
通过这个下面这个url可以访问到我刚刚创建的test.html文件
idea 与 Tomcat 有一个美妙的约定_第14张图片

  • http://localhost:8080/ 代表资源定位符
  • untitled 是项目名称,可以通过 Run > Edit Configurations > Deployment 修改
  • 通过Tomcat搭建一个环境,将项目写进去,我们就可以通过浏览器成功访问到项目中的文件资源(例如:test.html),Tomcat服务器找到了对应的文件资源(test.html),返回给浏览器,浏览器认识这个test.html文件,浏览器对这个html文件进行解析之后显示在界面上

编写与访问操作资源

. .
V :View 视图层(HTML+CSS+JS)
C:Controller 控制层(Java:HttpServlet类,一个规则)
M:Model 模型层(数据处理service,数据读写dao,数据存储domain)
DB:DataBase 数据库(我一般使用的是MySql)

如何在Tomcat中自己编写一个Java类(控制层Servlet)

  1. 自己定义一个类
  2. 继承Tomcat提供的一个规则HttpServlet(接口),重写一个方法service,方法内部有两个参数HttpServletRequest,HttpServletResponse,抛出两个异常ServletException,IOException,无返回值
  3. 填写配置文件web.xml,web > WEB-INF > web.xml,目的是配置请求名字与真实类名的对应关系
    idea 与 Tomcat 有一个美妙的约定_第15张图片

注意:web.xml文件有两个,

  • 一个是上面所说的项目中的web.xml,存放我们自己写的配置
  • 另一个在Tomcat根路径下conf文件夹中的web.xml,存放通用的配置

实例演示
第一步:创建一个类,继承HttpServlet

idea 与 Tomcat 有一个美妙的约定_第16张图片
第一步补充:如果发现这个类导不进来:File > Project Structure > Modules > Dependencies
idea 与 Tomcat 有一个美妙的约定_第17张图片
idea 与 Tomcat 有一个美妙的约定_第18张图片
第二步:填写web.xml配置文件(告诉Tomcat服务器,我有一个类需要你管理)
idea 与 Tomcat 有一个美妙的约定_第19张图片
我们若要在web.xml文件中添加配置,要写在 web-app 标签里面
写一个servlet类,要配置8行:

先把流程捋一遍:

  1. Tomcat容器先启动,等待浏览器进行访问
  2. 浏览器发送请求---->http://localhost:8080/untitled/test
  3. Tomcat启动一个线程Handler(1. 读取请求协议URL,得到test请求名字和参数---->2. 解析test请求名字和参数,包装成一个对象HttpServletRequest,为了让控制层执行后的结果能获取回来,创建一个空对象HttpServletResponse---->3. 参考web.xml配置文件,找控制层的类对象,看看有没有一个请求名字和真实类名字有对应关系)---->4. 用真实类名,反射,获取类对象,找到里面的service方法,执行---->5. 将响应信息填入HttpServletResponse,最后通过这个类将响应信息返回个浏览器
  4. 浏览器接收响应信息(就是个字符串)

idea 与 Tomcat 有一个美妙的约定_第20张图片

  • servlet-mapping 先起作用,为了截获请求
  • url-pattern 写相对路径,第一个/代表当前工程untitled的根目录
  • servlet-name 可以随便写,是为了servlet-mapping和servlet配对的
  • servlet-class 写test对应的真实类名,要写类全名
<servlet>
	<servlet-name>xxxservlet-name>
	<servlet-class>controller.TestControllerservlet-class>
servlet>
<servlet-mapping>
	<servlet-name>xxxservlet-name>
	<url-pattern>/testurl-pattern>
servlet-mapping>

六:其余设置

发送请求的时候,如果只写项目名,不写资源名会怎么样

发送请求的时候,如果只写工程名,不写资源名,Tomcat需要参考web.xml文件

  • 首先参考的是当前工程的web文件夹下WEB-INF文件夹内的web.xml,
  • 发现没有相关配置,然后去Tomcat文件夹下conf文件夹中的web.xml查看下面5行代码:
<welcome-file-list>
    <welcome-file>index.htmlwelcome-file>
    <welcome-file>index.htmwelcome-file>
    <welcome-file>index.jspwelcome-file>
welcome-file-list> 
  • welcome-file-list是请求的默认列表,如果没有发送任何的请求资源名,就会依次找寻中间三行显示的文件
  • 找到了就返回这个文件的信息,否则404

idea通过Tomcat创建web项目,导包时要注意的问题

拿我写的一个web项目AtmForServlet来举例

先说一下项目的部署及运行的过程:

  • 明确一点:用idea创建的项目和Tomcat容器是相分离的(不在一个路径下)
  • 在idea编辑器中写的web项目,是存放在你创建web项目所选的路径下的,比如D:\IdeaProjects\【demo】java\AtmForServlet
  • 然而创建的是一个web项目,执行需要Tomcat容器帮我们管理
  • 需要将web项目部署到Tomcat容器内部(webapps文件夹内),比如E:\utils\apache-tomcat-9.0.24\webapps
  • 部署的过程本质上是I/O流的读写,必然会耗费很多时间
  • 所以idea编辑器在这方面做了改动(默认的效果没有将真实的文件写入Tomcat的webapps文件夹下,而是写了一个映射关系)
    这个默认效果是可以改的,但是不推荐

项目部署之后,有一个解析的问题:

  1. 对于html文件资源,是直接读取内容的,作为响应返回给浏览器(因为浏览器认识html)
  2. 对于操作资源,Servlet类可以通过参考web.xml文件,获取类全名,然后通过反射找到类,执行最终的方法
  3. ----------上面的2点都没问题----------
  4. 对于JSP(java代码+html),这玩意直接写给浏览器是不行的,浏览器是无法解析JSP【所以:Tomcat会解析JSP,首先Tomcat生成一个为了解析JSP而生成的Java类,存放在Tomcat内部,work文件夹内】
    然而解析JSP文件生成的新文件却是存放在idea创建的项目里面(为了减少耗费的时间)
    如果将项目真实的部署到Tomcat中,这里就会产生麻烦

然后,分析一下:idea通过Tomcat创建web项目,运行后,文件会发生什么样的变化

  • 运行之前:
    idea 与 Tomcat 有一个美妙的约定_第21张图片
  • 运行之后:
    idea 与 Tomcat 有一个美妙的约定_第22张图片
    通过上图可以看出:
    idea创建的web项目部署在本项目下:AtmForServlet\out\artifacts
    AtmForServlet_war_exploded

最终:

  • web项目中,导入.jar文件的时候,操作与之前(创建的是Java项目)不一样了
  • 应该导入到web文件夹中的WEB-INF文件夹
  • 创建lib文件夹,将需要的.jar文件导入
    idea 与 Tomcat 有一个美妙的约定_第23张图片
    注意:导入包后,记得与项目进行关联

将idea项目真正部署到Tomcat文件夹下的操作

仅作了解,不推荐

IDEA部署Web项目时,默认使用映射关系(将项目地址与Tomcat联系起来)

一般而言,需要将项目资源放到Tomcat根目录下work文件夹中,有两种办法可以在IDEA部署Web项目时做到这一点

  • 方法一:idea > Run > Edit Configurations > Deployment
    idea 与 Tomcat 有一个美妙的约定_第24张图片
    idea 与 Tomcat 有一个美妙的约定_第25张图片
  • 方法二: File > Project Structure > Artifacts
    idea 与 Tomcat 有一个美妙的约定_第26张图片

Out directory 里面的路径是可以修改的,将路径改为Tomcat服务器下work文件夹即可

七:Tomcat9容器对get和post请求的字符集处理

经过实践证明,与请求相关的字符集问题,无论是哪种请求,只要在控制层的方法中使用 req.setCharacterEncoding("UTF-8"); 可以解决99%的问题

请求发送方式 .
get 1. 在浏览器中输入url,回车。2. 3.
post 1. 2. AJAX
请求 区别
get 1. url看起来很复杂,请求后面会有?拼接一些参数
. 2.只有协议头,没有协议体,只能将参数拼接在url上面
post 1. url看起来很简单,只有请求资源名,没有?拼接
. 2. 有些协议头和协议体,协议头传递资源名,协议体创建参数信息

发送请求 > 请求Tomcat > Tomcat有一个默认处理字符集

打开Tomcat9的web.xml文件,下面九行代码默认被注释掉
idea 与 Tomcat 有一个美妙的约定_第27张图片

get

  1. 发送请求的时候,请求名字和携带的参数信息都在协议头中(协议头是通过http协议在网络上传输的,而http协议是超文本传输协议)
    浏览器会以各自的方式(UTF-8/gbk/iso8859-1/…)对url进行encoding,将其转化为ASCII码,然后ASCII转化的二进制字节流在网络上传输;
    然后服务器先得到二进制字节码转化来的ASCII码,然后这时候问题来了,服务器会以其各自的方式对ASCII码进行转义(UTF-8/gbk/iso8859-1/…)
  2. 首先,现在浏览器基本上采用的都是UTF-8了,
  3. 然后Tomcat9的编码方式也是UTF-8,所以不用做编码字符的处理了,如果有问题请在控制层的方法中使用 req.setCharacterEncoding("UTF-8");

post:

  • 发送请求,请求名字在协议头中
  • 请求的参数信息在协议体中(协议体只能传递字节)
  • 服务器中:控制层接收请求的时候,post请求已经组合成一个String字符串了
    发送请求的时候按照UTF-8形式,拆开(字符集的处理应该是由浏览器决定的)
    接受的时候,request对象直接给我组合(按照平台默认的字符集)成一个String
  • 但是我所在的平台Windows默认的字符集是gbk,所以要在request组合之前告知,按照哪一种字符集组合:req.setCharacterEncoding("UTF-8");
  1. 在因特网上传送URL,只能采用ASCII字符集
  2. 其实做web开发乱码问题是经常出现的,乱码问题是web开发过程中经常遇到的问题,主要原因就是URL中使用了非ASCII码造成服务器后台程序解析出现乱码的问题。

补充关于URL编码的知识:

  1. 什么是URL编码:URL编码是一种浏览器用来打包表单输入的格式,浏览器从表单中获取所有的name和其对应的value,将他们以name/value编码方式作为URL的一部分或者分离的发送到服务器上。
  2. URL编码规则:每对name/value由&分开,每对来自表单的name/value用=分开。如果用户没有输入值的那个name依旧会出现不过就是没有值。
    URL编码是在字符ASCII码的十六进制数的前面加上%。例如\(它的十六进制数表示为5c)的URL编码就是%5c。
  3. URL encode到底是以什么样的编码方式对字符进行编码的,其实这个编码方式是由浏览器决定的,不同的浏览器和同一浏览器的不同设置影响了URL的编码,所以为了避免我们不需要的编码,我们可以通过java代码或javaspcript代码统一进行控制。
  4. 完成了URL encode之后URL就成了ASCII范围内的字符了
    。。。。。。
    这里我对于URL编码解释还是太苍白了,有兴趣的可以看看范海涛的这篇博客:浏览器URL编码

你可能感兴趣的:(Java)