Javaweb基础-tomcat,servlet

时间:2024-02-20 20:39:30

一.配置文件基础:

properties配置文件:

  • 由键值对组成

  • 键和值之间的符号是等号

  • 每一行都必须顶格写,前面不能有空格之类的其他符号

xml配置文件:(xml语法=HTML语法+HTML约束)xml约束-DTD /  Schema

DOM4J进行XML解析:(jar包 dom4j.jar )

1.创建SAXReader对象

SAXReader saxReader = new SAXReader();

2. 解析XML获取Document对象: 需要传入要解析的XML文件的字节输入流

Document document = reader.read(inputStream);

3\. 获取文档的根标签

Element rootElement = documen.getRootElement()
4\. 获取标签的子标签

//获取所有子标签
List<Element> sonElementList = rootElement.elements();
//获取指定标签名的子标签
List<Element> sonElementList = rootElement.elements("标签名");
5\. 获取标签体内的文本

String text = element.getText();

6\. 获取标签的某个属性的值

String value = element.attributeValue("属性名");

二.Tomcat(Javaweb服务器软件)

web项目标准文件结构(Tomcat/webapps下):

  • app 本应用根目录

    • static 非必要目录,约定俗成的名字,一般在此处放静态资源 ( css js img)

    • WEB-INF 必要目录,必须叫WEB-INF,受保护的资源目录,浏览器通过url不可以直接访问的目录

      • classes 必要目录,src下源代码,配置文件,编译后会在该目录下,web项目中如果没有源码,则该目录不会出现

      • lib 必要目录,项目依赖的jar编译后会出现在该目录下,web项目要是没有依赖任何jar,则该目录不会出现

      • web.xml 必要文件,web项目的基本配置文件.

    • index.html 非必要文件,index.html/index.htm/index.jsp为默认的欢迎页

开发部署:

静态资源:无需在程序运行时通过代码运行生成的资源,在程序运行之前就写好的资源. 例如:html css js img ,音频文件和视频文件

动态资源:需要在程序运行时通过代码运行生成的资源,在程序运行之前无法确定的数据,运行时动态生成,例如Servlet

servlet逻辑:用来接收、处理客户端请求、响应给浏览器的动态资源的接口(Servlet是运行在服务端的;必须在WEB项目中开发且在Tomcat这样的服务容器中运行 )

servlet开发流程:(eg:验证名字是否重复)

1.开发一个UserServlet

  • 自定义一个类,要继承HttpServlet类
  • 重写service方法,该方法主要就是用于处理用户请求的服务方法
  • HttpServletRequest 代表请求对象,是有请求报文经过tomcat转换而来的,通过该对象可以获取请求中的信息
  • HttpServletResponse 代表响应对象,该对象会被tomcat转换为响应的报文,通过该对象可以设置响应中的信息
  • Servlet对象的生命周期(创建,初始化,处理服务,销毁)是由tomcat管理的,无需我们自己new
  • HttpServletRequest HttpServletResponse 两个对象也是有tomcat负责转换,在调用service方法时传入给我们用的
public class UserServlet  extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取请求中的参数
        String username = req.getParameter("username");
//设置contenttype,帮助浏览器识别响应体中数据解析类型(在conf/web.xml配置文件下)
//查看mime类型,各种类型文件对应的声明
        resp.setcontentType("text/html");
        if("mingzi".equals(username)){
            //通过响应对象响应信息
            resp.getWriter().write("NO");
        }else{
            resp.getWriter().write("YES");
        }

    }
}

2.在web.xml为UseServlet配置请求的映射路径

当servlet接收到浏览器发起的一个url请求后,会用url减去当前应用的上下文路径(项目名及之前部分),以剩余的字符串作为servlet映射,假如url是http://localhost:8080/appDemo/index.html,其应用上下文是appDemo,容器会将http://localhost:8080/appDemo去掉,用剩下的/index.html部分拿来做servlet的映射匹配

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">

    <servlet>
        <!--给定义的Servlet类起一个别名-->
        <servlet-name>userServlet</servlet-name>
        <servlet-class>类的路径名</servlet-class>
    </servlet>


    <servlet-mapping>
        <!--关联别名和映射路径-->
        <servlet-name>userServlet</servlet-name>
        <!--可以为一个Servlet匹配多个不同的映射路径,但是不同的Servlet不能使用相同的url-pattern-->
        <url-pattern>/userServlet</url-pattern>//精确匹配
       <!-- <url-pattern>/userServlet2</url-pattern>-->
        <!--模糊匹配
            /        表示通配所有资源,不包括jsp文件
            /*       表示通配所有资源,包括jsp文件
            /a/*     匹配所有以a前缀的映射路径
            *.action 匹配所有以action为后缀的映射路径
        -->
       <!-- <url-pattern>/*</url-pattern>-->
    </servlet-mapping>

</web-app>

3.form表单向servlet发送一个get请求并携带username参数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="userServlet">//action属性为一个servlet动态资源,相对于当前HTML文件所在的URL进行解析
        请输入用户名:<input type="text" name="username" /> <br>
        <input type="submit" value="校验">
    </form>
</body>
</html>

@WebServlet注解使用-替换Servlet配置

@WebServlet(
value = "/user",//value可省略直接写成"/user"
)
public class UserServlet  extends HttpServlet {
...
}

servlet生命周期:

Servlet对象是Servlet容器创建的,生命周期方法都是由容器(eg:Tomcat)调用的

生命周期 对应方法 执行时机 执行次数
构造对象 构造器 第一次请求或者容器启动 1
初始化 init() 构造完毕后 1
处理服务 service(HttpServletRequest req,HttpServletResponse resp) 每次请求 多次
销毁 destory() 容器关闭 1

Servlet对象在容器中是单例的;容器是可以处理并发的用户请求的,每个请求在容器中都会开启一个线程;多个线程可能会使用相同的Servlet对象,尽量避免定义容易发生修改的成员变量;load-on-startup属性中定义的正整数表示容器的实例化顺序(1是defaultservlet,完成请求静态资源的任务)

servlet接口:

servletconfig对象:为Servlet提供初始配置参数的一种对象,每个Servlet都有自己独立唯一的ServletConfig对象;容器会为每个Servlet实例化一个ServletConfig对象,并通过Servlet生命周期的init方法传入给Servlet作为属性

方法名 作用
getServletName() 获取<servlet-name>HelloServlet</servlet-name>定义的Servlet名称
getServletContext() 获取ServletContext对象
getInitParameter() 获取配置Servlet时设置的『初始化参数』,根据名字获取值
getInitParameterNames() 获取所有初始化参数名组成的Enumeration对象
 // 获取所有参数名
        Enumeration<String> parameterNames = servletConfig.getInitParameterNames();
        // 迭代并获取参数名
        while (parameterNames.hasMoreElements()) {
            String paramaterName = parameterNames.nextElement();
        }
    <servlet>
        <servlet-name>Servlet</servlet-name>
        <servlet-class></servlet-class>
        <!--配置Servlet的初始参数-->
        <init-param>
            <param-name>param3</param-name>
            <param-value>value3</param-value>
        </init-param>
    //可以多个
    </servlet>

servletcontext对象:为上下文对象,容器会为每个app创建一个独立的唯一的ServletContext对象;ServletContext对象为所有的Servlet所共享;ServletContext可以为所有的Servlet提供初始配置参数

 <context-param>
        <param-name>paramA</param-name>
        <param-value>valueA</param-value>
    </context-param>
 // 从ServletContext中获取为所有的Servlet准备的参数
        ServletContext servletContext = this.getServletContext();
        // 获取所有参数名
        Enumeration<String> initParameterNames = servletContext.getInitParameterNames();
        // 迭代并获取参数名
        while (initParameterNames.hasMoreElements()) {
            String paramaterName = initParameterNames.nextElement();
        }

获取资源的真实路径(考虑项目的部署路径会发生变化,需要动态获取项目运行时候实际路径):

String realPath = servletContext.getRealPath("资源在web目录中的路径");

获取项目的上下文路径(项目部署名称-url栏中访问路径):解决一些后端页面渲染技术或者请求转发和响应重定向中的路径问题

String contextPath = servletContext.getContextPath();

域对象:用于存储数据和传递数据的对象,传递数据不同的范围,称之为不同的域。

ServletContext代表应用,所以ServletContext域也叫作应用域,是webapp中最大的域,可以在本应用内实现数据的共享和传递,除外还有会话域和请求域

void setAttribute(String key,Object value); 向域中存储/修改数据
Object getAttribute(String key); 获得域中的数据
void removeAttribute(String key); 移除域中的数据

HttpServletRequest的API

  • 获取请求行信息相关(方式,请求的url,协议及版本)

API 功能解释
StringBuffer getRequestURL(); 获取客户端请求的url
String getRequestURI(); 获取客户端请求项目中的具体资源
int getServerPort(); 获取客户端发送请求时的端口
int getLocalPort(); 获取本应用在所在容器的端口
int getRemotePort(); 获取客户端程序的端口
String getScheme(); 获取请求协议
String getProtocol(); 获取请求协议及版本号
String getMethod(); 获取请求方式
  • 获得请求头信息相关

API 功能解释
String getHeader(String headerName); 根据头名称获取请求头
Enumeration<String> getHeaderNames(); 获取所有的请求头名字
String getContentType(); 获取content-type请求头
  • 获得请求参数相关

API 功能解释
String getParameter(String parameterName); 根据请求参数名获取请求单个参数值
String[] getParameterValues(String parameterName); 根据请求参数名获取请求多个参数值数组
Enumeration<String> getParameterNames(); 获取所有请求参数名
Map<String, String[]> getParameterMap(); 获取所有请求参数的键值对集合
BufferedReader getReader() throws IOException; 获取读取请求体的字符输入流
ServletInputStream getInputStream() throws IOException; 获取读取请求体的字节输入流
int getContentLength(); 获得请求体长度的字节数
  • 其他API

API 功能解释
String getServletPath(); 获取请求的Servlet的映射路径
ServletContext getServletContext(); 获取ServletContext对象
Cookie[] getCookies(); 获取请求中的所有cookie
HttpSession getSession(); 获取Session对象
void setCharacterEncoding(String encoding) ; 设置请求体字符集

HttpServletResponse的常见API

  • 设置响应行相关

API 功能解释
void setStatus(int code); 设置响应状态码
  • 设置响应头相关

API 功能解释
void setHeader(String headerName, String headerValue); 设置/修改响应头键值对
void setContentType(String contentType); 设置content-type响应头及响应字符集(设置MIME类型)
  • 设置响应体相关

API 功能解释
PrintWriter getWriter() throws IOException; 获得向响应体放入信息的字符输出流
ServletOutputStream getOutputStream() throws IOException; 获得向响应体放入信息的字节输出流
void setContentLength(int length); 设置响应体的字节长度,其实就是在设置content-length响应头
  • 其他API

API 功能解释
void sendError(int code, String message) throws IOException; 向客户端响应错误信息的方法,需要指定响应码和响应信息
void addCookie(Cookie cookie); 向响应体中增加cookie
void setCharacterEncoding(String encoding); 设置响应体字符集
  • MIME类型,可以理解为文档类型,用户表示传递的数据是属于什么类型的文档

  • 浏览器可以根据MIME类型决定该用什么样的方式解析接收到的响应体数据

  • 可以这样理解: 前后端交互数据时,告诉对方发给对方的是 html/css/js/图片/声音/视频/... ...

  • tomcat/conf/web.xml中配置了常见文件的拓展名和MIMIE类型的对应关系

  • 常见的MIME类型举例如下

文件拓展名 MIME类型
.html text/html
.css text/css
.js application/javascript
.png /.jpeg/.jpg/... ... image/jpeg
.mp3/.mpe/.mpeg/ ... ... audio/mpeg
.mp4 video/mp4
.m1v/.m1v/.m2v/.mpe/... ... video/mpeg

请求转发与响应重定向

(web应用中间接访问项目资源的两种手段,也是Servlet控制页面跳转的两种手段 )

请求转发:

  • 请求转发通过HttpServletRequest对象获取请求转发器实现

  • 请求转发是服务器内部的行为,对客户端是屏蔽的

  • 客户端只发送了一次请求,客户端地址栏不变

  • 服务端只产生了一对请求和响应对象,这一对请求和响应对象会继续传递给下一个资源

  • 因为全程只有一个HttpServletRequset对象,所以请求参数可以传递,请求域中的数据也可以传递

  • 请求转发可以转发给其他Servlet动态资源,也可以转发给一些静态资源以实现页面跳转

  • 请求转发可以转发给WEB-INF下受保护的资源

  • 请求转发不能转发到本项目以外的外部资源

@WebServlet("/servletA")
public class ServletA extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //  获取请求转发器
        //  转发给servletB
        RequestDispatcher  requestDispatcher = req.getRequestDispatcher("servletB");
        //  做出转发动作
        requestDispatcher.forward(req,resp);
    }
}

响应重定向:

  • 响应重定向通过HttpServletResponse对象的sendRedirect方法实现

  • 响应重定向是服务端通过302响应码和路径,告诉客户端自己去找其他资源,是在服务端提示下的,客户端的行为

  • 客户端至少发送了两次请求,客户端地址栏是要变化的

  • 服务端产生了多对请求和响应对象,且请求和响应对象不会传递给下一个资源

  • 因为全程产生了多个HttpServletRequset对象,所以请求参数不可以传递,请求域中的数据也不可以传递

  • 重定向可以是其他Servlet动态资源,也可以是一些静态资源以实现页面跳转

  • 重定向不可以到给WEB-INF下受保护的资源

  • 重定向可以到本项目以外的外部资源

三.乱码问题:

Tomcat控制台乱码:修改 tomcat/conf/logging.properties中,所有的UTF-8为GBK即可

sout乱码问题,设置JVM加载.class文件时使用UTF-8字符集

请求乱码:

get:设置Tomcat的URI解析字符集和GET请求发送时所使用URL转码时的字符集一致即可,修改conf/server.xml中 Connecter 添加 URIEncoding="GBK"  

post:设置req.setcharacterencoding();

响应乱码:设置resp.setcharacterencoding()和resp.setcontenttype()一致;

四.路径问题:

前端路径:相对路径-在当前资源路径下拼接所设置路径(../表示上一层,./表示当前层)

绝对路径-在基准路径(IP+端口号)后面拼接所设置路径(需要添加上下文路径-可将上下文路径设置为/解决)

后端路径:重定向问题设置与前端一致;

请求转发:相对路径-在当前资源路径下拼接所设置路径,绝对路径-在基准路径后拼接(省略上下文路径)

MVC(Model View Controller)是软件工程中的一种软件架构模式,它把软件系统分为模型视图控制器三个基本部分。用一种业务逻辑、数据、界面显示分离的方法组织代码。