Java Web 300问
DAO 层的作用是什么?
DAO 层作用:与数据库直接交互,封装所有数据访问的细节(即CRUD操作),不包含业务逻辑,只关注数据的持久化。
DAO的全拼是什么
Data Access Object,数据连接实体。
SERVICE 层的作用是什么?
SERVICE 层作用:处理核心业务逻辑,协调多个DAO的操作,完成复杂的业务处理。
CONTROLLER 层的作用是什么?
CONTROLLER 层作用:接收客户端请求,调用 SERVICE 层并返回响应,只负责请求和响应的协调。
备注:这里的“客户端”,一般就是浏览器。
log4j.properties 文件的作用是什么?
日志配置文件。
src/main/java 文件夹的作用是什么?
存放 Java 源代码的文件夹,通常按照 controller、service、dao、model等包结构组织。
src/main/resources 文件夹的作用是什么?
存放配置文件,包括数据库配置、日志配置等。
WEB-INF 文件夹的作用是什么?
存放 Web 应用的配置文件和依赖库,包括web.xml
文件等。
WEB-INF 文件夹的完整路径:src/main/webapp/WEB-INF/
。
db.properties 文件的作用是什么?
数据库连接配置文件。
db.properties 示例:
# 数据库驱动类
jdbc.driver=com.mysql.cj.jdbc.Driver# 数据库连接URL
jdbc.url=jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC# 用户名和密码
jdbc.username=root
jdbc.password=123456
如何获得db.properties
文件中的配置信息?
在 Java 代码中通过 Properties
类加载该文件(以 Servlet 为例):
// 1. 加载配置文件
Properties props = new Properties();
try (InputStream input = getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties")) {props.load(input);
} catch (IOException e) {e.printStackTrace();
}// 2. 获取配置值
String driver = props.getProperty("jdbc.driver");
String url = props.getProperty("jdbc.url");
String username = props.getProperty("jdbc.username");
String password = props.getProperty("jdbc.password");// 3. 初始化数据库连接(示例:JDBC)
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, username, password);
注意:设计到框架时,可能不会使用db.properties
文件来配置数据库,而是使用框架专用的配置文件。
applicationContext.xml 文件的作用是什么?
Spring的配置文件。
src/main/webapp 文件夹的作用是什么?
存放 Web 的资源文件。
src/test 文件夹的作用是什么?
存放单元测试代码和测试配置文件。
target 文件夹的作用是什么?
Maven 项目的编译输出目录,存放编译后的类文件、打包的 WAR 文件等。
pom.xml 文件的作用是什么?
pom.xml
是 Maven 项目的核心配置文件,用于定义项目的基本信息、依赖库、构建配置和插件。它采用 XML 格式,Maven 通过该文件管理项目的整个生命周期(编译、测试、打包等)。
如何创建 JavaWeb 项目?
-
新建项目打开 IDEA,单击“New Project”或者通过 File–>new–>Project,在弹出的对话框中输入项目名称,其它的默认选择,点击 finish 按钮
-
设置项目信息
-
web 支持为项目添加 Web 框架支持,右键单击创建的项目,点击 Add Framework Support,在弹出的对话框中勾选 Web Application(4.0)及 Create web.xml 复选框,单击“OK”按钮,完成添加。
-
web application 支持
-
添加依赖添加依赖包,右键单击 WEB-INF 文件夹,在弹出的对话框中选择 New–>Directory 命令,创建 lib 文件夹。
-
Add As Library在 servlet-api.jar 文件上右击鼠标,选择 Add As Library,将 jar 包添加到 Library 中mysql-connector-j-8.2.0.jar 是 mysql 相关的连接包,如果不需要 mysql,可以不要这个包servlet-api.jar servlet 依赖包
MVC模式是什么?
MVC 模式是一种软件架构模式。
MVC 模式中,M、V、C分别代表什么?
Model(模型)
View(视图)
Controller(控制器)
Model 部分的责任是什么?
模型(Model)部分负责管理应用程序的核心数据和业务逻辑,通常与数据库交互。
MVC 模式的工作流程是什么?
- 用户通过视图与应用程序交互。
- 控制器接收用户输入并调用模型处理。
- 模型更新数据后,控制器通知视图更新显示。
- 视图从模型获取最新数据,并展示给用户。
Web 服务器的工作流程是什么?
- 客户端(如浏览器)发送 HTTP 请求到 Web 服务器。
- Web 服务器解析请求,确定请求的资源和操作。
- 如果请求静态资源(如HTML、图片),直接返回文件内容。
- 如果请求动态资源(如 PHP、JSP),则将请求转发给后端处理程序(如 Tomcat),然后将结果返回给客户端。
- 客户端接收响应并渲染内容。
常见的 Web 服务器有哪些?
Web 服务器有很多种,常见的主要有以下三种:
Tomcat:https://tomcat.apache.org
Nginx:https://nginx.org
Apache:https://httpd.apache.org
Tomcat 是什么?
Tomcat 是一个开源的 Java Servlet 容器和 Web 容器。
Tomcat 的主要功能有哪些?
三大主要功能:
- 运行 Java Web 应用。
- 处理 HTTP 请求。
- 管理 Web 应用。
如何安装 Tomcat ?
- 下载 Tomcat 安装包(Apache Tomcat 官网:https://tomcat.apache.org)。
- 解压到指定目录。
- 配置环境变量(如
CATALINA_HOME
)。 - 启动 Tomcat:
-
- Windows: 运行
bin/startup.bat
。 - Linux/macOS: 运行
bin/startup.sh
。 - 注意:启动tomcat时如果出现乱码,修改日志配置
logging.properties
文件中的参数java.logging.ConsoleHandler.encoding
即可。
- Windows: 运行
- 访问
http://localhost:8080
验证是否启动成功。 - 关闭Tomcat:运行
shutdown.bat
文件。
如何在 Tomcat 中部署 Web 应用?
示例:部署一个简单的 Web 应用
创建一个简单的 Servlet:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;public class HelloServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();out.println("<html><body>");out.println("<h1>Hello, Tomcat!</h1>");out.println("</body></html>");}
}
编译 Servlet 并将其放入 WEB-INF/classes
目录。
创建 web.xml
文件配置 Servlet:
<web-app><servlet><servlet-name>HelloServlet</servlet-name><servlet-class>HelloServlet</servlet-class></servlet><servlet-mapping><servlet-name>HelloServlet</servlet-name><url-pattern>/hello</url-pattern></servlet-mapping>
</web-app>
将应用打包为 WAR 文件或直接复制到 Tomcat 的 webapps
目录。
启动 Tomcat 并访问 http://localhost:8080/your-app/hello
。
war 模式和 war exploded 模式有什么区别?
在Java Web开发中(特别是使用IDEA或Eclipse等IDE部署到Tomcat时),会遇到WAR模式和WAR Exploded模式两种不同的部署方式。
WAR 模式(打包模式) | WAR Exploded(展开模式) | |
---|---|---|
热更新 | 不支持 | 支持 |
特点 | 将项目编译后打包成一个标准的 .war 文件(如 myapp.war ),部署时服务器会自动解压到其工作目录(如Tomcat的 webapps 目录)。 | 直接将项目的编译结果以目录结构展开(未压缩),部署到服务器。 |
是否压缩文件 | 压缩(ZIP格式) | 未压缩 |
部署速度 | 比WAR Exploded模式更快。 | 文件以目录形式存在,部署速度略慢于WAR模式。 |
调试便利性 | 低 | 高 |
建议:
- 开发阶段使用WAR Exploded模式:
- 使用 WAR Exploded,利用热更新提高开发效率。
- 在IDEA中配置Tomcat时,选择 Deploy as exploded war。
- 生产阶段使用WAR 模式:
- 使用 WAR模式,通过CI/CD工具生成
.war
文件后部署。
- 使用 WAR模式,通过CI/CD工具生成
IDEA中,如何启动 Tomcat 热部署?
Tomcat的热部署机制:
- 对于Exploded模式,Tomcat会监控
WEB-INF/classes
和WEB-INF/lib
的变化,但默认不自动重载Java类(需配置reloadable="true"
或使用JRebel)。
IDEA中的配置:
<!-- 在Tomcat的 context.xml 中 -->
<Context reloadable="true" path="/myapp"/>
开启后,Tomcat会检测变更并自动重启应用(影响性能,慎用于生产环境)。
Filter 是什么?
在Java Web开发中,Filter(过滤器)是一种用于在请求到达目标资源(如Servlet、JSP)之前或响应返回客户端之前进行预处理和后处理的组件。Filter可以拦截请求和响应,执行特定的操作,如日志记录、身份验证、数据压缩等。
Filter 的作用有哪些?
作用 | 介绍 |
---|---|
请求预处理 | 在请求到达Servlet或JSP之前,Filter可以对请求进行修改或验证。 |
响应后处理 | 在响应返回客户端之前,Filter可以对响应进行修改或处理。 |
链式处理 | 多个Filter可以串联,形成一个处理链,每个Filter依次处理请求和响应。 |
通用功能封装 | Filter可以将一些通用功能(如日志记录、字符编码设置、权限检查)封装起来,避免在多个Servlet中重复代码。 |
Filter 常见的应用场景有哪些?
- 身份验证和授权:检查用户是否登录或是否有权限访问资源。
- 日志记录:记录请求和响应的详细信息,用于调试或监控。
- 字符编码设置:统一设置请求和响应的字符编码,避免乱码。
- 数据压缩:对响应内容进行压缩,减少传输数据量。
- 跨域处理:设置响应头,解决跨域问题。
Filter 的工作原理是什么?
- 请求到达:客户端发送请求到服务器。
- Filter拦截:请求首先经过Filter链,每个Filter可以对请求进行处理。
- 目标资源处理:请求到达目标资源(如Servlet或JSP),资源生成响应。
- Filter后处理:响应经过Filter链,每个Filter可以对响应进行处理。
- 响应返回:最终响应返回客户端。
Filter 的生命周期分为哪些阶段?
- 初始化:Filter在Web应用启动时初始化,调用
init()
方法。 - 过滤:每次请求和响应都会调用
doFilter()
方法。 - 销毁:Filter在Web应用关闭时销毁,调用
destroy()
方法。
如何实现一个 Filter?
要实现一个Filter,需要实现javax.servlet.Filter
接口,并重写其方法:
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;@WebFilter("/*") // 拦截所有请求
public class ExampleFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化操作}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {// 请求预处理System.out.println("Before processing request");// 传递给下一个Filter或目标资源chain.doFilter(request, response);// 响应后处理System.out.println("After processing response");}@Overridepublic void destroy() {// 销毁操作}
}
如何配置 Filter ?
可以通过注解(如@WebFilter
)或在web.xml
中配置Filter:
<filter><filter-name>ExampleFilter</filter-name><filter-class>com.example.ExampleFilter</filter-class>
</filter>
<filter-mapping><filter-name>ExampleFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
@WebFilter("/api/*")
会拦截哪些资源?
api/
路径下的所有资源都会被拦截。
@WebFilter("*.do")
会拦截哪些资源?
以.do
结尾的所有资源都会被拦截。
Listener 是什么?
在Java Web开发中,Listener(监听器)是一种用于监听Web应用中特定事件(如ServletContext、HttpSession、ServletRequest的创建、销毁或属性修改)的组件。Listener可以在这些事件发生时执行自定义逻辑,常用于初始化资源、统计在线用户、清理资源等场景。
Listener 的作用有哪些?
- 事件监听:监听Web应用中的各种事件,如应用启动、会话创建、请求到达等。
- 资源管理:在应用启动时初始化资源,在应用关闭时释放资源(如数据库连接等)。
- 日志记录:记录应用的关键事件,用于监控和调试。
- 初始化全局资源:在应用启动时初始化数据库连接池、缓存等。
- 统计在线用户数:跟踪用户会话状态,通过监听会话的创建和销毁,统计在线用户数。
Listener 常见的类型有哪些?
Java Web提供了多种Listener接口,用于监听不同的事件:
- ServletContextListener
- 监听
ServletContext
的创建和销毁。 - 常用方法:
contextInitialized()
、contextDestroyed()
。 - 应用场景:在应用启动时初始化全局资源(如数据库连接池),在应用关闭时释放资源。
- 监听
- HttpSessionListener
- 监听
HttpSession
的创建和销毁。 - 常用方法:
sessionCreated()
、sessionDestroyed()
。 - 应用场景:统计在线用户数、跟踪用户会话状态。
- 监听
- ServletRequestListener
- 监听
ServletRequest
的创建和销毁。 - 常用方法:
requestInitialized()
、requestDestroyed()
。 - 应用场景:记录请求日志、统计请求处理时间。
- 监听
- ServletContextAttributeListener
- 监听
ServletContext
中属性的添加、修改和删除。 - 常用方法:
attributeAdded()
、attributeRemoved()
、attributeReplaced()
。 - 应用场景:跟踪全局属性的变化。
- 监听
- HttpSessionAttributeListener
- 监听
HttpSession
中属性的添加、修改和删除。 - 常用方法:
attributeAdded()
、attributeRemoved()
、attributeReplaced()
。 - 应用场景:跟踪用户会话中属性的变化。
- 监听
- ServletRequestAttributeListener
- 监听
ServletRequest
中属性的添加、修改和删除。 - 常用方法:
attributeAdded()
、attributeRemoved()
、attributeReplaced()
。 - 应用场景:跟踪请求中属性的变化。
- 监听
Session 相关的监听器有哪些?
和Session相关的监听器有两种:
HttpSessionListener
- 监听
HttpSession
的创建和销毁。 - 常用方法:
sessionCreated()
、sessionDestroyed()
。 - 应用场景:统计在线用户数、跟踪用户会话状态。
HttpSessionAttributeListener
- 监听
HttpSession
中属性的添加、修改和删除。 - 常用方法:
attributeAdded()
、attributeRemoved()
、attributeReplaced()
。 - 应用场景:跟踪用户会话中属性的变化。
Request 相关的监听器有哪些?
Request相关的监听器有两种:
ServletRequestListener
- 监听
ServletRequest
的创建和销毁。 - 常用方法:
requestInitialized()
、requestDestroyed()
。 - 应用场景:记录请求日志、统计请求处理时间。
ServletRequestAttributeListener
- 监听
ServletRequest
中属性的添加、修改和删除。 - 常用方法:
attributeAdded()
、attributeRemoved()
、attributeReplaced()
。 - 应用场景:跟踪请求中属性的变化。
ServletContext 相关的监听器有哪些?
ServletContext相关的监听器有两种:
ServletContextListener
- 监听
ServletContext
的创建和销毁。 - 常用方法:
contextInitialized()
、contextDestroyed()
。 - 应用场景:在应用启动时初始化全局资源(如数据库连接池),在应用关闭时释放资源。
ServletContextAttributeListener
- 监听
ServletContext
中属性的添加、修改和删除。 - 常用方法:
attributeAdded()
、attributeRemoved()
、attributeReplaced()
。 - 应用场景:跟踪全局属性的变化。
Listener 如何实现?
要实现一个Listener,需要实现相应的接口,并重写其方法。例如,实现ServletContextListener
:
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;@WebListener
public class ExampleContextListener implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent sce) {// 应用启动时执行System.out.println("Web应用初始化");// 初始化全局资源,如数据库连接池}@Overridepublic void contextDestroyed(ServletContextEvent sce) {// 应用关闭时执行System.out.println("Web应用销毁");// 释放全局资源}
}
如何配置 Listener?
可以通过注解(如@WebListener
)或在web.xml
中配置Listener:
<listener><listener-class>com.example.ExampleContextListener</listener-class>
</listener>
Servlet 是什么?
Java Servlet | ||
---|---|---|
运行位置 | Web 服务器或应用服务器,如 Tomcat 等。 | |
主要功能 | 处理请求 | 处理客户端(一般是浏览器)发送的 HTTP 请求。 |
生成响应 | 生成动态Web内容,如 HTML、JSON 等。 | |
业务逻辑 | 在服务器端执行业务逻辑,如访问数据库、调用其他服务等。 | |
会话管理 | 管理客户端与服务器之间的会话,如使用Session、Cookie。 | |
本质 | Java程序 |
Servlet 的作用有哪些
作用 | |
---|---|
生成动态 HTML 页面 | 生成动态的 HTML 页面。 |
提供 Web 服务 | 提供 RESTful API 或 SOAP 服务。 |
文件上传和下载 | 处理文件上传和下载请求。 |
表单处理 | 处理用户提交的表单数据。 |
Servlet 的工作流程是什么?
流程 | 备注 |
---|---|
Servlet 容器(例如Tomcat)产生一个 Servlet 实例。 | 在一个应用程序中,每种Servlet类型只能有一个实例。同时产生一个 ServletContext 对象、一个 ServletConfig 对象。 |
用户发送 HTTP 请求。 | |
Servlet容器调用 Servlet 实例的service 方法。 | service 方法的参数 ServletRequest 对象和 ServletResponse 对象都是由 Servlet 容器封装好的,程序员可以直接使用这两个对象。 |
通过ServletRequest 获取 HTTP 请求。 | ServletRequest 中封装了当前的 HTTP 请求。 |
通过ServletResponse 返回响应内容。 | ServletResponse 表示当前用户的 HTTP 响应。 |
Servlet 的生命周期有哪些阶段
阶段 | 生命周期 | 备注 |
---|---|---|
阶段一 | 加载和实例化 | Web 容器加载 Servlet 类并创建其实例。 |
通常是在第一次收到请求时加载,但也可以通过配置在启动时加载。 | ||
阶段二 | 初始化 | 调用 init() 方法,完成 Servlet 的初始化工作。 |
开发者可以重写此方法,执行自定义的初始化逻辑(如加载配置文件、初始化数据库连接等)。 | ||
阶段三 | 处理请求 | 调用 service() 方法,处理客户端请求。 |
对于 HTTP 请求,通常会使用 HttpServlet 的子类,并重写 doGet() 、doPost() 等方法。 | ||
阶段四 | 销毁 | 调用 destroy() 方法,释放资源(如关闭数据库连接、清理缓存等)。 |
通常是在 Web 应用关闭或 Servlet 被移除时调用。 | ||
补充 | Servlet 的生命周期由 Web 容器(如 Tomcat)管理。 |
Servlet 的核心接口和类有哪些
13个核心接口和类 | 类型 | 所在 java 包 | 简介 |
---|---|---|---|
Servlet | 接口 | javax.servlet | 定义了 Servlet 的生命周期方法 |
void init(ServletConfig config) :初始化 Servlet。 | |||
void service(ServletRequest req, ServletResponse res) :处理请求。 | |||
void destroy() :销毁 Servlet。 | |||
ServletConfig getServletConfig() :获取 Servlet 配置信息。 | |||
String getServletInfo() :获取 Servlet 的描述信息。 | |||
GenericServlet | 抽象类 | javax.servlet | 提供了 Servlet 接口的基本实现,简化了 Servlet 的开发。 |
开发者可以继承此类,并重写 service() 方法。 | |||
HttpServlet | 类 | javax.servlet.http | 继承自 GenericServlet ,专门用于处理 HTTP 请求。 |
提供了对 HTTP 方法的支持(如 doGet() 、doPost() 、doPut() 、doDelete() 等)。 | |||
开发者通常继承此类,并重写相应的方法。 | |||
ServletRequest | 接口 | javax.servlet | |
HttpServletRequest | 接口 | javax.servlet.http | |
ServletResponse | 接口 | javax.servlet | |
HttpServletResponse | 接口 | javax.servlet.http | |
ServletConfig | 接口 | 封装 Servlet 配置。 | |
ServletDispatcher | 接口 | ||
ServletContext | 接口 | 封装了上下文(应用程序)的环境详情。 | |
Filter | 接口 | ||
Listener | 接口 |
Servlet 如何使用
导入Servlet
<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope>
<!--提供provided 编译和测试有效,避免和 tomcat 中的 servlet-api 包冲突报错-->
</dependency>
以下是一个简单的 Servlet 示例,用于处理 HTTP GET 请求并返回 “Hello, World!”:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class HelloWorldServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws IOException {// 设置响应内容类型response.setContentType("text/html;charset=UTF-8");// 获取输出流PrintWriter out = response.getWriter();// 向客户端发送响应out.println("<html>");out.println("<head><title>Hello World</title></head>");out.println("<body>");out.println("<h1>Hello, World!</h1>");out.println("</body>");out.println("</html>");}
}
Servlet 如何配置
两种配置方式 | 介绍 |
---|---|
web.xml 配置 | 在 web.xml 文件中定义 Servlet 和映射 |
注解配置 | 使用 @WebServlet 注解定义 Servlet 和映射 |
(1) web.xml
配置
在 web.xml
文件中定义 Servlet 和映射:
<servlet><servlet-name>HelloWorldServlet</servlet-name><servlet-class>HelloWorldServlet</servlet-class>
</servlet>
<servlet-mapping><servlet-name>HelloWorldServlet</servlet-name><url-pattern>/hello</url-pattern>
</servlet-mapping>
(2) 注解配置
使用 @WebServlet
注解定义 Servlet 和映射:
配置之后,我们就可以通过
http://localhost:8080/hello
访问Servlet。
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;@WebServlet(name = "HelloWorldServlet", urlPatterns = "/hello")
public class HelloWorldServlet extends HttpServlet {// Servlet 代码
}
Servlet 中的常用方法有哪些
七个相关的类或接口 | 常用方法 | |
---|---|---|
Servlet | void init(ServletConfig config) | 初始化 Servlet,容器在创建 Servlet 实例后调用此方法。 |
void service(ServletRequest req, ServletResponse res) | 处理客户端请求的核心方法。 | |
void destroy() | 销毁 Servlet,容器在移除 Servlet 实例前调用此方法。 | |
ServletConfig getServletConfig() | 返回 ServletConfig 对象,用于获取 Servlet 的配置信息。 | |
String getServletInfo() | 返回 Servlet 的描述信息(如作者、版本等)。 | |
GenericServlet | void init() | 无参的初始化方法,开发者可以重写此方法来实现自定义的初始化逻辑。 |
void log(String msg) | 将消息写入 Servlet 容器的日志文件。 | |
void log(String msg, Throwable t) | 将消息和异常信息写入 Servlet 容器的日志文件。 | |
HttpServlet | void doGet(HttpServletRequest req, HttpServletResponse resp) | 处理 HTTP GET 请求。 |
void doPost(HttpServletRequest req, HttpServletResponse resp) | 处理 HTTP POST 请求。 | |
void doPut(HttpServletRequest req, HttpServletResponse resp) | 处理 HTTP PUT 请求。 | |
void doDelete(HttpServletRequest req, HttpServletResponse resp) | 处理 HTTP DELETE 请求。 | |
void service(HttpServletRequest req, HttpServletResponse resp) | 根据请求方法(GET、POST 等)调用相应的 doXxx 方法。 | |
ServletRequest 和 HttpServletRequest | String getParameter(String name) | 根据参数名称获取请求参数的值。 |
String[] getParameterValues(String name) | 根据参数名称获取多个请求参数的值(适用于多选框等场景)。 | |
Map<String, String[]> getParameterMap() | 返回所有请求参数的键值对。 | |
String getHeader(String name) | 根据头名称获取请求头的值。 | |
Enumeration<String> getHeaderNames() | 返回所有请求头的名称。 | |
InputStream getInputStream() | 返回一个二进制输入流,用于读取请求体中的数据。 | |
BufferedReader getReader() | 返回一个字符输入流,用于读取请求体中的文本数据。 | |
void setAttribute(String name, Object obj) | 设置请求属性的名称和值。 | |
Object getAttribute(String name) | 根据名称获取请求属性的值。 | |
void removeAttribute(String name) | 移除指定的请求属性。 | |
ServletResponse 和 HttpServletResponse | void setContentType(String type) | 设置响应的内容类型(MIME 类型),例如 text/html 或 application/json 。 |
void setCharacterEncoding(String charset) | 设置响应的字符编码,例如 UTF-8 。 | |
ServletOutputStream getOutputStream() | 返回一个二进制输出流,用于向客户端发送二进制数据。 | |
PrintWriter getWriter() | 返回一个字符输出流,用于向客户端发送文本数据。 | |
void setHeader(String name, String value) | 设置响应头的名称和值。 | |
void addHeader(String name, String value) | 添加一个响应头,允许多个同名的头信息。 | |
void sendRedirect(String location) | 将客户端重定向到指定的 URL。 | |
void setStatus(int sc) | 设置响应的状态码(如 200、404 等)。 | |
注意 | getOutputStream() 和getWriter() | 不能同时调用,同时调用会发生异常。 |
示例代码
以下是一个简单的 Servlet 示例,展示了常用方法的使用:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class ExampleServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置响应内容类型和字符编码response.setContentType("text/html;charset=UTF-8");// 获取请求参数String username = request.getParameter("username");// 获取输出流PrintWriter out = response.getWriter();// 向客户端发送响应out.println("<html>");out.println("<head><title>Example Servlet</title></head>");out.println("<body>");out.println("<h1>Hello, " + (username != null ? username : "Guest") + "!</h1>");out.println("</body>");out.println("</html>");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 处理 POST 请求doGet(request, response);}
}
ServletRequest 的核心方法有哪些
获取请求参数
String getParameter(String name) | 根据参数名称获取单个请求参数的值。例如,获取表单中 name="username" 的值。 |
---|---|
String[] getParameterValues(String name) | 根据参数名称获取多个请求参数的值(适用于多选框等场景)。 |
Map<String, String[]> getParameterMap() | 返回所有请求参数的键值对,其中键是参数名称,值是参数值的数组。 |
获取请求头信息
String getHeader(String name) | 根据头名称获取单个请求头的值。例如,获取 User-Agent 或 Content-Type 。 |
---|---|
Enumeration<String> getHeaders(String name) | 根据头名称获取多个请求头的值(适用于多值的头信息)。 |
Enumeration<String> getHeaderNames() | 返回所有请求头的名称。 |
获取输入流
ServletInputStream getInputStream() | 返回一个二进制输入流,用于读取请求体中的数据(例如文件上传或二进制数据)。 |
---|---|
BufferedReader getReader() | 返回一个字符输入流,用于读取请求体中的文本数据(例如 JSON 或 XML)。 |
注意 | getInputStream 和 getReader 不能同时调用,否则会抛出 IllegalStateException 。 |
获取请求属性
void setAttribute(String name, Object obj) | 设置请求属性的名称和值。 |
---|---|
Object getAttribute(String name) | 根据名称获取请求属性的值。 |
void removeAttribute(String name) | 移除指定的请求属性。 |
Enumeration<String> getAttributeNames() | 返回所有请求属性的名称。 |
获取客户端和服务器信息
String getRemoteAddr() | 获取客户端的 IP 地址。 |
---|---|
String getRemoteHost() | 获取客户端的主机名。 |
int getRemotePort() | 获取客户端的端口号。 |
String getServerName() | 获取服务器的主机名。 |
int getServerPort() | 获取服务器的端口号。 |
String getProtocol() | 获取请求的协议(例如 HTTP/1.1 )。 |
String getScheme() | 获取请求的协议方案(例如 http 或 https )。 |
(6) 其他方法
String getContentType() | 获取请求体的内容类型(MIME 类型)。 |
---|---|
int getContentLength() | 获取请求体的长度(字节数)。 |
Locale getLocale() | 获取客户端的本地化信息。 |
Enumeration<Locale> getLocales() | 获取客户端支持的所有本地化信息。 |
使用示例
以下是一个简单的示例,展示如何使用 ServletRequest
获取请求参数并生成响应:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置响应内容类型response.setContentType("text/html;charset=UTF-8");// 获取请求参数String username = request.getParameter("username");// 获取字符输出流PrintWriter out = response.getWriter();// 向客户端发送响应out.println("<html>");out.println("<head><title>Hello Servlet</title></head>");out.println("<body>");out.println("<h1>Hello, " + (username != null ? username : "Guest") + "!</h1>");out.println("</body>");out.println("</html>");}
}
注意事项
- 参数编码:如果请求参数包含非 ASCII 字符(例如中文),需要设置正确的字符编码(例如
UTF-8
),否则可能出现乱码。可以通过request.setCharacterEncoding("UTF-8")
设置。 - 输入流的使用:根据请求体的数据类型选择
getInputStream
(二进制)或getReader
(文本)。 - 属性与参数的区别:请求参数是客户端发送的数据,而请求属性是服务器端设置的数据,用于在请求处理过程中共享信息。
ServletRequest
与 HttpServletRequest
是什么关系
父子接口 | HttpServletRequest 是ServletRequest 的子接口。 |
---|---|
HTTP 专用 | 专用于 HTTP 协议,提供了更多与 HTTP 相关的方法 |
新增特殊方法 | 获取 HTTP 方法(getMethod )。 |
获取请求的 URL 信息(getRequestURI 、getQueryString )。 | |
管理会话(getSession )。 | |
获取 Cookie(getCookies )。 | |
实际开发常用 | 在实际开发中,通常使用 HttpServletRequest ,因为它提供了更多 HTTP 相关的功能。 |
ServletResponse
的核心方法有哪些
以下是 ServletResponse
接口中一些重要的方法:
设置内容类型与字符编码
方法 | 介绍 |
---|---|
void setContentType(String type) | 设置响应的内容类型,如 text/html 或 application/json 。可附加字符编码,如 text/html;charset=UTF-8 。 |
void setCharacterEncoding(String charset) | 设置响应的字符编码,如 UTF-8 。若已经通过 setContentType 设置,则此方法会覆盖之前的设置。 |
获取输出流
方法 | 介绍 |
---|---|
ServletOutputStream getOutputStream() | 返回一个二进制输出流,用于向客户端发送二进制数据(例如图片、文件等)。 |
PrintWriter getWriter() | 返回一个字符输出流,用于向客户端发送文本数据(例如 HTML、JSON 等)。 |
注意 | getOutputStream 和 getWriter 不能同时调用,否则会抛出 IllegalStateException 。 |
设置响应头
方法 | 介绍 |
---|---|
void setHeader(String name, String value) | 设置响应头的名称和值,例如 setHeader("Content-Disposition", "attachment; filename=file.txt") 。 |
void addHeader(String name, String value) | 添加一个响应头,允许多个同名的头信息。 |
void setIntHeader(String name, int value) | 设置一个整数值的响应头。 |
缓冲区控制
方法 | 介绍 |
---|---|
void setBufferSize(int size) | 设置响应缓冲区的大小。 |
int getBufferSize() | 获取当前响应缓冲区的大小。 |
`void flushBuffer() | 强制将缓冲区的内容发送到客户端。 |
void reset() | 重置响应,清除缓冲区、状态码和头信息。 |
void resetBuffer() | 仅重置缓冲区的内容,不清除状态码和头信息。 |
boolean isCommitted() | 检查响应是否已经提交(即数据是否已经发送到客户端)。 |
其他方法
方法 | 介绍 |
---|---|
void setLocale(Locale loc) | 设置响应的本地化信息。 |
Locale getLocale() | 获取响应的本地化信息。 |
使用示例
以下是一个简单的示例,展示如何使用 ServletResponse
向客户端返回 HTML 内容:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class HelloWorldServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置内容类型和字符编码response.setContentType("text/html;charset=UTF-8");// 获取字符输出流PrintWriter out = response.getWriter();// 向客户端发送 HTML 内容out.println("<html>");out.println("<head><title>Hello World</title></head>");out.println("<body>");out.println("<h1>Hello, World!</h1>");out.println("</body>");out.println("</html>");}
}
注意事项
- 内容类型和字符编码:必须在调用
getWriter
或getOutputStream
之前设置内容类型和字符编码,否则设置可能无效。 - 输出流的选择:根据返回数据的类型选择
getWriter
(文本)或getOutputStream
(二进制)。 - 缓冲区管理:合理设置缓冲区大小,避免内存浪费或性能问题。
- 响应提交:一旦调用
flushBuffer
或缓冲区已满,响应就会被提交,之后无法修改状态码或头信息。
ServletResponse
与 HttpServletResponse
是什么关系
父子接口 | HttpServletResponse 是ServletResponse 的子接口。 |
---|---|
HTTP 专用 | 专用于 HTTP 协议,提供了更多与 HTTP 相关的方法 |
新增特殊方法 | 设置状态码(setStatus 、sendError )。 |
重定向(sendRedirect )。 | |
管理 Cookie(addCookie )。 | |
实际开发常用 | 实际开发中,通常使用 HttpServletResponse ,因为它提供了更多 HTTP 相关的功能。 |
Servlet
和ServletConfig
是什么关系
一对一 | 每个 Servlet 都有一个独立的 ServletConfig 对象,由 Servlet 容器(如 Tomcat)创建并传递给 Servlet。 |
---|---|
保存配置信息 | 通过 ServletConfig ,开发者可以访问 Servlet 的初始化参数、Servlet 上下文等信息。 |
ServletConfig
的核心方法有哪些
方法 | 介绍 | |
---|---|---|
获取初始化参数 | String getInitParameter(String name) | 根据参数名称获取 Servlet 的初始化参数值。如web.xml 中配置的 <init-param> 值 |
Enumeration<String> getInitParameterNames() | 返回所有初始化参数的名称。 | |
获取 ServletContext | ServletContext getServletContext() | 返回 ServletContext 对象,用于与 Servlet 容器通信。 |
获取 Servlet 名称 | String getServletName() | 返回 Servlet 名称。名称在 web.xml 中通过 <servlet-name> 配置,或注解 @WebServlet 指定。 |
使用示例
以下是一个简单的示例,展示如何使用 ServletConfig
获取初始化参数:
(1) 在 web.xml
中配置初始化参数
<servlet><servlet-name>MyServlet</servlet-name><servlet-class>com.example.MyServlet</servlet-class><init-param><param-name>username</param-name><param-value>admin</param-value></init-param><init-param><param-name>password</param-name><param-value>123456</param-value></init-param>
</servlet>
<servlet-mapping><servlet-name>MyServlet</servlet-name><url-pattern>/myservlet</url-pattern>
</servlet-mapping>
(2) 在 Servlet 中使用 ServletConfig
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class MyServlet extends HttpServlet {private String username;private String password;@Overridepublic void init(ServletConfig config) throws ServletException {super.init(config);// 获取初始化参数username = config.getInitParameter("username");password = config.getInitParameter("password");}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html;charset=UTF-8");PrintWriter out = response.getWriter();out.println("<html>");out.println("<head><title>MyServlet</title></head>");out.println("<body>");out.println("<h1>Username: " + username + "</h1>");out.println("<h1>Password: " + password + "</h1>");out.println("</body>");out.println("</html>");}
}
ServletConfig
与 ServletContext
的区别是什么
ServletConfig | ServletContext | |
---|---|---|
范围不同 | 每个 Servlet 有独立的 ServletConfig 。 | 整个 Web 应用共享一个 ServletContext 对象。在应用关闭时销毁。 |
用途不同 | 用于访问Servlet 的初始化参数。 | 用于访问 Web 应用的全局信息,如上下文初始化参数,资源路径等。 |
创建时机不同 | ServletConfig 对象在 Servlet 初始化时(init 方法调用时)创建 | 当 Web 服务器(如 Tomcat)启动并加载 Web 应用时创建。 |
线程安全 | 线程安全,可以在多线程环境中使用。 | 线程安全,可以在多线程环境中使用。 |
如何通过注解配置初始化参数
如果使用注解配置 Servlet,可以通过 @WebServlet
的 initParams
属性设置初始化参数:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet(name = "MyServlet",urlPatterns = "/myservlet",initParams = {@WebInitParam(name = "username", value = "admin"),@WebInitParam(name = "password", value = "123456")}
)
public class MyServlet extends HttpServlet {private String username;private String password;@Overridepublic void init(ServletConfig config) throws ServletException {super.init(config);// 获取初始化参数username = config.getInitParameter("username");password = config.getInitParameter("password");}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html;charset=UTF-8");PrintWriter out = response.getWriter();out.println("<html>");out.println("<head><title>MyServlet</title></head>");out.println("<body>");out.println("<h1>Username: " + username + "</h1>");out.println("<h1>Password: " + password + "</h1>");out.println("</body>");out.println("</html>");}
}
ServletContext的核心方法有哪些
作用 | 方法 | 介绍 |
---|---|---|
获取初始化参数 | String getInitParameter(String name) | 根据参数名称获取 Web 应用的初始化参数值。这些参数通常在 web.xml 中通过 <context-param> 配置。 |
- | Enumeration<String> getInitParameterNames() | 返回所有 Web 应用初始化参数的名称。 |
获取资源 | URL getResource(String path) | 根据路径获取资源的 URL。路径必须以 / 开头,相对于 Web 应用的根目录。 |
- | InputStream getResourceAsStream(String path) | 根据路径获取资源的输入流。适用于读取文件内容。 |
- | String getRealPath(String path) | 根据虚拟路径获取文件系统的真实路径。例如,将 /WEB-INF/web.xml 转换为服务器文件系统中的绝对路径。 |
- | Set<String> getResourcePaths(String path) | 返回指定路径下的所有资源路径。 |
共享数据(属性) | void setAttribute(String name, Object object) | 在应用范围内设置属性,让所有 Servlet 和请求都可以访问。 |
- | Object getAttribute(String name) | 根据名称获取应用范围内的属性。 |
- | void removeAttribute(String name) | 移除应用范围内的属性。 |
- | Enumeration<String> getAttributeNames() | 返回所有应用范围内的属性名称。 |
记录日志 | void log(String message) | 将消息写入 Servlet 容器的日志文件。 |
- | void log(String message, Throwable throwable) | 将消息和异常信息写入 Servlet 容器的日志文件。 |
获取容器信息 | String getServerInfo() | 返回 Servlet 容器的名称和版本信息。 |
- | int getMajorVersion() | 返回 Servlet API 的主版本号。 |
- | int getMinorVersion() | 返回 Servlet API 的次版本号。 |
其他方法 | String getContextPath() | 返回 Web 应用的上下文路径(例如 /myapp )。 |
- | String getMimeType(String file) | 返回指定文件的 MIME 类型(例如 text/html 或 image/jpeg )。 |
- | RequestDispatcher getRequestDispatcher(String path) | 返回一个 RequestDispatcher 对象,用于请求转发或包含其他资源。 |
使用示例
以下是一些常见的使用场景和示例:
(1) 获取初始化参数
在 web.xml
中配置上下文参数:
<context-param><param-name>appName</param-name><param-value>My Web Application</param-value>
</context-param>
在 Servlet 中获取参数:
String appName = getServletContext().getInitParameter("appName");
System.out.println("Application Name: " + appName);
(2) 获取资源
读取 WEB-INF
目录下的配置文件:
InputStream inputStream = getServletContext().getResourceAsStream("/WEB-INF/config.properties");
Properties properties = new Properties();
properties.load(inputStream);
String value = properties.getProperty("key");
(3) 共享数据
设置应用范围内的属性:
getServletContext().setAttribute("userCount", 100);
获取应用范围内的属性:
int userCount = (Integer) getServletContext().getAttribute("userCount");
(4) 记录日志
记录日志信息:
getServletContext().log("An error occurred in the application.");
GenericServlet与Servlet是什么关系
实现 ServletConfig 和 Servlet 接口 | GenericServlet 实现了 Servlet 和 ServletConfig 接口,并提供了一些默认的方法实现。 |
---|---|
简化 Servlet 开发 | 开发者可以通过继承 GenericServlet 来创建自定义的 Servlet,而不需要实现所有 Servlet 接口的方法。 |
注意事项 | GenericServlet 没有提供 service 方法的默认实现,开发者必须重写此方法。 |
- | 可以通过重写无参的 init() 方法来实现自定义的初始化逻辑,而不需要直接处理 ServletConfig 对象。 |
GenericServlet的核心方法有哪些
方法 | 介绍 | |
---|---|---|
Servlet 生命周期方法 | void init(ServletConfig config) | 初始化 Servlet。GenericServlet 提供了默认实现,将 ServletConfig 对象保存起来,并调用无参的 init() 方法。 |
- | void init() | 无参的初始化方法,开发者可以重写此方法来实现自定义的初始化逻辑。 |
- | void service(ServletRequest req, ServletResponse res) | 处理客户端请求的核心方法。GenericServlet 没有提供默认实现,开发者必须重写此方法。 |
- | void destroy() | 销毁 Servlet。GenericServlet 提供了默认实现,开发者可以重写此方法来实现自定义的销毁逻辑。 |
获取配置信息 | ServletConfig getServletConfig() | 返回 ServletConfig 对象。 |
- | String getInitParameter(String name) | 根据参数名称获取 Servlet 的初始化参数值。 |
- | Enumeration<String> getInitParameterNames() | 返回所有初始化参数的名称。 |
- | ServletContext getServletContext() | 返回 ServletContext 对象。 |
日志 | void log(String msg) | 将消息写入 Servlet 容器的日志文件。 |
- | void log(String msg, Throwable t) | 将消息和异常信息写入 Servlet 容器的日志文件。 |
其它方法 | String getServletInfo() | 返回 Servlet 的描述信息。默认返回空字符串,开发者可以重写此方法。 |
- | String getServletName() | 返回 Servlet 的名称。 |
使用示例
以下是一个简单的示例,展示如何通过继承 GenericServlet
创建自定义的 Servlet:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;public class MyServlet extends GenericServlet {@Overridepublic void init() throws ServletException {// 自定义初始化逻辑System.out.println("Servlet initialized.");}@Overridepublic void service(ServletRequest req, ServletResponse res)throws ServletException, IOException {// 设置响应内容类型res.setContentType("text/html;charset=UTF-8");// 获取输出流PrintWriter out = res.getWriter();// 向客户端发送响应out.println("<html>");out.println("<head><title>MyServlet</title></head>");out.println("<body>");out.println("<h1>Hello, World!</h1>");out.println("</body>");out.println("</html>");}@Overridepublic void destroy() {// 自定义销毁逻辑System.out.println("Servlet destroyed.");}
}
GenericServlet
与 HttpServlet
的区别是什么
区别 | GenericServlet | HttpServlet |
---|---|---|
父子类 | - | GenericServlet 的子类。 |
协议无关性 | 适用于任何协议,包括HTTP、FTP等。 | 专用于 HTTP 协议。提供了对 HTTP 方法的支持(如:doGet、doPost)。 |
JSP 的全拼是什么?
Java Server Pages。
JSP 作用是什么
JSP(JavaServer Pages) | 简化服务器端的Web开发,用于开发动态网页的Java技术,允许将Java代码嵌入HTML页面中。 |
---|---|
JSP = 静态页面 + java 动态展示 | JSP用于生成动态内容,根据用户请求实时生成HTML。 |
JSP 代码的工作原理是什么
JSP页面在首次请求时被编译成Servlet,后续请求直接由Servlet处理,JSP代码在服务器端执行,生成HTML后发送到客户端。
当浏览器请求一个JSP页面时,服务器将JSP文件编译成一个Servlet(Java类)。
这个Servlet生成HTML内容并发送回客户端(浏览器)。
JSP 的基本语法有哪些?
基本语法
JSP脚本元素:
<% ... %>
: 嵌入Java代码。<%= ... %>
: 输出表达式结果。<%! ... %>
: 声明变量或方法。
JSP指令:
<%@ page ... %>
: 定义页面属性。<%@ include ... %>
: 包含其他文件。<%@ taglib ... %>
: 引入标签库。
JSP动作:
<jsp:include>
: 包含其他页面。<jsp:useBean>
: 使用JavaBean。<jsp:setProperty>
: 设置JavaBean属性。<jsp:getProperty>
: 获取JavaBean属性。
示例代码
JSP 页面 (example.jsp
):
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head><title>JSP 示例</title>
</head>
<body><h1>当前时间</h1><p><%= new java.util.Date() %></p><jsp:useBean id="user" class="com.example.User" scope="session"/><jsp:setProperty name="user" property="name" value="Alice"/><p>用户名: <jsp:getProperty name="user" property="name"/></p>
</body>
</html>
JavaBean (User.java
):
package com.example;public class User {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
JSP 和 Servlet 是什么关系
- JSP和Servlet可以相互调用,形成MVC(Model-View-Controller)模式。
- JSP是Servlet的简化版,专注于页面显示。
- Servlet适合处理复杂的逻辑和控制流程。
JSP 与 Servlet 、JavaScript、静态 HTML 相比,分别有什么区别?
- 与纯 Servlet 相比:JSP可以很方便的编写或者修改HTML网页而不用去面对大量的println语句
- 与JavaScript相比:虽然JavaScript可以在客户端动态生成 HTML,但是很难与服务器交互,因此不能提供复杂的服务,比如访问数据库和图像处理等等
- 与静态HTML相比:静态HTML不包含动态信息
W3C 是什么?
W3C(World Wide Web Consortium,万维网联盟)是一个国际性的组织,致力于制定和维护 Web 技术的标准。它的使命是通过开发和推广开放的技术标准,确保 Web 的长期发展和互操作性。W3C 的标准是 Web 技术的基石,涵盖了 HTML、CSS、XML、HTTP、DOM 等核心技术。
负责动态更新内容,如 AJAX 请求等的是哪一个?
JavaScript
负责操作 DOM 的是哪一个?
HTML
负责设置颜色、字体、间距、背景等样式的是哪一个?
CSS
DOM 是什么?
DOM 是 Web 开发中用于操作 HTML 和 XML 文档的核心接口。通过 DOM,开发者可以动态修改文档的内容、结构和样式,并处理用户交互事件。理解 DOM 是掌握前端开发的基础。
DOM全拼是什么?中文是什么?
Document Object Model,文档对象模型。
DOM中,如何访问元素?
访问元素
- 通过 ID:
document.getElementById("id")
- 通过标签名:
document.getElementsByTagName("div")
- 通过类名:
document.getElementsByClassName("class")
- 通过 CSS 选择器:
document.querySelector("selector")
和document.querySelectorAll("selector")
示例:
const elementById = document.getElementById("myId");
const elementsByTag = document.getElementsByTagName("div");
const elementsByClass = document.getElementsByClassName("myClass");
const elementBySelector = document.querySelector("myId .myClass");
DOM中,如何修改属性和文本内容?
修改内容
- 修改文本:
element.textContent
或element.innerHTML
- 修改属性:
element.setAttribute("attribute", "value")
示例:
const element = document.getElementById("myId");
element.textContent = "新的文本内容";
element.setAttribute("class", "newClass");
DOM中,如何绑定和移除事件?
事件处理
- 绑定事件:
element.addEventListener("event", handler)
- 移除事件:
element.removeEventListener("event", handler)
示例:
const button = document.getElementById("myButton");
button.addEventListener("click", function() {alert("按钮被点击了!");
});
BOM 中的“B“指的是什么?
B:Browser,即浏览器。
打开新窗口、调整窗口大小,使用DOM还是BOM?
BOM。
DOM和BOM是什么关系?
DOM(Document Object Model,文档对象模型) 和 BOM(Browser Object Model,浏览器对象模型) 是 Web 开发中两个重要的概念,它们都与浏览器环境相关,但功能和作用不同。
DOM | BOM | |
---|---|---|
简介 | DOM 是将 HTML 或 XML 文档表示为树形结构的编程接口。 | BOM 是浏览器提供的对象模型,用于操作浏览器窗口和浏览器本身的行为。 |
核心对象 | document | window |
作用 | 操作文档的内容、结构和样式,专注于文档内容的操作 | 控制浏览器的导航、历史、屏幕信息等,专注于浏览器窗口和浏览器行为的操作。 |
核心关系 | DOM 是 BOM 的一部分。 | DOM 的核心对象 document 是 BOM 的核心对象 window 的一个属性。 |
共同点 | 都是浏览器提供的 JavaScript API。 | 都是浏览器提供的 JavaScript API。 |
DOM示例:
const element = document.getElementById("myId");
element.textContent = "新的文本内容";
BOM示例:
window.location.href = "https://example.com"; // 跳转到新页面
window.alert("Hello, World!"); // 弹出警告框
DOM 与 BOM 协作:
- 通过 BOM 的
window.location
跳转页面后,使用 DOM 更新页面内容。 - 通过 BOM 的
window.setTimeout
设置定时器,使用 DOM 动态修改页面元素。
示例:
// 使用 BOM 设置定时器
window.setTimeout(function() {// 使用 DOM 修改页面内容const element = document.getElementById("myId");element.textContent = "5 秒后更新的内容";
}, 5000);
“专注于文档内容的操作“的是DOM还是BOM?
DOM
”专注于浏览器窗口和浏览器行为的操作“的是DOM还是BOM?
BOM
DOM的核心对象是什么?
document
BOM的核心对象是什么?
window
BOM中的核心属性有哪些?
window:BOM 的顶层对象,代表浏览器窗口。
window.location
: 提供当前页面的 URL 信息。window.navigator
: 提供浏览器信息(如用户代理、平台)。window.screen
: 提供屏幕信息(如宽度、高度)。window.history
: 提供浏览器历史记录。
window 对象的核心方法有哪些?
window.alert()
: 弹出警告框。window.open()
: 打开新窗口。window.setTimeout()
: 设置定时器。
示例:
console.log(window.location.href); // 获取当前页面的 URL
window.navigator.userAgent; // 获取用户代理信息
window.screen.width; // 获取屏幕宽度
window.history.back(); // 返回上一页
解析XML文档的技术有哪些?
SAX 和 DOM。
SAX的全拼是什么?
Simple API for XML
SAX 解析方式和 DOM 解析方式最主要的区别是什么?
SAX 和 DOM 是两种用于解析 XML 文档的技术。它们的主要区别如下:
特性 | DOM | SAX |
---|---|---|
解析方式 | 将整个 XML 文档加载到内存中,形成树结构。 | 基于事件驱动,逐行解析 XML 文档。 |
内存占用 | 占用内存较大,适合小文件。 | 占用内存较小,适合大文件。 |
速度 | 解析速度较慢(需要加载整个文档)。 | 解析速度较快(逐行解析)。 |
修改文档 | 支持对 XML 文档的增删改查。 | 不支持直接修改 XML 文档。 |
适用场景 | 小型 XML 文档或需要频繁操作 XML 的场景。 | 大型 XML 文档或只需读取数据的场景。 |
API 复杂度 | API 较复杂,但操作方便。 | API 较简单,但需要编写事件处理器。 |
DOM 解析示例
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;public class DOMParser {public static void main(String[] args) throws Exception {DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = factory.newDocumentBuilder();Document document = builder.parse("example.xml");NodeList nodeList = document.getElementsByTagName("name");for (int i = 0; i < nodeList.getLength(); i++) {System.out.println(nodeList.item(i).getTextContent());}}
}
SAX 解析示例
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;public class SAXParserExample {public static void main(String[] args) throws Exception {SAXParserFactory factory = SAXParserFactory.newInstance();SAXParser saxParser = factory.newSAXParser();DefaultHandler handler = new DefaultHandler() {boolean isName = false;@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) {if (qName.equalsIgnoreCase("name")) {isName = true;}}@Overridepublic void characters(char[] ch, int start, int length) {if (isName) {System.out.println(new String(ch, start, length));isName = false;}}};saxParser.parse("example.xml", handler);}
}
当XML文档较大时,应该使用哪种解析方式?
SAX
为什么SAX的解析方式,不能修改数据?DOM的解析方式,可以修改数据?
因为 SAX 的解析方式是基于事件驱动,逐行解析 XML 文档并触发事件。而 DOM 的解析方式是将整个 XML 文档加载到内存中,形成树结构,开发者通过操作 DOM 树的节点来访问或修改数据。。
只需读取数据的场景使用哪种解析方式比较好?
SAX
占用内存比较低的是哪种解析方式?
SAX
需要频繁操作元素时,使用哪种解析方式比较好?
DOM
常见的解析器有哪些?
常见的解析器有三种:
- JAXP:sum 公司提供的解析器。支持 dom sax
- DOM4J:比较优秀
- jsoup:HTML 解析
推荐挑选 DOM4J 的版本 2.1.3以上。
HTML、CSS、JavaScript 是什么关系?
- HTML: 提供网页的基本结构和内容。
- CSS: 美化网页,使其更具吸引力。
- JavaScript: 增加交互性,提升用户体验。。
示例:结合使用三大组件:
<!DOCTYPE html>
<html>
<head><title>三大组件示例</title><style>body {font-family: Arial, sans-serif;background-color: f0f0f0;text-align: center;}button {padding: 10px 20px;font-size: 16px;background-color: blue;color: white;border: none;cursor: pointer;}</style>
</head>
<body><h1>欢迎来到我的网页</h1><button id="demo">点击我</button><script>document.getElementById("demo").addEventListener("click", function() {alert("按钮被点击了!");});</script>
</body>
</html>
HTML 的全拼是什么?CSS全拼是什么?
HyperText Markup Language
Cascading Style Sheets
Tags 是什么?
Tags 即 HTML 中所谓的”标签“。
文档结构标签有哪些?
文档结构标签
这些标签用于定义 HTML 文档的基本结构。
<!DOCTYPE html>
声明文档类型,告诉浏览器使用 HTML5 标准。<html>
定义 HTML 文档的根元素。<head>
包含文档的元数据(如标题、字符编码、样式表链接等)。<title>
定义文档的标题,显示在浏览器的标题栏或标签页上。<body>
定义文档的主体内容,显示在浏览器窗口中。
<title>
标签中的内容显示在什么位置?
显示在网页顶部的标签栏。
<hr>
标签的作用是什么?
插入水平线。
<br/>
标签的作用是什么?
插入换行符。
<strong>
标签的作用是什么?
定义加粗文本,表示重要内容。
<em>
标签的作用是什么?
定义斜体文本,表示强调内容。
<a>
标签中,最重要的属性是什么?
<a>
标签用于定义超链接,href
属性指定链接的目标地址。
<a href="https://www.example.com">访问示例网站</a>
<img>
标签中,src
属性的作用是什么?alt
属性的作用是什么?
src
属性用于指定图像的路径,alt
属性提供替代文本。
<img src="image.jpg" alt="示例图片">
有序列表的标签是什么?
<ol><li>第一项</li><li>第二项</li>
</ol>
无序列表的标签是什么?
<ul><li>项目 1</li><li>项目 2</li>
</ul>
定义表格的标签是什么?
<table>
标签用于定义表格。
<table><tr><th>姓名</th><th>年龄</th></tr><tr><td>张三</td><td>25</td></tr>
</table>
表格标签中,定义表格行的标签是什么?
<tr>
标签定义表格行。
<table><tr><th>姓名</th><th>年龄</th></tr><tr><td>张三</td><td>25</td></tr>
</table>
定义表单的标签是什么?
<form><label for="username">用户名:</label><input type="text" id="username" name="username"><br><label for="password">密码:</label><input type="password" id="password" name="password"><br><button type="submit">提交</button>
</form>
定义“多行文本输入框”的标签是什么?
<textarea>
定义“下拉列表”的标签是什么?
<select>
定义“下拉列表的选项”的标签是什么?
<option>
定义“表单控件”的标签是什么?
<label>
定义“输入字段”的标签是什么?
<input>
,其中的type
属性指定输入的类型(如文本、密码、复选框等)。
什么是“语义化标签”?
语义化标签用于定义网页的结构和内容的意义。它们本身没有特殊的显示效果,只是标签的名称有更明显的结构含义。
定义“页眉或章节的头部”的标签是什么?
<header>
<header><h1>网站标题</h1><nav><a href="#">首页</a> |<a href="#">关于我们</a> |<a href="#">联系我们</a></nav>
</header>
<main><article><h2>文章标题</h2><p>文章内容...</p></article>
</main>
<footer><p>版权所有 © 2023</p>
</footer>
定义“页脚或章节的尾部”的标签是什么?
<footer>
定义“导航链接”的标签是什么?
<nav>
定义“块级容器”的标签是什么?
<div>
定义“客户端脚本(如 JavaScript)”的标签是什么?
<script>
定义“行内容器”的标签是什么?
<span>
定义“文档的元数据”的标签是什么?
<meta>
定义“内部样式表”的标签是什么?
<style>
定义“外部资源链接(如样式表)”的标签是什么?
<link>
<meta charset="UTF-8">
<link rel="stylesheet" href="styles.css">
<script src="script.js"></script>
<style>body { font-family: Arial, sans-serif; }
</style>
CSS的全拼是什么?中文名是什么?
Cascading Style Sheets,层叠样式表。
如何选择类名为"example"的元素?
/* 选择类名为"example"的元素 */
.example {background-color: yellow;padding: 10px;
}
内联CSS和内部CSS有什么区别?
内联样式:直接在HTML元素的style
属性中定义样式。
<p style="color: red;">这是一个段落。</p>
内部样式表:在HTML文档的<head>
部分使用<style>
标签定义样式。
<head><style>p {color: green;}</style>
</head>
CSS的使用方式有哪些?
CSS的使用方式有以下三种:
内联样式:直接在HTML元素的style
属性中定义样式。
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>内联样式示例</title>
</head>
<body><h1 style="color: red;">Hello, World!</h1><p style="font-size: 18px;">这是一个段落。</p>
</body>
</html>
内部样式表:在HTML文档的<head>
部分使用<style>
标签定义样式。
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>内部样式表示例</title><style>h1 {color: green;}p {font-size: 16px;}</style>
</head>
<body><h1>Hello, World!</h1><p>这是一个段落。</p>
</body>
</html>
外部样式表:在单独的CSS文件中定义样式,并通过<link>
标签引入。
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>外部样式表示例</title><link rel="stylesheet" href="styles.css">
</head>
<body><h1>Hello, World!</h1><p>这是一个段落。</p>
</body>
</html>
外部CSS要如何引入?
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>外部样式表示例</title><link rel="stylesheet" href="styles.css">
</head>
<body><h1>Hello, World!</h1><p>这是一个段落。</p>
</body>
</html>
内部CSS的<style>
标签一般放在什么位置?
一般放在<head>
标签中。
选择所有元素的选择器如何写?
/* 选择所有元素 */
* {color: blue;font-size: 16px;
}
CSS 文件的后缀名是什么?
.css
最推荐的CSS导入方式是哪一种?
外部样式。
- 外部样式表易于维护。
- 外部样式表可以被浏览器缓存,提高加载速度。
如何在 CSS 文件中导入其他 CSS 样式表?
@import
@import url("reset.css");
@import url("typography.css");h1 {color: purple;
}
CSS的选择器有哪些?
CSS 选择器分为基本选择器和组合选择器两大类。(属性选择器、伪类选择器和伪元素选择器不常用)
基本选择器主要有:
- 元素选择器
- ID 选择器
- 类选择器
- 通用选择器
组合选择器主要有:
- 后代选择器
- 子元素选择器
- 相邻兄弟选择器
- 通用兄弟选择器
如何选择p标签中,class属性为center的元素?
p.center {text-align: center;color: red;
}
如何“动态导入 CSS ”?
使用 JavaScript 动态导入
通过 JavaScript 动态插入 <link>
标签来加载 CSS 文件,适用于需要条件加载的场景。
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>动态导入样式表示例</title><script>function loadStyleSheet(url) {var link = document.createElement("link");link.rel = "stylesheet";link.href = url;document.head.appendChild(link);}loadStyleSheet("styles.css");</script>
</head>
<body><h1>Hello, World!</h1><p>这是一个段落。</p>
</body>
</html>
JavaScript 是什么?
JavaScript 是一种广泛用于网页开发的脚本语言,主要用于增强网页的交互性和动态功能。
示例代码:
// 在网页中显示 "Hello, World!"
document.getElementById("demo").innerHTML = "Hello, World!";
引入 JavaScript 的方式有哪些?
在网页中引入 JavaScript 有多种方式,常见的有以下三种:
- 内联 JavaScript
直接将 JavaScript 代码嵌入 HTML 文件的<script>
标签中。
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>内联 JavaScript 示例</title>
</head>
<body><h1 id="demo">Hello, World!</h1><script>// 内联 JavaScript 代码document.getElementById("demo").innerHTML = "你好,世界!";</script>
</body>
</html>
- 内部 JavaScript
将 JavaScript 代码放在 HTML 文件的<script>
标签中,通常放在<head>
或<body>
的末尾。(把脚本置于<head>
或<body>
的末尾,可改善显示速度,因为脚本编译会拖慢显示。)
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>内部 JavaScript 示例</title><script>// 内部 JavaScript 代码function changeText() {document.getElementById("demo").innerHTML = "你好,世界!";}</script>
</head>
<body><h1 id="demo">Hello, World!</h1><button onclick="changeText()">点击我</button>
</body>
</html>
- 外部 JavaScript(推荐使用)
将 JavaScript 代码保存在单独的.js
文件中,通过<script>
标签的src
属性引入。
HTML 文件:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>外部 JavaScript 示例</title><script src="script.js"></script>
</head>
<body><h1 id="demo">Hello, World!</h1><button onclick="changeText()">点击我</button>
</body>
</html>
JavaScript 文件 (script.js
):
// 外部 JavaScript 代码
function changeText() {document.getElementById("demo").innerHTML = "你好,世界!";
}
引入 JavaScript 拓展:
异步和延迟加载
通过 async
和 defer
属性控制脚本加载和执行时机。
async
: 脚本异步加载,下载完成后立即执行。defer
: 脚本延迟到 HTML 解析完成后执行。
<script src="script.js" async></script>
<script src="script.js" defer></script>
内联 JavaScript 和内部 JavaScript 的区别是什么?
这个问题不重要,没必要研究。
- 内联 JavaScript
直接将 JavaScript 代码嵌入 HTML 文件的<script>
标签中。
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>内联 JavaScript 示例</title>
</head>
<body><h1 id="demo">Hello, World!</h1><script>// 内联 JavaScript 代码document.getElementById("demo").innerHTML = "你好,世界!";</script>
</body>
</html>
- 内部 JavaScript
将 JavaScript 代码放在 HTML 文件的<script>
标签中,通常放在<head>
或<body>
的末尾。(把脚本置于<head>
或<body>
的末尾,可改善显示速度,因为脚本编译会拖慢显示。)
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>内部 JavaScript 示例</title><script>// 内部 JavaScript 代码function changeText() {document.getElementById("demo").innerHTML = "你好,世界!";}</script>
</head>
<body><h1 id="demo">Hello, World!</h1><button onclick="changeText()">点击我</button>
</body>
</html>
外部JavaScript文件的后缀名是什么?
.js
为什么内部JavaScript最好放在<body>
或<head>
标签的末尾?
因为脚本编译会拖慢显示,所有把脚本置于<head>
或 <body>
的末尾,可改善显示速度。
三种引入方式中,最推荐哪一种?为什么?
推荐使用外部 JavaScript 。原因有以下几点:
- 外部 JavaScript 能够做到分离解耦,使 HTML 和 JavaScript 更易于阅读和维护。
- 已缓存的 JavaScript 文件可加速页面加载
引入外部 JavaScript 脚本文件的标签是什么?
通过 <script>
标签的 src
属性引入。
HTML 文件:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>外部 JavaScript 示例</title><script src="script.js"></script>
</head>
<body><h1 id="demo">Hello, World!</h1><button onclick="changeText()">点击我</button>
</body>
</html>
JavaScript 文件 (script.js
):
// 外部 JavaScript 代码
function changeText() {document.getElementById("demo").innerHTML = "你好,世界!";
}
JavaScript中,let
和const
的区别是什么?
let
和const
都用于块级作用域的变量的声明。
区别在于:
let
: 可重新赋值。const
: 声明后不可重新赋值。
let y = 20;
const z = 30;
JavaScript 中的引用类型有哪些?
JavaScript 中的引用类型有3种:
object
array
function
let obj = { name: "Alice", age: 25 }; // object
let arr = [1, 2, 3]; // array
JavaScript 中的基本类型有哪些?
JavaScript 中的基本类型有7种:
number
,string
,boolean
,null
,undefined
,symbol
,bigint
。
let num = 42; // number
let str = "Hello"; // string
let bool = true; // boolean
JavaScript 中,如何定义对象?
对象: 使用 {}
定义,包含键值对。
let person = {name: "Alice",age: 25,greet: function() {console.log("Hello, " + this.name);}
};
JavaScript 中,如何定义数组?
数组: 使用 []
定义,元素可任意类型。
let fruits = ["apple", "banana", "cherry"];
fruits.push("orange"); // 添加元素
JavaScript 中,如何”捕获和处理异常“?
错误处理
try...catch
: 捕获并处理异常。
try {let result = riskyOperation();
} catch (error) {console.error("发生错误:", error);
}
JavaScript 中,如何”定义和继承类“?
类和面向对象
class
: 定义类。constructor
: 构造函数。extends
: 继承。
class Animal {constructor(name) {this.name = name;}speak() {console.log(`${this.name} 发出声音。`);}
}class Dog extends Animal {speak() {console.log(`${this.name} 汪汪叫。`);}
}let dog = new Dog("Rex");
dog.speak(); // Rex 汪汪叫。
JavaScript 中,==
和===
的区别是?
两者的区别主要在于是否进行”类型转换“:
==
(宽松相等)
- 有类型转换: 在比较前会进行类型转换,尝试将操作数转换为相同类型。
- 比较值: 转换后比较值是否相等。
示例:
console.log(5 == "5"); // true,字符串 "5" 转换为数字 5
console.log(true == 1); // true,true 转换为数字 1
console.log(null == undefined); // true,null 和 undefined 在宽松相等下被视为相等
===
(严格相等,在大多数情况下,使用===
更为安全可靠。)
- 无类型转换: 直接比较值和类型,不进行类型转换。
- 严格比较: 值和类型都必须相同才返回
true
。
示例:
console.log(5 === "5"); // false,类型不同
console.log(true === 1); // false,类型不同
console.log(null === undefined); // false,类型不同
- 使用建议
- 推荐使用
===
: 避免类型转换带来的意外行为,代码更可预测。 - 谨慎使用
==
: 仅在明确需要类型转换时使用。
示例对比:
console.log(0 == false); // true,0 转换为 false
console.log(0 === false); // false,类型不同
JavaScript 中,null
和undefined
的区别是?
特性 | undefined | null |
---|---|---|
含义 | 未定义的值 | 显式的空值 |
类型 | "undefined" | "object" |
默认赋值 | 系统自动赋值 | 需手动赋值 |
null == undefined; | true | true |
null === undefined; | false | false |
XML的全拼是什么?中文名是什么?
eXtensible Markup Language,可扩展标记语言
XML和HTML的区别是什么?
相比 HTML,XML 的设计宗旨是存储和传输数据,而不是显示数据。
XML的声明标签是什么?
声明标签: <?xml version="1.0" encoding="UTF-8"?>
。
<?xml version="1.0" encoding="UTF-8"?>
<bookstore><book category="fiction"><title lang="en">Harry Potter</title><author>J.K. Rowling</author><year>2005</year><price>29.99</price></book><book category="non-fiction"><title lang="en">Learning XML</title><author>John Doe</author><year>2020</year><price>39.95</price></book>
</bookstore>
XML 和 JSON 有什么区别?
XML 和 JSON 的区别主要有以下几个方面:
特性 | XML | JSON |
---|---|---|
格式 | 标签和属性 | 键值对 |
可读性 | 低 | 高 |
文件大小 | 大 | 小 |
解析性能 | 慢 | 快 |
用途 | 数据存储、配置文件、Web 服务 | 数据交换、API 通信 |
常见的 HTML 解析方式有哪些?
常见的 HTML 解析器有哪些?
JSON和XML的格式有什么区别?
XML的格式是标签 + 属性,JSON 的格式是键值对。
XML和JSON哪一个的解析性能更高?
JSON
DTD全拼是什么?作用是什么?
Document Type Definition,用于定义 XML 文档结构。
XML文件的后缀名是什么?
.xml
为什么要避免在XML文档中使用属性?
相比通过属性来描述数据,通过标签来描述数据更具优势:
- 属性难以阅读和维护
- 属性不易扩展
- 属性无法描述树型结构
- 属性无法包含多重的值
XML 中,标签名可以以数字开头吗?可以包含数字吗?
标签名不能以数字开头,但是可以包含数字。
XML 中,标签名的命名有什么要求?
标签名的命名有以下几个条件:
- 不可以以数字或标点符号开始,
- 也不可以包含空格,会报错。
- XML文档中的标签是对大小写敏感的。
XML 中,标签对大小写敏感吗?
XML 中的标签对大小写是敏感的。
XML 中的实体引用有哪些?
XML中,有5预定义的实体引用:
<
:小于>
:大于&
:和号&
'
:单引号"
:双引号
XML 中,“小于”引用怎么写?
<
“大于”引用怎么写?
>
“单引号”引用怎么写?
'
“双引号”引用怎么写?
"
“和号”引用怎么写?
&
XML 约束的作用是什么?
XML 约束:用于定义 XML 文档的结构和内容规则,确保文档符合预定的格式和要求。
常见的 XML 约束技术有哪些?
常见的 XML 约束技术主要有两种:
- DTD(Document Type Definition )
- XML Schema
以及其它一些 XML 约束技术。
DTD示例:
<!DOCTYPE note [<!ELEMENT note (to, from, heading, body)><!ELEMENT to (PCDATA)><!ELEMENT from (PCDATA)><!ELEMENT heading (PCDATA)><!ELEMENT body (PCDATA)>
]>
此 DTD 定义了一个 note
元素,包含 to
、from
、heading
和 body
四个子元素,且这些子元素只能包含文本。
XML Schema示例:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:element name="note"><xs:complexType><xs:sequence><xs:element name="to" type="xs:string"/><xs:element name="from" type="xs:string"/><xs:element name="heading" type="xs:string"/><xs:element name="body" type="xs:string"/></xs:sequence></xs:complexType></xs:element>
</xs:schema>
此 Schema 定义了一个 note
元素,包含 to
、from
、heading
和 body
四个子元素,且这些子元素必须为字符串类型。
Schema 约束文件的后缀是什么?
.xsd
DTD 约束文件的扩展名是什么?
.dtd
如何导入 DTD 约束文件?
<!DOCTYPE note SYSTEM "D:\02-WEB\JAVA_WEB\homework\html_project\xml\xml约束\note.dtd">
JSON 是什么?
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,广泛用于 Web 应用程序中的数据传输和存储。
JSON 和 XML 有什么区别?
JSON 与 XML 的比较:
特性 | JSON | XML |
---|---|---|
格式 | 键值对 | 标签和属性 |
可读性 | 较好 | 较好 |
文件大小 | 较小 | 较大 |
解析性能 | 较快 | 较慢 |
数据类型 | 有限 | 支持复杂数据类型 |
用途 | 数据交换、配置文件 | 数据存储、配置文件、Web 服务 |
JSON 和 JavaScript 是什么关系?
JSON 与 JavaScript 的关系:
- JSON 是 JavaScript 的子集: JSON 的语法基于 JavaScript 的对象字面量。
- JavaScript 中的 JSON 支持:
JSON.parse()
: 将 JSON 字符串解析为 JavaScript 对象。JSON.stringify()
: 将 JavaScript 对象转换为 JSON 字符串。
示例:
// JSON 字符串
const jsonString = '{"name":"Alice","age":25}';// 解析为 JavaScript 对象
const obj = JSON.parse(jsonString);
console.log(obj.name); // 输出: Alice// 将 JavaScript 对象转换为 JSON 字符串
const newJsonString = JSON.stringify(obj);
console.log(newJsonString); // 输出: {"name":"Alice","age":25}
JSON 中,数组如何表示?
JSON 的基本语法:
- 键值对: 数据以键值对的形式表示,键和值之间用冒号
:
分隔。 - 对象: 使用花括号
{}
表示,键值对之间用逗号,
分隔。 - 数组: 使用方括号
[]
表示,元素之间用逗号,
分隔。 - 数据类型: 支持字符串、数字、布尔值、数组、对象和
null
。
示例:
{"name": "Alice","age": 25,"isStudent": false,"courses": ["Math", "Science"],"address": {"city": "Beijing","postalCode": "100000"},"graduated": null
}
JSON 的局限性有哪些?
JSON 的局限性:
- 不支持注释: JSON 标准不支持注释。
- 数据类型有限: 仅支持字符串、数字、布尔值、数组、对象和
null
。 - 不适合存储复杂数据: 对于二进制数据或复杂数据结构,可能需要其他格式(如 XML、Protocol Buffers)。
Fastjson 是什么?
Fastjson 是阿里巴巴开源的一个高性能 Java 库,用于处理 JSON 数据。它能够将 Java 对象序列化为 JSON 字符串,并将 JSON 字符串反序列化为 Java 对象。
Fastjson 的主要功能有哪些?
Fastjson 的主要功能
- 序列化: 将 Java 对象转换为 JSON 字符串。
- 反序列化: 将 JSON 字符串转换为 Java 对象。
- 支持注解: 通过注解控制序列化和反序列化的行为。
- 支持泛型: 可以处理泛型类型的对象。
- 自定义序列化: 支持自定义序列化和反序列化逻辑。
JSON 字符串转为 Java 对象是序列化还是反序列化?
反序列化
Fastjson 中,最常用的类是哪一个?
如何将java对象转JSON字符串?
如何将JSON字符串转java对象?
@JSONField(serialize = false)
有什么意义?
使用注解
Fastjson 提供注解来控制序列化和反序列化的行为。
示例:
import com.alibaba.fastjson.annotation.JSONField;public class User {@JSONField(name = "user_name")private String name;@JSONField(serialize = false)private int age;// 构造函数、getter 和 setter 省略public static void main(String[] args) {User user = new User();user.setName("Alice");user.setAge(25);String jsonString = JSON.toJSONString(user);System.out.println(jsonString); // 输出: {"user_name":"Alice"}}
}
常用的JSON库有哪些?其中最常用的是哪一个?
Fastjson 如何使用?
(1) 添加依赖
在 Maven 项目中添加 Fastjson 依赖:
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version>
</dependency>
(2) 序列化(Java 对象 → JSON 字符串)
import com.alibaba.fastjson.JSON;public class User {private String name;private int age;// 构造函数、getter 和 setter 省略public static void main(String[] args) {User user = new User();user.setName("Alice");user.setAge(25);String jsonString = JSON.toJSONString(user);System.out.println(jsonString); // 输出: {"age":25,"name":"Alice"}}
}
(3) 反序列化(JSON 字符串 → Java 对象)
import com.alibaba.fastjson.JSON;public class User {private String name;private int age;// 构造函数、getter 和 setter 省略public static void main(String[] args) {String jsonString = "{\"name\":\"Alice\",\"age\":25}";User user = JSON.parseObject(jsonString, User.class);System.out.println(user.getName()); // 输出: AliceSystem.out.println(user.getAge()); // 输出: 25}
}
Fastjson 的缺点是什么?
Fastjson 的安全性问题
Fastjson 在过去曾多次被发现存在安全漏洞(如反序列化漏洞),因此在使用时需要谨慎:
- 及时更新: 使用最新版本以修复已知漏洞。
- 避免反序列化不可信数据: 防止恶意数据导致的安全问题。
Vue 是什么?
全名:Vue.js
作用:用于构建用户界面的渐进式JavaScript框架,是前端开发中最流行的框架之一。
示例代码:
<div id="app">{{ message }}
</div><script>var app = new Vue({el: 'app',data: {message: 'Hello Vue!'}});
</script>
Vue 中文文档的网址是什么?
中文文档网址: https://vuejs.bootcss.com/guide/
Vue 中,常用的指令有哪些?
- v-bind:为HTML标签绑定属性值,如设置 href,css样式等
- v-model:在表单元素上创建双向数据绑定
- V-on:为HTML标签绑定事件
- V-if:条件性的渲染某元素,判定为true时渲染,否则不渲染
- v-else:条件性渲染某元素 执行 else语句
- v-else-if:条件性渲染某元素 执行 else if语句 判断
- v-show:根据条件展示某元素,区别在于切换的是display属性的值
- v-for:列表渲染,遍历容器的元素或者对象的属性
MVVM中的各个元素分别是什么意义?
- M:
- V:
- V:
- M:
Vue.js
的核心是什么?
Vue.js
的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:
如何引入vue.js
文件?
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
如何使用v-once
指令插值?
<span>Message: {{ message }}</span><!--只插值一次-->
<span v-once>{{message}}</span>
v-bind
指令如何使用?
<div id="app"><a v-bind:href="url"> 点击我 </a><a :href="url"> 点击我 </a>
</div>
v-model
指令如何使用?
<div id="app"><a v-bind:href="url"> 点击我 </a><input v-model="url" placeholder="输入修改"><textarea v-model="message" placeholder="add multiple lines"></textarea>
</div>
条件渲染指令如何使用?
<div id="app"><span v-if="number == 1"> 星期一</span><span v-else-if="number == 2"> 星期二</span><span v-else-if="number == 3"> 星期三</span><span v-else-if="number == 4"> 星期四</span><span v-else-if="number == 5"> 星期五</span><span v-else-if="number == 6"> 星期六</span><span v-else> 星期天</span><input v-model="number">
</div>
列表渲染v-for
指令如何使用?
<li v-for="(item,i) in items" :key="item.course">{{i+1}}:{{ item.course }}
</li>
事件处理v-on
指令如何使用?
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head><meta charset="UTF-8"><title>Title</title><script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app"><button v-on:click="counter += 1">点击次数加 1</button><button v-on:click="add('what')">点击</button><p>已经点击的次数 {{ counter }} </p>
</div><script>var app = new Vue({el: '#app',data: {items:[{course:'java'},{course:'mysql'},{course:'spring'}],counter:0},methods:{add:function (hi) {alert('Hello ' + hi)}}})
</script>
</body>
</html>
Element
中文学习地址是什么?
https://element.eleme.cn/#/zh-CN/component/installation
Element是什么?
Element(通常称为 Element UI 或 Element Plus)是一套基于 Vue.js 的开源 UI 组件库,专为开发者提供丰富的、高质量的组件,用于快速构建企业级中后台前端应用。
Element 的常用组件有哪些?
- 基础组件:按钮(Button)、输入框(Input)、布局(Layout)等。
- 表单组件:表单(Form)、选择器(Select)、日期选择器(DatePicker)等。
- 数据展示:表格(Table)、标签(Tag)、卡片(Card)等。
- 导航组件:菜单(Menu)、面包屑(Breadcrumb)等。
- 反馈组件:对话框(Dialog)、消息提示(Message)、加载(Loading)等。
如何安装与使用 Element ?
安装 Element Plus(Vue 3)
npm install element-plus --save
在项目中引入
import { createApp } from 'vue';
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';
import App from './App.vue';const app = createApp(App);
app.use(ElementPlus);
app.mount('app');
示例代码
<template><el-button type="primary">点击我</el-button>
</template><script>
export default {name: 'App',
};
</script>
Element 的资源有哪些?
- 官网:
- Element UI(Vue 2):https://element.eleme.io/
- Element Plus(Vue 3):https://element-plus.org/
- GitHub:
- Element UI:https://github.com/ElemeFE/element
- Element Plus:https://github.com/element-plus/element-plus
如何引入 Element 文件?
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><!--引入js 和 css--><script src="/js/vue.js"></script><script src="/element-ui/lib/index.js"></script><link rel="stylesheet" href="/element-ui/lib/theme-chalk/index.css">
</head>
<body></body>
</html>
如何创建Vue
对象?
<div id="app"></div>
<script>new Vue({el:'#app'})
</script>
Ajax 是什么
Ajax(Asynchronous JavaScript and XML,异步 JavaScript 和 XML)是一种用于创建快速动态网页的技术。它允许网页在不重新加载整个页面的情况下,与服务器进行异步通信并更新部分页面内容,常见场景如搜索框中,输入关键字后,可以即时生成下拉框中的内容。
什么是“异步通信”?
异步通信:Ajax 可以在后台与服务器交换数据,而不会阻塞用户的操作或刷新页面。
什么是“局部更新”?
局部更新:只更新网页的某一部分,而不是整个页面,提升了用户体验。
Ajax 的工作原理是什么?
Ajax 工作原理:
- 用户触发事件(如点击按钮)。
- JavaScript 创建一个
XMLHttpRequest
对象(或使用fetch
API)。 - 通过该对象向服务器发送请求。
- 服务器处理请求并返回数据(通常是 JSON 或 XML 格式)。
- JavaScript 解析返回的数据并更新网页内容。
Ajax 的使用场景有哪些?
- 表单验证:实时验证用户输入,无需刷新页面。
- 动态加载内容:如无限滚动、分页加载等。
- 自动补全:搜索框的自动补全功能。
- 实时更新:如聊天应用、通知系统等。
- 交互式网页:提升用户体验,减少页面刷新。
Ajax 的实现方式是什么?
使用 XMLHttpRequest
对象
// 创建 XMLHttpRequest 对象
var xhr = new XMLHttpRequest();// 设置请求方法和 URL
xhr.open('GET', 'https://api.example.com/data', true);// 设置回调函数
xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {var response = JSON.parse(xhr.responseText);console.log(response);}
};// 发送请求
xhr.send();
使用 fetch
API(现代方式)
fetch('https://api.example.com/data').then(response => response.json()).then(data => console.log(data)).catch(error => console.error('Error:', error));
Ajax 的优点是什么?
优点:
- 提升用户体验:页面无需刷新,操作更加流畅。
- 减少带宽消耗:只传输需要的数据,而不是整个页面。
- 提高性能:局部更新比重新加载页面更快。
Ajax 的缺点有哪些?
缺点:
- SEO 不友好:搜索引擎可能无法抓取通过 Ajax 动态加载的内容。
- 浏览器兼容性:虽然现代浏览器都支持 Ajax,但旧版浏览器可能需要额外处理。
- 复杂性:需要处理异步编程和错误处理。
axios 是什么?
Axios 是一个基于 Promise 的现代化 HTTP 客户端库,专门为浏览器和 Node.js 环境设计,用于发送异步 HTTP 请求。
axios 的官网是?
https://www.axios-http.cn/docs
如何引入 axios?
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
如何调用 axios?
axios.get('/ajax').then(function (response) {// 处理成功情况 console.log(response);}).catch(function (error) {// 处理错误情况console.log(error);}).then(function () {// 总是会执行});
axios 如何使用?
安装
npm install axios或
yarn add axios
发起请求
// GET 请求
axios.get('/user?ID=12345').then(response => console.log(response)).catch(error => console.error(error));// POST 请求
axios.post('/user', { firstName: 'John', lastName: 'Doe' }).then(response => console.log(response));
为什么说HTTP是“无状态”的协议 | |
为什么使用HTTP协议的时候,要配合Cookie或Session来保留客户端的状态信息 | |
HTTP的请求和响应消息格式 | |
HTTP的工作流程 |
HTTP 请求组成部分 | |
---|---|
请求行包含哪些信息? | |
常见的请求方法有哪些? | |
为什么GET请求的数据量有大小的限制,而POST请求则没有大小的限制? | |
HEAD请求和GET请求的区别是什么? | |
HTTP 响应由哪些部分组成? | |
4xx是什么含义? | 重要 |
5xx是什么含义? | |
HTTP/1.0 和HTTP/1.1 的区别是什么? | |
HTTP 与 HTTPS的区别是什么? | 重要 |
OSI 模型分为几层?分别是什么? | |
---|---|
TCP/IP模型分为几层?分别是什么? | |
OSI 和 TCP/IP 中,哪一个是理论模型,哪一个 是实际应用模型? |
TCP全拼是什么?中文是什么? | |
---|---|
UDP全拼是什么?中文是什么? | |
TCP 的应用场景有哪些? | |
UDP 的应用场景有哪些? | |
HTTP属于哪一层的协议?TCP 和 UDP 属于哪一层的协议? | !!!! |
TCP和UDP的区别是什么? | !!!! |
TCP和UDP中,当传输的数据量较大时,应该采用哪种协议? | 要进一步分析 |
TCP和UDP中,当对可靠性要求较高时,应该采用哪种协议? | |
TCP和UDP中,当实时性要求较高时,应该采用哪种协议? | |
TCP建立连接的三次握手是如何进行的? | |
TCP关闭连接的四次挥手是如何进行的? | |
如果数据包丢失或损坏,UDP 协议会如何处理? | |
UDP 协议中,数据包的顺序有什么特点? |
HTTP是什么?
HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网上应用最广泛的协议之一,用于在客户端(如浏览器)和服务器之间传输数据。它是 Web 通信的基础,支持浏览器访问网页、提交表单、下载文件等操作。
HTTP 协议属于五层模型中的哪一层?
应用层。
HTTP 的基本特点有哪些?
HTTP 的基本概念
- 协议类型:HTTP 是一种应用层协议,基于请求-响应模型。
- 通信方式:客户端发送请求(Request),服务器返回响应(Response)。
- 无状态协议:HTTP 本身是无状态的,每个请求都是独立的,服务器不会保留客户端的状态信息(除非使用 Cookie 或 Session 等技术)。
- 基于文本:HTTP 的请求和响应消息是文本格式的,易于阅读和调试。
什么是“无状态协议”?
HTTP 是无状态协议:HTTP 本身是无状态的,每个请求都是独立的,服务器不会保留客户端的状态信息(除非使用 Cookie 或 Session 等技术)。
HTTP 的工作流程是什么?
工作流程:
- 建立连接:客户端(如浏览器)通过 TCP/IP 协议与服务器建立连接(默认端口为 80,HTTPS 为 443)。
- 发送请求:客户端向服务器发送 HTTP 请求,请求中包含方法(如 GET、POST)、URL、头信息和可选的消息体。
- 处理请求:服务器接收请求并处理,可能会访问数据库、调用其他服务等。
- 返回响应:服务器向客户端返回 HTTP 响应,响应中包含状态码、头信息和消息体(如 HTML、JSON 等)。
- 关闭连接:在 HTTP/1.0 中,每次请求后连接会关闭;在 HTTP/1.1 及更高版本中,默认使用持久连接(Keep-Alive),可以在一次连接中发送多个请求。
HTTP 请求的组成部分有哪些?
HTTP 请求由以下部分组成:
请求行:包含请求方法、URL 和 HTTP 版本。
- 示例:
GET /index.html HTTP/1.1
请求头:包含客户端信息、请求条件等。
- 示例:
Host: www.example.com User-Agent: Mozilla/5.0 Accept: text/html
请求体:可选部分,通常用于 POST 或 PUT 请求,包含提交的数据。
- 示例:
username=admin&password=123456
示例
以下是一个简单的 HTTP 请求和响应的示例:
请求:
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html
响应:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1234<html><body><h1>Hello, World!</h1></body>
</html>
常见的请求方法有哪些?
常见的请求方法:
- GET:请求指定的资源,通常用于获取数据。(数据量一般有大小限制)
- POST:向服务器提交数据,通常用于表单提交或上传文件。(数据量一般没有大小限制)
- PUT:更新服务器上的资源。
- DELETE:删除服务器上的资源。
- HEAD:类似于 GET,但只返回响应头,不返回响应体。
- OPTIONS:获取服务器支持的 HTTP 方法。
HTTP 响应的组成部分有哪些?
HTTP 响应由以下部分组成:
状态行:包含 HTTP 版本、状态码和状态描述。
- 示例:
HTTP/1.1 200 OK
响应头:包含服务器信息、响应条件等。
- 示例:
Content-Type: text/html Content-Length: 1234
响应体:包含服务器返回的数据(如 HTML、JSON 等)。
- 示例:
<html><body><h1>Hello, World!</h1></body> </html>
示例
以下是一个简单的 HTTP 请求和响应的示例:
请求:
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0
Accept: text/html
响应:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1234<html><body><h1>Hello, World!</h1></body>
</html>
常见的状态码都是什么含义?
- 1xx(信息性状态码):表示请求已被接收,继续处理。
- 示例:
100 Continue
- 示例:
- 2xx(成功状态码):表示请求已成功处理。
- 示例:
200 OK
、201 Created
- 示例:
- 3xx(重定向状态码):表示需要进一步操作以完成请求。
- 示例:
301 Moved Permanently
、302 Found
- 示例:
- 4xx(客户端错误状态码):表示客户端请求有误。
- 示例:
400 Bad Request
、404 Not Found
- 示例:
- 5xx(服务器错误状态码):表示服务器处理请求时出错。
- 示例:
500 Internal Server Error
、503 Service Unavailable
- 示例:
HTTP 与 HTTPS 有什么区别?
- HTTP:明文传输,数据容易被窃听或篡改。
- HTTPS:在 HTTP 基础上增加了 SSL/TLS 加密层,确保数据传输的安全性。
- 默认端口为 443。
- 使用数字证书验证服务器身份。
HTTP和TCP、UDP是什么关系?
HTTP、TCP 和 UDP 是计算机网络中不同层次的协议,它们之间的关系可以通过 OSI 模型 或 TCP/IP 模型 来理解。
HTTP、TCP 和 UDP 的层次关系
- HTTP:属于 应用层协议,用于定义客户端和服务器之间的通信规则(如请求和响应的格式)。
- TCP 和 UDP:属于 传输层协议,用于在网络上可靠地或高效地传输数据。
具体关系:
- HTTP 依赖于 TCP:
- HTTP 是基于 TCP 协议实现的。TCP 提供可靠的、面向连接的通信服务,确保数据按顺序传输且不丢失。
- 当客户端通过 HTTP 请求访问网页时,底层是通过 TCP 建立连接并传输数据的。
- HTTP 不直接使用 UDP:
- UDP 是无连接的、不可靠的传输协议,适用于对实时性要求高但允许少量数据丢失的场景(如视频流、在线游戏)。
- HTTP 通常不直接使用 UDP,但某些基于 HTTP 的协议(如 HTTP/3)使用 UDP 作为底层传输协议。
OSI 模型有哪些层?
OSI 模型将网络通信分为 7 层:
- 物理层(Physical Layer)
- 数据链路层(Data Link Layer)
- 网络层(Network Layer)
- 传输层(Transport Layer)
- 会话层(Session Layer)
- 表示层(Presentation Layer)
- 应用层(Application Layer)
TCP/IP 模型有哪些层?
TCP/IP 模型将网络通信分为 4 层:
- 网络接口层(Network Interface Layer)
- 网络层(Internet Layer)
- 传输层(Transport Layer)
- 应用层(Application Layer)
TCP 和 UDP 的区别是什么?
特性 | TCP(传输控制协议) | UDP(用户数据报协议) |
---|---|---|
连接方式 | 面向连接(需要三次握手建立连接) | 无连接(直接发送数据) |
可靠性 | 可靠(确保数据不丢失、不重复、按顺序到达) | 不可靠(可能丢失、重复或乱序) |
传输效率 | 较低(需要维护连接状态和确认机制) | 较高(无需维护连接状态) |
适用场景 | 对可靠性要求高的场景(如网页浏览、文件传输) | 对实时性要求高的场景(如视频流、在线游戏) |
头部开销 | 较大(20 字节) | 较小(8 字节) |
HTTP 和 TCP 的组合工作流程是什么?
一、建立 TCP 连接:
- 客户端和服务器通过三次握手建立 TCP 连接。
- 示例:
客户端 -> 服务器:SYN 客户端 <- 服务器:SYN-ACK 客户端 -> 服务器:ACK
二、发送 HTTP 请求:
- 客户端通过 TCP 连接发送 HTTP 请求。
- 示例:
GET /index.html HTTP/1.1 Host: www.example.com
三、接收 HTTP 响应:
- 服务器通过 TCP 连接返回 HTTP 响应。
- 示例:
HTTP/1.1 200 OK Content-Type: text/html Content-Length: 1234<html>...</html>
四、关闭 TCP 连接:
- 客户端和服务器通过四次挥手关闭 TCP 连接。
- 示例:
客户端 -> 服务器:FIN 客户端 <- 服务器:ACK 客户端 <- 服务器:FIN 客户端 -> 服务器:ACK
OSI 模型和 TCP/IP 模型的主要区别有哪些?
主要区别:
- 层数:OSI 有七层,TCP/IP 有四层。
- 用途:OSI 是理论模型,TCP/IP 是实际应用模型。
- 协议:OSI 不绑定特定协议,TCP/IP 与特定协议(如 TCP、IP)紧密相关。
总结:OSI 模型提供理论框架,TCP/IP 模型是互联网的实际基础。
TCP是什么?
TCP(传输控制协议,Transmission Control Protocol)是一种面向连接的、可靠的传输层协议,主要用于在网络上可靠地传输数据。它是 TCP/IP 协议族的核心协议之一,广泛应用于互联网通信中。
TCP 的主要特点有哪些?
-
面向连接:
- 在数据传输前,通信双方需要通过“三次握手”建立连接。
- 数据传输结束后,通过“四次挥手”释放连接。
-
可靠性:
- 通过确认机制(ACK)、重传机制和校验和确保数据准确无误地传输。
- 如果数据丢失或损坏,TCP 会重新发送数据。
-
有序性:
- 数据按发送顺序到达接收方,TCP 会对数据包进行排序。
-
流量控制:
- 通过滑动窗口机制,防止发送方发送数据过快导致接收方无法处理。
-
拥塞控制:
- 通过动态调整发送速率,避免网络拥塞。
TCP 的工作原理是什么?
TCP 的工作有三个阶段:建立连接、传输数据、释放连接:
- 建立连接(三次握手):
- 客户端发送 SYN 报文给服务器,请求建立连接。
- 服务器回复 SYN-ACK 报文,表示同意建立连接。
- 客户端发送 ACK 报文,确认连接建立。
- 数据传输:
- 数据被分割成 TCP 段,每个段都有序号和确认号。
- 接收方收到数据后发送 ACK 确认,发送方根据确认决定是否重传。
- 释放连接(四次挥手):
- 客户端发送 FIN 报文,请求关闭连接。
- 服务器回复 ACK 报文,确认关闭请求。
- 服务器发送 FIN 报文,请求关闭连接。
- 客户端回复 ACK 报文,确认关闭连接。
TCP 的优点有哪些?
优点:
- 可靠性高,适合对数据完整性要求高的场景。
- 支持流量控制和拥塞控制,适应复杂网络环境。
TCP 的缺点有哪些?
缺点:
- 由于建立连接和确认机制,传输效率较低。
- 不适合实时性要求高的应用(如视频流、在线游戏),这些场景通常使用 UDP。
UDP是什么?
UDP(用户数据报协议,User Datagram Protocol)是一种无连接的、简单的传输层协议,主要用于在网络上快速传输数据。与 TCP 不同,UDP 不提供可靠性保证,但具有低延迟和高效率的特点,适用于对实时性要求较高的应用场景。
UDP 的主要特点有哪些?
-
无连接:
- 通信前不需要建立连接,直接发送数据。
- 数据传输结束后也不需要释放连接。
-
不可靠性:
- 不保证数据包的顺序、完整性或可靠性。
- 如果数据包丢失或损坏,UDP 不会重传。
-
高效性:
- 由于没有连接建立、确认和重传机制,UDP 的开销更小,传输速度更快。
-
支持广播和多播:
- UDP 可以向多个接收方同时发送数据(广播和多播)。
UDP 的工作原理是什么?
-
发送数据:
- 应用程序将数据交给 UDP,UDP 添加头部信息后直接发送。
- 不等待接收方的确认,也不关心数据是否到达。
-
接收数据:
- 接收方从网络中获取 UDP 数据包,交给应用程序处理。
- 不保证数据包的顺序或完整性。
UDP 的优点有哪些?
优点:
- 传输效率高,延迟低。
- 实现简单,开销小。
- 支持广播和多播。
UDP 的缺点有哪些?
缺点:
- 不保证数据可靠性,可能丢失或乱序。
- 没有流量控制和拥塞控制,可能导致网络拥塞。
UDP 与 TCP 的区别有哪些?
特性 | UDP | TCP |
---|---|---|
连接方式 | 无连接 | 面向连接 |
可靠性 | 不可靠 | 可靠 |
数据传输效率 | 高 | 较低 |
数据顺序 | 不保证 | 保证 |
头部开销 | 小(8 字节) | 大(至少 20 字节) |
适用场景 | 实时应用(视频、游戏、语音) | 可靠传输(网页、文件、邮件) |
EL表达式是什么
EL(Expression Language)表达式是一种用于在JSP(JavaServer Pages)和JSF(JavaServer Faces)等Java Web应用中简化数据访问的表达式语言。它主要用于在JSP页面中嵌入动态内容,访问JavaBean属性、集合、请求参数、会话属性等。
EL 表达式的基本语法有哪些?
- 访问Bean属性:
${user.name}
- 访问集合元素:
${users[0].name}
- 访问请求参数:
${param.username}
- 访问会话属性:
${sessionScope.user}
- 条件判断:
${user.age > 18 ? "Adult" : "Minor"}
示例
假设有一个JavaBean User
:
public class User {private String name;private int age;// getters and setters
}
在JSP页面中使用EL表达式:
<p>User Name: ${user.name}</p>
<p>User Age: ${user.age}</p>
<p>Is Adult: ${user.age > 18 ? "Yes" : "No"}</p>
JSTL 标签是什么
JSTL(JavaServer Pages Standard Tag Library)是Java EE中的一组标准标签库,用于简化JSP页面的开发。它提供了一系列标签,帮助开发者在JSP中执行常见任务,如循环、条件判断、数据格式化等,减少Java代码的嵌入,使页面更简洁易读。
如何引入 JSTL 标签?
引入JSTL标签:
<dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>1.2</version>
</dependency><dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version>
</dependency>
JSTL 的常用标签有哪些?
-
核心标签(Core Tags):
<c:out>
:输出表达式结果。<c:set>
:设置变量值。<c:remove>
:删除变量。<c:if>
:条件判断。<c:choose>
、<c:when>
、<c:otherwise>
:多条件判断。<c:forEach>
:循环遍历集合或数组。<c:forTokens>
:按分隔符遍历字符串。
-
格式化标签(Formatting Tags):
<fmt:formatNumber>
:格式化数字。<fmt:parseNumber>
:解析数字字符串。<fmt:formatDate>
:格式化日期。<fmt:parseDate>
:解析日期字符串。<fmt:setLocale>
:设置本地化环境。<fmt:setTimeZone>
:设置时区。
-
SQL标签(SQL Tags):
<sql:setDataSource>
:设置数据源。<sql:query>
:执行SQL查询。<sql:update>
:执行SQL更新。<sql:param>
:设置SQL参数。<sql:dateParam>
:设置SQL日期参数。
-
XML标签(XML Tags):
<x:parse>
:解析XML文档。<x:out>
:输出XPath表达式结果。<x:set>
:设置XPath表达式结果。<x:if>
:条件判断。<x:choose>
、<x:when>
、<x:otherwise>
:多条件判断。<x:forEach>
:循环遍历XML节点。
-
函数标签(Function Tags):
- 提供字符串处理函数,如
fn:contains
、fn:substring
等。
- 提供字符串处理函数,如
使用示例
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %><c:set var="name" value="World" />
<c:if test="${not empty name}"><p>Hello, <c:out value="${name}" />!</p>
</c:if><c:forEach items="${product}" var="i" begin="1" end="5"><tr align="center"><td>${i.id}</td><td>${i.name}</td><td>${i.price}</td><td><a href="#">编辑</a><a href="#">删除</a></td></tr>
</c:forEach><fmt:formatNumber value="12345.678" type="currency" />
Cookie与Session是什么?
Cookie和Session是用于在Web应用中管理用户状态的两种常见会话跟踪技术。
Cookie
- 定义:Cookie是由服务器发送到用户浏览器并保存在本地的一小段数据,浏览器会在后续请求中将Cookie发送回服务器。
- 特点:
- 存储位置:客户端(浏览器)。
- 生命周期:可设置过期时间,可以是会话结束时失效,也可以长期保存。
- 大小限制:通常每个Cookie不超过4KB。
- 安全性:相对较低,容易被篡改或窃取。
- 用途:常用于保存用户偏好、登录状态、购物车信息等。
Session
- 定义:Session是服务器端存储的用户会话数据,每个用户会话都有一个唯一的Session ID,通常通过Cookie传递给客户端。
- 特点:
- 存储位置:服务器端。
- 生命周期:用户会话期间有效,通常用户关闭浏览器后失效。
- 大小限制:理论上无限制,但受服务器内存限制。
- 安全性:较高,因为数据存储在服务器端。
- 用途:常用于保存用户的登录状态、购物车内容等敏感信息。
使用场景
- Cookie:适合存储不敏感的小数据,如用户偏好、跟踪信息。
- Session:适合存储敏感数据,如用户登录状态、购物车内容。
如何创建 Cookie 对象?
创建 Cookie 对象:
Cookie cookie = new Cookie(String name, String value)
Cookie 常用方法有哪些?
String getName()String getValue()
如何响应Cookie 给客户端?
void addCookie(Cookie cookie)
如何获取 Cookie?
Cookie[] getCookies()
如何设置Cookie 有效期设置?
设置 Cookie 存活时间:
public void setMaxAge(int expiry)
。
- 设置0 :删除 Cookie,
cookie.setMaxAge(0);
。- 正数:设置过期时间,到时间自动删除,
cookie.setMaxAge(24*60*60);
。- 负数:关闭浏览器同时关闭Cookie,
cookie.setMaxAge(-1);
。
如何获取 Session 对象?
获取 Session 对象:
HttpSession getSession()
//Returns the current session associated with this request, or if the request does not have a session, creates one.
如何设置值进 Session 中?
void setAttribute(String name,Object value);
如何从 Session 中取值?
Object getAttribute(String name);
如何从 Session 中删除属性?
void removeAttribute(String name);
什么是 Session 的钝化与活化?
钝化与活化的目的是为了存储session,保证正常关闭下正常启动的时候,同一会话有效。
- 服务器正常关闭的时候,tomcat 会把 session 数据写入硬盘work 目录下(sessions.ser文件)
- 服务器启动的时候,tomcat 读取 sessions.ser 中的数据,并且删掉这个文件(删掉是为了减少不需要的钝化文件污染磁盘,造成磁盘空间的浪费)
Cookie与Session的区别有哪些?
区别 | Cookie | Session |
---|---|---|
存储位置 | 客户端 | 服务器端 |
生命周期 | 可以长期保存 | 默认30分钟,通常在会话结束时失效 |
存储数据大小 | 最大3KB | 无限制 |
安全性 | 不安全 | 安全 |
服务器性能影响 | 不占用服务器资源 | 占用服务器资源 |
Cookie 与 Session 的应用场景有什么区别?
使用场景
- Cookie:适合存储不敏感的小数据,如用户偏好、跟踪信息。
- Session:适合存储敏感数据,如用户登录状态、购物车内容。
如何销毁 Session
Session 的销毁分为两种方式:
- 自动销毁:默认情况下无操作 30分钟
- 手动销毁
设置自动销毁:
<!--web.xml -->
<web-app><display-name>Archetype Created Web Application</display-name><session-config><session-timeout>33333</session-timeout></session-config>
</web-app>
手动销毁Session
void invalidate()
//Invalidates this session then unbinds any objects bound to it.
请求转发和重定向的有什么区别?
区别 | 请求转发(Forward) | 重定向(Redirect) |
---|---|---|
定义 | 服务器内部的跳转,客户端(浏览器)并不知道跳转的发生。 | 服务器告诉客户端去请求一个新的URL,客户端会发起新的请求。 |
实现方式 | 在Servlet中使用RequestDispatcher 的forward() 方法。 | 在Servlet中使用response.sendRedirect() 方法。 |
在JSP中使用<jsp:forward> 标签。 | 在JSP中使用response.sendRedirect() 。 | |
地址栏 | 地址栏不变 | 地址栏改变 |
请求次数 | 客户端发起一次请求 | 客户端发起两次请求 |
数据共享 | 转发前后的页面共享同一个request 对象,共享请求数据。 | 不共享请求数据,之前的request 对象中的数据会丢失。 |
效率 | 服务器内部操作,不需要额外的网络请求,效率较高 | 需要额外的网络请求,效率较低 |
使用场景 | 需要在多个页面或Servlet之间共享数据时 | 需要跳转到外部网站或不同应用时 |
不希望客户端知道跳转的目标地址时 | 需要让客户端知道跳转的目标地址时 | |
需要防止表单重复提交(通过重定向到结果页面)时 |
请求转发(Forward)示例:
RequestDispatcher dispatcher = request.getRequestDispatcher("target.jsp");
dispatcher.forward(request, response);
重定向(Redirect)示例:
response.sendRedirect("target.jsp");
可以共享数据的是哪种跳转方式?
请求转发
客户端发起的请求数量更多的是哪种跳转方式?
重定向
JDBC 全拼是什么?
Java DataBase Connectivity。
JDBC 的主要功能有哪些?
主要功能 | 介绍 | |
---|---|---|
1 | 连接数据库 | 通过DriverManager 或DataSource 建立与数据库的连接。 |
2 | 执行SQL语句 | 支持执行查询、更新等SQL操作。 |
3 | 处理结果集 | 通过ResultSet 处理查询结果。 |
4 | 事务管理 | 支持事务的提交和回滚。 |
JDBC 相关的核心接口和类有哪些?
核心接口和类 | 类型 | 介绍 |
---|---|---|
DriverManager(驱动管理对象) | 管理数据库驱动。 | |
Connection(数据库连接对象) | 获取连接。 | |
Statement、PreparedStatement、CallableStatement(执行SQL语句的对象) | 接口 | 执行SQL语句。 |
ResultSet(结果集对象) | 存储查询结果。 |
Statement、PreparedStatement、CallableStatement的区别是什么?
区别 | Statement | PreparedStatement | CallableStatement |
---|---|---|---|
作用 | 最基本的SQL执行接口 | 可以高效执行多次相同结构的SQL | 执行SQL语句 |
特点 | 每次执行时都会将SQL语句发送到数据库进行编译 | 预编译SQL语句,性能更高 | 专用于调用数据库存储过程,支持输入(IN)、输出(OUT)和输入输出(INOUT)参数,可以处理复杂的返回值 |
关系 | 父接口 | 继承自Statement接口 | 继承自PreparedStatement接口 |
SQL注入 | 容易产生SQL注入漏洞 | 使用参数化查询,防止SQL注入 | |
使用场景 | 执行简单、一次性或不含参数的SQL语句 | 需要多次执行相同SQL但参数不同时 | 调用数据库存储过程 |
需要防止SQL注入时 | 需要处理多个输出参数时 | ||
处理二进制数据(如BLOB)时 |
总结:
- 优先使用PreparedStatement,因为它安全且高效
- 只有在调用存储过程时才使用CallableStatement
- 避免使用Statement,除非是执行非常简单的静态SQL
Statement 示例:
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users");
PreparedStatement 示例:
PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM users WHERE username = ? AND password = ?");
pstmt.setString(1, username);
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();
CallableStatement示例:
CallableStatement cstmt = conn.prepareCall("{call get_employee_data(?, ?)}");
cstmt.setInt(1, employeeId); // 设置输入参数
cstmt.registerOutParameter(2, Types.VARCHAR); // 注册输出参数
cstmt.execute();
String result = cstmt.getString(2); // 获取输出参数
JDBC 的使用步骤是什么?
流程 | ||
---|---|---|
1 | 加载数据库驱动 | 使用Class.forName() 加载数据库驱动。 |
2 | 建立数据库连接 | 通过DriverManager.getConnection() 获取连接。 |
3 | 创建 Statement 对象 | 使用Connection 创建Statement 对象。 |
4 | 执行SQL | 通过Statement 或PreparedStatement 执行SQL语句。 |
5 | 处理结果 | 使用ResultSet 处理查询结果。 |
6 | 关闭资源 | close() 方法依次关闭ResultSet 、Statement 和Connection 。 |
示例代码
import java.sql.*;public class JDBCExample {public static void main(String[] args) {String url = "jdbc:mysql://localhost:3306/mydatabase";String user = "username";String password = "password";try (Connection conn = DriverManager.getConnection(url, user, password);Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery("SELECT * FROM mytable")) {while (rs.next()) {System.out.println(rs.getString("column_name"));}} catch (SQLException e) {e.printStackTrace();}}
}
JDBC的缺点有哪些?
缺点 | 备注 |
---|---|
性能较低 | 相比ORM框架,性能稍差。 |
代码冗余 | 需要手动管理资源和异常。 |
excute、excuteQuery、excuteUpdate的区别是什么?
区别 | excute | excuteQuery | excuteUpdate |
---|---|---|---|
适用SQL类型 | 任何类型 | 专用于 SELECT 语句 | 专用于 INSERT、UPDATE、DELETE 等DML语句和 CREATE TABLE 等 DDL 语句 |
返回值 | boolean 值 | ResultSet 对象(结果集) | int 值(表示受影响的行数) |
execute()
示例:
boolean hasResultSet = stmt.execute(sql);
if (hasResultSet) {ResultSet rs = stmt.getResultSet();// 处理结果集
} else {int updateCount = stmt.getUpdateCount();// 处理更新计数
}
executeQuery()
示例:
ResultSet rs = stmt.executeQuery("SELECT * FROM employees");
while (rs.next()) {// 处理每一行数据
}
executeUpdate()
示例:
int rowsAffected = stmt.executeUpdate("UPDATE employees SET salary = salary + 1000");
System.out.println("更新了 " + rowsAffected + " 行记录");
excute()
的返回值为 true 和 false 时分别是什么含义?
注意 | |
---|---|
excute 的返回值为 true 时 | 表示执行的是查询语句(SELECT),有结果集返回 |
excute 的返回值为 false 时 | 表示执行的是更新语句(INSERT, UPDATE, DELETE等)或无结果集的语句 |
如果执行的是 SELECT 语句,但是没有结果集返回,返回结果是 true 还是 false ?
executeUpdate()
执行 DDL 语句时,返回值是多少?
注意 | |
---|---|
executeUpdate | 执行 DDL (数据定义语言)语句如 CREATE TABLE时,返回值为0 。 |
什么是事务的 ACID 特性?
原子性(Atomicity) | 事务中的所有操作要么全部完成,要么全部不执行 |
---|---|
一致性(Consistency) | 事务执行前后数据库保持一致状态 |
隔离性(Isolation) | 并发事务之间互不干扰 |
持久性(Durability) | 事务提交后结果永久保存,事务执行前后,数据库状态一致 |
JDBC 事务管理的核心方法有哪些?
方法 | 作用 |
---|---|
connection.setAutoCommit(false); | 开启事务,关闭自动提交 |
connection.commit(); | 提交事务,使所有操作永久生效 |
connection.rollback(); | 回滚事务,撤销所有未提交的操作 |
Savepoint savepoint = connection.setSavepoint("savepoint1"); | 设置保存点,可以通过conn.rollback(savepoint); 回滚到特定保存点 |
JDBC 是如何进行事务管理的?
JDBC完整事务处理示例:
Connection conn = null;
try {// 1. 获取连接conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "password");// 2. 关闭自动提交,开启事务conn.setAutoCommit(false);// 3. 执行SQL操作Statement stmt = conn.createStatement();stmt.executeUpdate("UPDATE accounts SET balance = balance - 100 WHERE user_id = 1");stmt.executeUpdate("UPDATE accounts SET balance = balance + 100 WHERE user_id = 2");// 4. 提交事务conn.commit();System.out.println("事务执行成功");} catch (SQLException e) {// 5. 发生异常时回滚if (conn != null) {try {conn.rollback();System.out.println("事务回滚");} catch (SQLException ex) {ex.printStackTrace();}}e.printStackTrace();
} finally {// 6. 恢复自动提交并关闭连接try {if (conn != null) {conn.setAutoCommit(true); // 恢复自动提交模式conn.close();}} catch (SQLException e) {e.printStackTrace();}
}
如何获得“数据库驱动连接对象”?
connection
是通过数据库驱动获得的连接对象:
Connection connection = DriverManager.getConnection(url, user, password);
JDBC 如何设置事务隔离级别
JDBC 支持设置不同的事务隔离级别:
// 设置隔离级别
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);// 可用的隔离级别常量:
// TRANSACTION_READ_UNCOMMITTED
// TRANSACTION_READ_COMMITTED (最常用)
// TRANSACTION_REPEATABLE_READ
// TRANSACTION_SERIALIZABLE
数据库连接池的作用有哪些?
作用 | 备注 |
---|---|
连接复用 | 连接已预先建立,使用时直接获取,无需等待连接创建 |
性能提升 | 减少连接创建时间,频繁的创建和关闭连接是非常耗时的。 |
数据库连接管理 | 分配、管理和释放数据库连接,提供连接生命周期管理、超时检测等功能 |
常见的数据库连接池有哪些?
数据库连接池 | 特点 |
---|---|
Druid | 阿里开源,淘宝和支付宝专用数据库连接池 |
Tomcat JDBC | Tomcat内置 |
C3P0 | |
DBCP2 | Apache项目 |
Druid 数据库连接池如何使用?
步骤 | ||
---|---|---|
1 | 导入 jar 包:druid-1.0.9\druid-1.0.9.jar | |
2 | 编写配置文件,放在 src 目录下 | |
3 | 修改url,用户名和密码 | |
4 | 通过 Properties 集合加载配置文件 | |
5 | 通过 Druid 连接池工厂类获取数据库连接池对象 | |
6 | 获取数据库连接进行使用 | |
注意 | Druid 不会自动加载配置文件,需要我们手动加载,但是文件的名称可以自定义。 |
如何自定义数据库连接池?
步骤 | |
---|---|
1 | 定义一个类,实现 DataSource 接口。 |
2 | 定义一个容器,用于保存多个 Connection 连接对象。 |
3 | 定义静态代码块,通过 JDBC 工具类获取 10 个连接保存到容器中。 |
4 | 重写 getConnection 方法,从容器中获取一个连接并返回。 |
5 | 定义 getSize 方法,用于获取容器的大小并返回。 |
Maven 的功能有哪些?
Maven 是基于项目对象模型(POM)的项目管理工具。
功能 | ||
---|---|---|
1 | Java 项目构建生命周期 | 支持编译、测试、打包、部署等操作,简化项目构建流程。 |
2 | 依赖管理 | 自动下载并管理依赖,解决版本冲突,减少手动配置。 |
3 | 项目信息管理 | 管理项目元数据,如版本、开发者信息等。 |
4 | 报告生成 | 生成测试报告、代码覆盖率报告等。 |
5 | 多环境支持 | 支持不同环境的配置管理,如开发、测试、生产。 |
多模块支持 | 支持多模块项目,便于管理复杂项目结构。 |
如何使用Maven?
-
安装 Maven:
- 下载并配置 Maven,确保
mvn
命令可用。
- 下载并配置 Maven,确保
-
创建项目:
- 使用以下命令创建项目:
mvn archetype:generate -DgroupId=com.example -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
- 使用以下命令创建项目:
-
编译项目:
- 进入项目目录,运行:
mvn compile
- 进入项目目录,运行:
-
运行测试:
- 运行:
mvn test
- 运行:
-
打包项目:
- 运行:
mvn package
- 运行:
-
安装到本地仓库:
- 运行:
mvn install
- 运行:
-
清理项目:
- 运行:
mvn clean
- 运行:
Maven 中的常用命令有哪些?
mvn clean | 清理项目。 |
---|---|
mvn compile | 编译项目。 |
mvn test | 运行测试。 |
mvn package | 打包项目。 |
mvn install | 安装到本地仓库。 |
mvn deploy | 部署到远程仓库。 |
Spring 的功能有哪些?
主要功能 | 介绍 | |
---|---|---|
重点 | 依赖注入(DI) | 通过 XML 或注解配置 Bean 管理对象及其依赖,降低耦合度。 |
重点 | 面向切面编程(AOP) | 支持 AOP,便于处理日志、事务管理等横切关注点。 |
模块化设计 | 由多个模块组成,开发者可按需选择使用。 | |
声明式编程 | 提供声明式事务管理、安全等功能,减少样板代码。 | |
集成支持 | 支持与多种框架和技术集成,如 Hibernate、JPA、JMS 等。 | |
测试支持 | 提供测试框架,便于单元和集成测试。 | |
重点 | 事务管理 | 提供声明式和编程式事务管理。 |
重点 | MVC框架 | 提供模型-视图-控制器架构,便于 Web 开发。 |
数据访问 | 简化数据库操作,支持 JDBC、ORM 等。 | |
安全性 | 提供安全框架,支持认证和授权。 | |
如何使用 Spring ?
1.创建 Spring 项目 | 使用 Maven 或 Gradle 创建项目,添加 Spring 依赖。 |
---|---|
2.配置 Spring 容器 | 通过 XML 或 Java 配置类定义 Bean。 |
3.使用依赖注入 | 通过 @Autowired 或 XML 配置注入依赖。 |
4.创建 Spring MVC 应用 | 配置 DispatcherServlet,定义控制器和视图。 |
5.运行和测试 | 使用 Spring Test 进行单元和集成测试。 |
Spring 的主要模块有哪些?
Spring Core | 提供 IoC 容器和依赖注入功能。 |
---|---|
Spring Context | 在 Core 基础上扩展,支持国际化、事件传播等。 |
Spring AOP | 提供面向切面编程支持。 |
Spring DAO | 简化数据库操作,提供一致的异常处理。 |
Spring ORM | 支持与 ORM 框架集成,如 Hibernate、JPA。 |
Spring Web | 提供 Web 开发支持,包括 MVC 框架。 |
Spring Test | 提供测试支持,便于单元和集成测试。 |
什么是“面向切面编程”?
简述 | 面向切面编程是一种编程范式,旨在通过分离横切关注点(cross-cutting concerns)来提高模块化程度。 |
---|---|
全拼 | AOP(Aspect-Oriented Programming) |
核心概念 | 横切关注点:那些影响多个模块的功能(如日志、安全、事务管理等) |
切面(Aspect):模块化的横切关注点 | |
连接点(Join point):程序执行过程中的特定点(如方法调用) | |
通知(Advice):在连接点执行的动作 | |
切入点(Pointcut):定义通知应在哪些连接点执行 | |
AOP优势 | 减少代码重复:将通用功能集中处理 |
业务逻辑更清晰:核心业务代码不再混杂辅助功能 | |
更易维护:横切关注点变更只需修改切面 | |
常见应用场景 | 日志记录 |
事务管理 | |
安全控制 | |
性能监控 | |
异常处理 |
如何实现 AOP ?
- 编译时织入:在编译阶段修改源代码
- 类加载时织入:在类加载时修改字节码
- 运行时织入:通过代理模式实现(如Spring AOP)
AOP 示例(Spring AOP):
@Aspect
@Component
public class LoggingAspect {@Before("execution(* com.example.service.*.*(..))")public void logBefore(JoinPoint joinPoint) {System.out.println("调用方法: " + joinPoint.getSignature().getName());}@AfterReturning(pointcut = "execution(* com.example.service.*.*(..))", returning = "result")public void logAfterReturning(JoinPoint joinPoint, Object result) {System.out.println("方法返回: " + result);}
}
如何实现依赖注入?
DI 示例代码
依赖注入:
@Service
public class MyService {public String getMessage() {return "Hello, Spring!";}
}@RestController
public class MyController {@Autowiredprivate MyService myService;@GetMapping("/message")public String getMessage() {return myService.getMessage();}
}
.bat
是什么文件?
.bat
结尾的是 windows 的可执行文件
.sh
是什么文件?
.sh
结尾的是linux 的可执行文件