这是我做的一张关于javaWeb的学习笔记,可以快速回忆有关javaWeb的概要和重点,接下来是javaWeb的学习笔记详细说明
软件系统体系结构包含B/S,C/S
1、B/S
-
B/S结构即浏览器/服务器(Browser/Server);
-
优点:只需要编写服务器端程序;
-
缺点:安全性较差。
B/S体系,也就是浏览器上的网页,就是我们今天学习的javaWeb技术实现的
2、C/S
-
C/S结构即客户端/服务器(Client/Server),例如QQ;
-
需要编写服务器端程序,以及客户端程序,例如我们安装的就是QQ的客户端程序;
-
缺点:软件更新时需要同时更新客户端和服务器端两端,比较麻烦;
-
优点:安全性比较好。
1、JavaWeb的概述
JavaWeb 是使用 Java 技术来解决相关 web 互联网领域的技术总和。它包括了使用 Java 语言开发服务器端应用程序、动态网页技术、数据库访问技术等。交互对象为服务器/浏览器
2、JavaWeb的技术栈
- 前端技术:HTML,CSS,JavaScript用于构建用户界面
- HTML是网页的基础结构
- CSS用于美化页面的外观
- JavaScript为网页添加了互动性
- 后端技术
- Java编程语言,具有强大的面向对象特性,跨平台性和丰富的类库
- Servlet和jsp是构建动态页面的核心技术
- Servlet是运行在服务器端的Java程序,用于处理客户端的请求并相应
- jsp运行在HTML页面中引入Java代码,使得页面的动态生成更加方便
- 还有一些框架如Spring,SpringMVC等可以提高开发效率和代码的可维护性
- 数据库技术
- 关系型数据库如MySQL、Oracle等用于存储数据
- 通过JDBC技术可以实现Java与数据库的连接和交互
3、JavaWeb环境的构建
3.1 Web服务器
Web服务器的作用是接收客户端的请求,并给客户端作出响应。那么,我们就需要一个Web服务器,以下是几种服务器可以选择:
-
Tomcat(Apache):Apache基金组织,中小型的JavaEE服务器,仅仅支持少量的JavaEE规范servlet/jsp。开源的,免费的
-
JBoss(JBOSS):大型的JavaEE服务器,支持所有的JavaEE规范,收费的。
-
Weblogic(Orcale):大型的JavaEE服务器,支持所有的JavaEE规范,收费的。
-
Websphere(IBM):IBM公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费的
JavaEE:Java语言在企业级开发中使用的技术规范的总和,一共规定了13项大的规范
当然,作为初学者的我们使用Tomcat就可以了,接下来我就用Tomcat为例进行说明。至于Tomcat的配置我就不在此说明
3.2 Web应用
3.2.1 创建静态应用
- 首先在Web目录下创建创建index.html
- 然后写一个自己想要的标题
- 启动Tomcat
- 打开浏览器搜索http://localhost:8080/index.html
这样一个简单的浏览器页面就做好了,当然仅仅这样还是不够的,接下来我们就需要在页面中不断添加各种互动性,后端也需要有执行代码
3.2.2 创建动态页面
- 在web下的WEB-INF下创建lib目录
- 将所需要的jar包导入lib目录中,并添加到库
- 在web下创建hello.html
- 在src中创建Servlet目录,在该目录下创建AServlet
- AServlet继承HttpServlet,并写注解可以快速配置web.xml文件
然后部署Tomcat服务器
4. Servlet
4.1 Servlet概述
Servlet是JavaWeb的 三大组件之一 ,它属于动态资源。Servlet的作用是处理请求,服务器会把接收到的请求交给Servlet来处理,在Servlet中通常需要:
-
接收请求数据;
-
处理请求;
-
完成响应。
例如客户端发出登录请求,或者输出注册请求,这些请求都应该由Servlet来完成处理!Servlet需要我们自己来编写,每个Servlet必须实现javax.servlet.Servl口。
4.2 Servlet的实现
实现Servlet主流的有两种方式:
-
实现javax.servlet.Servlet接口;
-
继承javax.servlet.http.HttpServlet类;(建议使用这个,更常用)
通常我们会去继承HttpServlet类来完成我们的Servlet,但学习Servlet还要从javax.servlet.Servlet接口开始学习。
1.1 javax.servlet.Servlet 类
因为Servlet是接口,因此我们实现接口时,必须实现所有的方法:
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import java.io.IOException;@WebServlet("/A")
public class AServlet implements Servlet {@Overridepublic void init(ServletConfig servletConfig) throws ServletException {//Servlet的初始化,会在服务器第一次调用AServlet时,调用init();}@Overridepublic ServletConfig getServletConfig() {//获取Servlet的配置信息return null;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {//在service方法中完成对客户端的响应}@Overridepublic String getServletInfo() {//获取Servlet的信息return "";}@Overridepublic void destroy() {//当服务器关闭时,自动调用destroy方法来摧毁Servlet}
}
在Servlet接口中还存在三个我们不熟悉的类型:
-
ServletRequest:service() 方法的参数,它表示请求对象,它封装了所有与请求相关的数据,它是由服务器创建的;
-
ServletResponse:service()方法的参数,它表示响应对象,在service()方法中完成对客户端的响应需要使用这个对象;
-
ServletConfig:init()方法的参数,它表示Servlet配置对象,它对应Servlet的配置信息,那对应web.xml文件中的
<servlet>
元素。
ServletRequest 和 ServletResponse 的实例由服务器创建,然后传递给service()方法。如果在service() 方法中希望使用HTTP相关的功能,那么可以把 ServletRequest 和ServletResponse 强转成 HttpServletRequest 和 HttpServletResponse。这也说明我们经常需要在service()方法中对 ServletRequest 和 ServletResponse 进行强转,这是很心烦的事情。不过后面会有一个类来帮我们解决这一问题的。
HttpServletRequest方法:
-
String getParameter(String paramName):获取指定请求参数的值;经常用到!!!类似于k-v 键值对,通过k名,获取v值
-
String getMethod():获取请求方法,例如GET或POST;
-
String getHeader(String name):获取指定请求头的值;
-
void setCharacterEncoding(String encoding):设置请求体的编码!因为GET请求没有请求体,所以这个方法只只对POST请求有效。当调用request.setCharacterEncoding(“utf-8”)之后,再通过getParameter()方法获取参数值时,那么参数值都已经通过了转码,即转换成了UTF-8编码。所以,这个方法必须在调用getParameter()方法之前调用
HttpServletResponse方法:
-
PrintWriter getWriter():获取字符响应流,使用该流可以向客户端输出响应信息。例如response.getWriter().print(“<h1>Hello JavaWeb!</h1>”); 常用
-
ServletOutputStream getOutputStream():获取字节响应流,当需要向客户端响应字节数据时,需要使用这个流,例如要向客户端响应图片;
-
void setCharacterEncoding(String encoding):用来设置字符响应流的编码,例如在调用setCharacterEncoding(“utf-8”);之后,再response.getWriter()获取字符响应流对象,这时的响应流的编码为utf-8,使用response.getWriter()输出的中文都会转换成utf-8编码后发送给客户端;
-
void setContentType(String contentType):该方法是setHeader(“content-type”, “xxx”)的简便方法,即用来添加名为content-type响应头的方法。content-type响应头用来设置响应数据的MIME类型,例如要向客户端响应jpg的图片,那么可以setContentType(“image/jepg”),如果响应数据为文本类型,那么还要台同时设置编码,例如:setContentType(“text/html;chartset=utf-8”)表示响应数据类型为文本类型中的html类型,并且该方法会调用setCharacterEncoding(“utf-8”)方法; 常用
-
void sendError(int code, String errorMsg):向客户端发送状态码,以及错误消息。例如给客户端发送404:response(404, “您要查找的资源不存在!”)。
1.2 实现Servlet接口
首先需要创建Servlet类,然后实现Servlet接口:
import javax.servlet.Servlet;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import java.io.IOException;public class MyServletImpl implements Servlet {@Overridepublic void init(ServletConfig servletConfig) throws ServletException {// 初始化方法,在Servlet被加载时调用}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException, ServletException {// 处理请求的方法,类似于HttpServlet中的doGet和doPost方法servletResponse.getWriter().println("Hello, This is a Servlet implementing Servlet interface!");}@Overridepublic String getServletInfo() {return null;}@Overridepublic void destroy() {// 销毁方法,在Servlet被卸载时调用}}
在传统的JavaWeb项目中,我们需要对web.xml进行Servlet的配置,配置信息包括Servlet的名称,Servlet 类的全限定名以及Servlet的路径,例如以下:
<web - app><servlet><servlet - name>MyServletImpl</servlet - name><servlet - class>com.example.MyServletImpl</servlet - class></servlet><servlet - mapping><servlet - name>MyServletImpl</servlet - name> <url - pattern>/MyServletImpl</url - pattern> </servlet - mapping></web - app>
上述配置中,
<servlet - name>
标签定义了 Servlet 的名称,<servlet - class>
标签指定了 Servlet 类的全限定名,<servlet - mapping>
中的<url - pattern>
定义了客户端访问该 Servlet 的路径。当客户端访问http://localhost:8080/MyServlet
时,服务器就会调用MyServlet
类的doGet
方法来处理请求。
2.1 javax.servlet.http.HttpServlet类
HttpServlet是Java Servlet API 中的一个抽象类,用于处理 HTTP 请求。它继承自GenericServlet,专门为处理 HTTP 协议的请求而设计。
HTTP 协议定义了多种请求方法,如 GET、POST、PUT、DELETE 等。HttpServlet
针对不同的请求方法提供了相应的默认处理方法,如doGet()
、doPost()
、doPut()
、doDelete()
等。其中doGet()和doPost()方法十分常用。
import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;public class MyGetServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();out.println("<html><body>");out.println("<h1>Hello from GET request!</h1>");out.println("</body></html>");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();out.println("<html><body>");out.println("<h1>Hello from POST request!</h1>");out.println("</body></html>");}}
在 HttpServlet 的 service(HttpServletRequest,HttpServletResponse) 方法会去判断当前请求是GET还是POST,如果是GET请求,那么会去调用本类的doGet()方法,如果是POST请求会去调用doPost()方法,这说明我们在子类中去覆盖doGet()或doPost()方法即可。
同时,在doGet() 和doPost() 中,我们可以用request.getParameter()方法获取参数:
import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;public class ParameterServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();String name = request.getParameter("name");out.println("<html><body>");out.println("<h1>Hello, " + name + "!</h1>");out.println("</body></html>");}}
获取请求头信息
import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;public class HeaderServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();String userAgent = request.getHeader("User-Agent"); out.println("<html><body>");out.println("<h1>Your user agent is: " + userAgent + "</h1>");out.println("</body></html>");}}
2.2 继承 HttpServlet类
首先,创建Servlet类来继承HttpServlet,来处理客户端发来请求:
import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;public class MyServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {// 设置响应内容类型为HTMLresponse.setContentType("text/html");// 获取输出流对象PrintWriter out = response.getWriter();// 输出HTML内容out.println("<html><body>");out.println("<h1>Hello, This is a Servlet using doGet method!</h1>");out.println("</body></html>");}}
然后如同实现Servlet类一样,在web.xml中配置MyServlet:
<web - app><servlet><servlet - name>MyServlet</servlet - name><servlet - class>com.example.MyServlet</servlet - class></servlet><servlet - mapping><servlet - name>MyServlet</servlet - name><url - pattern>/MyServlet</url - pattern></servlet - mapping></web - app>
但是,我们写着写着可能会有一些疑惑,如果每创建一个Servlet,都要对web.xml进行配置,那无疑会打断写代码的连贯性,同时代码的可维护性和可理解性也降低了,因此在Servlet 3.0 及以上版本,我们可以使用注解去快速配置web.xml,使用方法如下:
首先创建Servlet来继承HttpServlet类,然后在Servlet类的上方使用@WebServlet注解来配置Servlet
import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;@WebServlet("/MyAnnotatedServlet")public class MyAnnotatedServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();out.println("<html><body>");out.println("<h1>Hello, This is an Annotated Servlet!</h1>");out.println("</body></html>");}}
@WebServlet
注解中的参数"/MyAnnotatedServlet"
指定了 Servlet 的访问路径。这种方式不需要在web.xml
文件中进行配置,使得代码更加简洁,但是需要注意的是,项目的 Servlet 版本必须是 3.0 及以上,并且如果项目同时使用了注解和web.xml
配置,可能会出现冲突,需要谨慎处理。
4.3 Servlet的生命周期(重要)
1、Servlet的创建和初始化
当服务器第一次调用Servlet(a)时,a就会创建一个实例(一个Servlet只会创建一个实例),并调用init() 进行初始化(只会初始化一次)
2、 Servlet的使用(服务)
当每次客户端发起请求到Servlet时,服务器都会调用service方法来处理请求
3、Servlet的销毁
当web服务器关闭时,或者Servlet长时间未用,服务器会调用destroy()方法