今天终于听完了b站300p的javaweb课程,今天我写一篇关于javaweb知识点总结的博客(又水了一篇)。

我们学校正好这学期也学javaweb,我只有把javaweb复习踏实了然后再复习一下javaSE才敢碰框架,要不然真不敢盲目学框架。

首先明确一点javaweb三大件:servlet程序,filter过滤器,listenner监听器。

我先来着重讲解一下servlet程序。(jsp、JSTL、EL表达式后面会提)

当然了,想要写出一个javaweb项目还不能缺少和数据库的交互,底下两个链接分别是JDBC底层和JDBC在项目实战的运用:

一、servlet程序

首先来介绍一下在javaweb中的路径问题,路径的一般形式:



http://localhost:8080/demo/


其中http是协议,localhost是服务器ip,8080是端口号,demo是工程名,同时也是artficats名,后面就是跟资源路径了。

servlet程序也是有生命周期的:



/**
* @author 陈柏宇
*
* servlet生命周期
* 1、执行servlet构造器方法
* 2、执行init初始化方法
* 第一 二步是在第一次访问的时候servlet程序会调用
* 3、执行service方法
* 第三步每次访问都会调用
* 4、执行destroy方法
* web工程停止的时候才会执行第四步
*/
一般在实际项目开发中,都是使用继承HttpServlet类的方法去实现Servlet程序
1、编写一个类去继承 HttpServlet类
2、根据业务需要重写 doGet 或者 doPost方法
3、到 web.xml中的配置Servlet访问程序
一个普通的servlet程序实例:



public class HelloServlet extends HttpServlet {
private String message;

public void init() {
System.out.println("2、初始化方法");
}

public HelloServlet()
{
System.out.println("1 构造器方法");
}

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");

// Hello
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1>" + message + "</h1>");
out.println("</body></html>");
}

public void destroy() {
System.out.println("4、destroy销毁方法");
}

/**
*
* @param req
* @param res
* @throws ServletException
* @throws IOException
* 执行你的功能代码
*/
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("3、service方法");

}

private void doGet()
{
System.out.println("1get请求的操作");
}

private void doPost()
{
System.out.println("post请求的操作");
}
}


我们是这样在web.xml中配置的:



<!--给tomcat配置servlet程序-->
<servlet>
<!--给servlet程序起一个别名-->
<servlet-name>
HelloServlet
</servlet-name>

<servlet-class>
com.example.demo.HelloServlet
</servlet-class>
</servlet>


<!--给servlet程序配置一个访问地址-->
<servlet-mapping>
<!--告诉服务器当前配置的地址给哪个服务器使用-->
<servlet-name>HelloServlet</servlet-name>
<!--url pattern 标签配置访问地址
/ 斜杠在服务器解析的时候表示地址为http://ip:port/工程路径
/hello 表示地址为:http://ip:port/工程路径/hello
一定要以/开头
-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>


 

servlet中有一个很重要的成员:servletContext对象(servlet上下文对象)

那么什么是servlet上下文对象呢?



/**
* 什么是ServletContext
* 1、ServletContext是一个接口,他表示Servlet上下文对象
* 2、一个web工程,只有一个ServletContext对象实例
* 3、ServletContext对象是一个域对象
* 4、ServletContext对象在web工程启动的时候创建,停止的时候销毁,生命周期在整个工程运行期间
*/


servlet对象是一个域对象,域对象就是指能像Map一样存取数据的对象,这里的域是指存取数据的操作范围,整个Web工程

这里我把Map和sevletContext对象做一下类比:



存数据                 取数据                     删除数据
Map put() get() remove()
域对象 setAttribute() getAttribute() removeAttribute()


那么ServletContext类有哪些作用呢:



1、获取web.xml中配置的上下文参数 context-param
2、获取当前的工程路径 格式: /工程路径
3、获取工程部署后再服务器硬盘上的绝对路径
4、像Map 一样存取数据


首先介绍第一点:获取web.xml中配置的上下文参数 context-param

我们在web.xml中这样配置上下文参数:



<!--context-param 是上下文参数(它属于整个web工程)-->
<context-param>
<param-name>username</param-name>
<param-value>context</param-value>
</context-param>

<!--context-param 是上下文参数(它属于整个web工程)-->
<context-param>
<param-name>password</param-name>
<param-value>root</param-value>
</context-param>


在servlet程序又是这样获取的:



protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1、获取web.xml中配置的上下文参数 context-param
ServletContext context = getServletContext();
String username = context.getInitParameter("username");
System.out.println("context-param参数username的值是:" + username);
//context-param参数username的值是:context
System.out.println("context-param参数password的值是: " + context.getInitParameter("password"));
//context-param参数password的值是:root

//2、获取当前的工程路径 格式: /工程路径
System.out.println("当前工程路径:" + context.getContextPath());
//当前工程路径:/demo

//3、获取工程部署后再服务器硬盘上的绝对路径
/*
/ 被服务器解析 地址为 : http://ip:port/工程名/ 映射到idea代码的web目录<br/>
*/
System.out.println("工程部署的路径::" + context.getRealPath("/"));
//工程部署的路径::C:\Users\HASEE\Desktop\apache-tomcat-8.5.70\webapps\WebProjects\demo\target\demo-1.0-SNAPSHOT\


}


在浏览器我们打开 开发者模式可以在NetWork(我用的谷歌浏览器)中查看请求头的信息:

常用请求头有:



常用请求头:
Accept 表示客户端可以接受的数据类型
Accept-Language 表示客户端可以接收的语言类型
User-Agent 表示客户端浏览器的信息
Host:表示请求时的服务器ip和端口号


客户端(浏览器)和服务器的交互方式可以通过get请求和post请求来体现

那么get请求和post请求有哪些区别呢:

请求方式:



Get请求有哪些:
1.form标签,method = get
2.a标签
3.link标签引入css
4.script标签引入js文件
5.img标签引入图片
6.iframe引入html页面
7.浏览器地址栏中输入地址后输入回车
post请求:
1.form标签 method = post


传输数据的大小:



在HTTP规范中,没有对URL的长度和传输的数据大小进行限制。
但是在实际开发过程中,对于GET,特定的浏览器和服务器对URL的长度有限制。
因此,在使用GET请求时,传输数据会受到URL长度的限制。
对于POST,由于不是URL传值,理论上是不会受限制的,但是实际上各个服务器会规定对POST提交数据大小进行限制,Apache、IIS都有各自的配置。


安全性:



POST的安全性比GET的高。这里的安全是指真正的安全,而不同于上面GET提到的安全方法中的安全,上面提到的安全仅仅是不修改服务器的数据。
比如,在进行登录操作,通过GET请求,用户名和密码都会暴露在URL上了。


综上,虽然get请求方式比post请求方式多,但并不能说明get请求比post方式好,我们在项目中很多时候都用的post请求。

接下来看看响应的HTTP协议格式:



响应的http协议格式
1.响应行
(1)相应的协议和版本号
(2)相应状态码
(3)相应状态描述符
2.响应头
key : value 不同响应头有其不同的含义
Server : 表示服务器的信息
Content-Type : 表示响应体的数据类型
空行
3.响应体 ---->>> 就是回传给客户端的数据


常见的响应码格式(就是大家最讨厌的404哪些东西):



常见的响应码说明:
200 请求成功
302 表示请求重定向
404 表示请求服务器已经收到,但是你要的数据不存在 (请求地址错误)
500 表示服务器已经收到请求但是服务器代码错误(内部错误)


话题再回到前面ServletContext上下文对象,我们如何使用这个域对象呢,我们之前已经介绍了setAttribute()方法和getAttribute对象了,我们是这样在程序中使用的:



protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//getServletConfig().getServletContext();
//获取ServletContext对象
ServletContext context = getServletContext();

System.out.println("保存之前: Context1 获取 key1的值是:"+context.getAttribute("key1")); //null

context.setAttribute("key1","value1");

System.out.println("context1中获取域数据eky1的值是"+context.getAttribute("key1"));

}


这里注意一下:



getServletConfig().getServletContext();


我这里先获得了Servlet的配置文件再获取上下文对象

其中ServletConfig也是一个类,它有如下作用:



ServletConfig 类 : 是 Servlet程序的配置信息类
Servlet程序和 ServletConfig对象都是由Tomcat负责创建,我们负责使用
Servlet程序默认是第一次访问时创建 ServletConfig是每个 Servlet程序创建时,就创建一个对应的 ServletConfig对象
三大作用
1、可以获取Servlet 程序的别名 servlet-name的值
2、获取初始化参数 init - param
3、获取ServletContext 对象


我在web.xml中这样定义:



<servlet>

<servlet-name>ServletConfigTest</servlet-name>

<servlet-class>com.example.demo.ServletConfigTest</servlet-class>

<init-param>
<!--是参数名-->
<param-name>username</param-name>
<!--是参数值-->
<param-value>root</param-value>
</init-param>

<init-param>
<!--是参数名-->
<param-name>url</param-name>
<!--是参数值-->
<param-value>jdbc:mysql://3306/test</param-value>
</init-param>

</servlet>


<servlet-mapping>
<servlet-name>ServletConfigTest</servlet-name>
<url-pattern>/Test3</url-pattern>
</servlet-mapping>


我在程序是这样写的:



public void init(ServletConfig servletConfig) throws ServletException {
//别名是servlet - name
System.out.println("ServletConfigTest的别名是:" + servletConfig.getServletName());
//ServletConfigTest的别名是:ServletConfigTest

//初始化参数init-param
System.out.println("初始化参数username的值是:" + servletConfig.getInitParameter("username"));
//初始化参数username的值是:root
System.out.println("初始化参数username的值是:" + servletConfig.getInitParameter("url"));
//初始化参数username的值是:jdbc:mysql://3306/test

//获取ServletContext 对象
System.out.println(servletConfig.getServletContext());
//org.apache.catalina.core.ApplicationContextFacade@4b94c49d
}


当我在启动服务器并在浏览器中输入:



http://localhost:8080/demo/Test3


控制台就会打印:



ServletConfigTest的别名是:ServletConfigTest
初始化参数username的值是:root
初始化参数username的值是:jdbc:mysql://3306/test
org.apache.catalina.core.ApplicationContextFacade@6ff4bf1


可以发现前三行内容都是我们在web.xml定义的,而最后一行是上下文对象的地址。

 

我们可以注意到在Servlet程序中无论是get()方法还是post()方法都有两个不同参数:

HttpServletRequest对象,和HttpServletResopnse对象

前者是客户端给服务器的请求对象

后者是服务器给客户端的相应对象

关于requst对象:



/**
* @author 陈柏宇
* HttpServletRequestTest类的作用:
* 每次只要有请求进入tomcat服务器,Tomcat服务器就会把请求过来的http协议信息解析好封装到Request对象中
* 然后传递到service方法(doGet和doPost)中给我们使用
* 我们可以通过HttpServletRequest对象获取到所有请求的信息
*
* 常用方法:
* getRequestURI() : 获取请求的资源路径
* getRequestURL() : 获取请求的统一资源定位符
* getRemoteHost() : 获取客户端的ip地址
* getHeader() : 获取请求头
* getParameter() : 获取请求的参数
* getParameterValues() : 获取请求的参数(多个值的时候使用)
* getMethod() : 获取请求的方式 GET 或 POST
* setAttribute(key,value) : 设置域数据
* getAttribute(key) : 获取域数据
* getRequestDispatcher() : 获取请求转发对象
*/


我们在web.xml中这样设置:



<servlet>
<servlet-name>HttpServletRequestTest</servlet-name>
<servlet-class>com.example.demo.HttpServletRequestTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HttpServletRequestTest</servlet-name>
<url-pattern>/request</url-pattern>
</servlet-mapping>


并且写这样的一个html表单:



<form action="http://localhost:8080/demo/request" method="post">
用户名:<input type="text" name = "username"><br/>
密 码:<input type="password" name="pwd"><br/>
兴趣爱好:<input type="checkbox" name="hobby" value="cpp">C++
<input type="checkbox" name="hobby" value="java">java
<input type="checkbox" name="hobby" value="python">python<br/>
<input type="submit">
</form>


再写一个这样的servlet程序:



protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8"); //设置请求体的字符集为utf-8,从而解决post请求中文乱码问题

System.out.println("--------Post-----------");

String username = req.getParameter("username");
System.out.println("获取用户名: "+username);

String password = req.getParameter("pwd");
System.out.println("获取密码: " + password);

String[] hobby = req.getParameterValues("hobby");
System.out.println("获取兴趣: " + Arrays.asList(hobby));
}


我们在表单中输入用户名为123,密码为123,三项全选

最终控制台输出:



--------Post-----------
获取用户名: 123
获取密码: 123
获取兴趣: [cpp, java, python]


这样就可以实现从浏览器获取数据到服务器上了。

那么我们如何在浏览器上写数据呢?

这里就要用到我们前面提到的HttpServletResponse类了:

首先来介绍一下这个类:



/**
* HttpServletResponse类和HttpServletRequest类一样,每次请求进来,Tomcat服务器都会创建一个Response对传递给
* Servlet程序去使用,HttpServletRequest表示请求过来的信息,HttpServletResponse表示响应的信息
* 我们如果需要设置返回给客户端的信息,就可以通过HttpServletResponse对象来进行设置
*
* HttpServletResponse输出流的说明
* 字节流 getOutStream(); 常用于下载(传递二进制)
* 字符流 getWriter(); 常用于回传字符串(常用)
* 用了字节流,就不能再用字符流,反之一样
*/


我们在往客户端回传字符的时候要注意,我们回传的如果是中文字符那就一定要设置字符集,

因为Tomcat服务器默认使用iso字符集(谁叫Tomcat服务器是美国人设计出来的呢,26个英语字母解决一切问题)

我们最好使用这种方法设计字符集:



resp.setContentType("text/html;charset=UTF-8");  //此方法一定要在获取流对象之前才有效


而后就可以放心在浏览器中输出中文字符了



PrintWriter writer = resp.getWriter();  //获取流对象
writer.write("你好"); //设置字符集后不会出现乱码


JavaWeb----知识点总结_客户端

当然了,我们在web.xml要配置路径,具体我就省略了。

 

瑞了,明天讲请求转发和重定向。