JavaWeb----知识点总结

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

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

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

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

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

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("你好");  //设置字符集后不会出现乱码

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

 

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

 

posted @ 2021-09-18 22:25  Apak陈柏宇  阅读(325)  评论(0编辑  收藏  举报