java web 后端知识简介

2020-08-22  本文已影响0人  吃饭看书打酱油

1、servlet简介

servlet.png

(1)、servlet实现使用
创建一个普通的java文件,继承HttpServlet,可以重写service方法,或重写doXX方法。在WEB-INFO下的web.xml中添加请求与servlet类的映射关系。

    <!--配置servlet的别名,同时在servlet-class配置项中添加servlet类的完全限定名  包名+类名-->
    <servlet>
        <servlet-name>myServlet</servlet-name>
        <servlet-class>com.xxx.MyServlet</servlet-class>
    </servlet>
    <!--配置servlet跟请求的映射关系-->
    <servlet-mapping>
        <servlet-name>myServlet</servlet-name>
        <url-pattern>/xx</url-pattern>
    </servlet-mapping>

(2)、servlet的生命周期
servlet生命周期如上图的请求流程,首次请求时由容器创建servlet对象(配置了 load-on-startup的情况有所不同,不一定是请求时创建servlet对象了,有可能是容器启动的时候创建servlet对象,例如 Spring mvc的 DispatcherServlet),执行init()方法,然后调用service方法,容器销毁时会调用destroy方法,后续请求过来时只会执行service方法。init和destroy只会执行一次,init在servlet对象创建后执行(servlet对象在首次请求的时候创建,后面请求过来复用对象)。

2、http协议简介

HTTP:超文本传输协议(Hyper Text Transfer Protocol)
作用:规范了浏览器和服务器的数据交互,还有其它...
特点:
1、简单快速
2、灵活
3、无连接
4、无状态
5、支持B/S和C/S架构
注意:HTTP1.1版本之后支持可持续连接

http1.1.png

(1)、http请求格式

请求.png

(2)、http请求方法

方法.png

1、get请求参数是直接显示在地址栏的,而post在地址栏不显示
2、get方式不安全,post安全
3、get请求参数有长度限制,post没有限制

(3)、http响应格式

响应.png

(4)、http响应状态码

image.png

200 OK //客户端请求成功
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate 报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的 URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常

3、Tomcat原理简介

Tomcat服务器是一款轻量级应用服务器。我们正常开发完一个web应用后,编译打包后得到一个war包,这个war包放入Tomcat的应用程序路径下,启动Tomcat就可以通过http请求访问这个web应用了。

Tomcat基本逻辑:

(1)、Tomcat启动以后,其实在操作系统中看到的是一个JVM虚拟机进程。这个虚拟机启动后,加载class进来执行,首先加载的是org.apache.catalina.startup.Bootstrap类,这个类里面有一个main()函数,是整个Tomcat的入口函数,JVM虚拟机会启动一个主线程从这个入口函数开始执行。
(2)、Bootstrap的main()函数开始执行,初始化Tomcat运行环境。这时候主要是创建一些线程,如负责监听80端口的线程,处理客户端连接请求的线程,以及执行用户请求的线程。创建这些线程的代码是Tomcat代码的一部分。
(3)、初始化运行环境之后,Tomcat就会扫描web程序路径,扫描到开发的war包后,再加载war包里面的类到JVM(因为web应用是被Tomcat加载运行的,所以也称Tomcat为Web容器)。
(4)、外部请求发送到Tomcat,也就说外部程序通过80端口和Tomcat进行http通信的时候,Tomcat会根据war包中的web.xml配置,决定这个请求url应该由哪个servlet处理,然后Tomcat就会分配一个线程去处理这个请求,实际上,就是这个线程执行响应的servlet代码。

Tomcat的目录结构:
简单Tomcat实现:

(1)、首先需要一个类似bootstrap的功能类

public class MyServer {

    // 请求和servlet映射关系
    public static HashMap<String,String> mapping = new HashMap<String,String>();
    static {
        mapping.put("/test","com.xx.MyServlet");
    }

    // 容器启动入口
    public static void main(String[] args) {
        try {
            startServer(8888);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 定义服务端的接受程序,接受socket请求
     * @param port
     */
    public static void startServer(int port) throws Exception{
        //定义服务端套接字
        ServerSocket serverSocket = new ServerSocket(port);
        //定义客户端套接字
        Socket socket = null;

        while (true){
            socket = serverSocket.accept();

            //获取输入流和输出流
            InputStream inputStream = socket.getInputStream();
            OutputStream outputStream = socket.getOutputStream();

            //封装一个请求对象  --  参照http协议请求的格式
            MyRequest request = new MyRequest(inputStream);
            //封装一个响应对象 --  参照http协议响应的格式
            MyResponse response = new MyResponse(outputStream);

            //根据请求获取对应的处理类,即servlet(这里的映射关系简单的用了一个Map表示,真实情况是用web.xml配置的)
            String clazz = new mapping.get(request.getRequestUrl());
            if(clazz!=null){
                Class<MyServlet> myServletClass = (Class<MyServlet>)Class.forName(clazz);
                //根据myServletClass创建对象
                MyServlet myServlet = myServletClass.newInstance();
                myServlet.service(request,response);
            }

        }
    }

}

(2)、request和response对象封装
request:

public class MyRequest {

    //请求方法  GET/POST
    private String requestMethod;
    //请求地址
    private String requestUrl;

    public MyRequest(InputStream inputStream) throws Exception{
        //缓冲区域
        byte[] buffer = new byte[1024];
        //读取数据的长度
        int len = 0;
        //定义请求的变量
        String str = null;

        if((len = inputStream.read(buffer))>0){
            str = new String(buffer,0,len);
        }
        // GET / HTTP/1.1
       String data =  str.split("\n")[0];
       String[] params =  data.split(" ");
        this.requestMethod = params[0];
        this.requestUrl = params[1];
    }

    public String getRequestMethod() {
        return requestMethod;
    }

    public void setRequestMethod(String requestMethod) {
        this.requestMethod = requestMethod;
    }

    public String getRequestUrl() {
        return requestUrl;
    }

    public void setRequestUrl(String requestUrl) {
        this.requestUrl = requestUrl;
    }
}

response:

public class MyResponse {

    private OutputStream outputStream;

    public MyResponse(OutputStream outputStream) {
        this.outputStream = outputStream;
    }

    public void write(String str) throws  Exception{
        StringBuilder builder = new StringBuilder();
        builder.append("HTTP/1.1 200 OK\n")
                .append("Content-Type:text/html\n")
                .append("\r\n")
                .append("<html>")
                .append("<body>")
                .append("<h1>"+str+"</h1>")
                .append("</body>")
                .append("</html>");
        this.outputStream.write(builder.toString().getBytes());
        this.outputStream.flush();
        this.outputStream.close();
    }
}

(3)、servlet相关封装
类似HttpServlet的类:

public abstract class MyHttpServlet {

    //定义常量
    public static final String METHOD_GET = "GET";
    public static final String METHOD_POST = "POST";

    public abstract void doGet(MyRequest request,MyResponse response) throws  Exception;
    public abstract void doPost(MyRequest request,MyResponse response) throws  Exception;

    /**
     * 根据请求方式来判断调用哪种处理方法
     * @param request
     * @param response
     */
    public void service(MyRequest request,MyResponse response) throws Exception{
        if(METHOD_GET.equals(request.getRequestMethod())){
            doGet(request,response);
        }else if(METHOD_POST.equals(request.getRequestMethod())){
            doPost(request,response);
        }
    }
}

定义的servlet:

public class MyServlet extends MyHttpServlet{
    @Override
    public void doGet(MyRequest request, MyResponse response) throws Exception {
        response.write("mytomcat get test");
    }

    @Override
    public void doPost(MyRequest request, MyResponse response) throws Exception {
        response.write("mytomcat post test");
    }
}

(4)、测试
运行MyServer,浏览器中输入 “http://127.0.0.1:8888/test”,测试结果:

测试结果.png

4、HttpServletRequest和HttpServletResponse

(1)、HttpServletRequest
HttpServletRequest对象代表客户端的请求,当客户端通过http协议访问服务器时,http请求中的所有信息都封装在这个对象中,可以通过这个对象获取请求中的数据。
常用方法:

(2)、HttpServletResponse
HttpServletResponse对象是服务器的响应对象,这个对象中封装了向客户端发送的数据、响应头以及响应状态码。
常用方法:

(3)、乱码问题解决

5、servlet请求转发和重定向

(1)、servlet请求转发 request.getRequestDispatcher("servletname").forward(request, response);

不同的servlet之间共享数据可以通过request.setAttribute("","")和request.getAttribute("");实现。

(2)、重定向 response.sendRedirect("url");

6、Cookie简介

http是一个无状态的协议,当一个客户端向服务端发送请求,在服务器返回响应后,连接就关闭了,在服务器端不保留连接信息。也就是请求A之后的请求B不知道请求A干了什么。

当客户端发送多次请求,且需要相同的请求参数时,这时候cookie就非常有用了。比如,某段时间内免登录。
cookie说明:

cookie基本操作:

  Cookie cookie = new Cookie(String key,String value);
  // 设置了最大年龄的cookie是持久化的,如果不设置则默认保存在内存中,随着浏览器关闭而消失
  cookie.setMaxAge(int seconds);
  // 给cookie设置请求路径,只有请求了设置的路径是才会带上这个cookie信息给服务器
  cookie.setPath(String url);
response.addCookie(Cookie cookie);
Cookie[] cookies = request.getCookies();

if (cookies != null) { 
   for (Cookie  c: cookies) {
       String key = c.getName();
       //......  cookie 是key value的,这里省略一堆判断~~~
       c.getValue();
   }
}

7、Session简介

Session是一种在服务器端保存http状态信息的技术。

session说明:

session基本操作:

HttpSession session = request.getSession();
session.setMaxInactiveInterval(5);//设置存活时间,时间单位秒
session.invalidate(); //session强制失效
sessoin.setAttribute(String name,Object object);

session.getAttribute(String name);

session常见问题:

8、ServletContext和ServletConfig

(1)、ServletContext 全局共享

ServletContext说明:

ServletContext对象基本操作:

ServletContext context = this.getServletContext();
//其它几种方式
this.getServletConfig().getServletContext();
request.getSession().getServletContext();
String getInitParameter(String paramName);

上下文参数在web.xml中设置

 <context-param>
      <param-name>myparam</param-name>
      <param-value>xxxx</param-value>
 </context-param>
context.setAttribute("name","value");
context.getAttribute("name");
context.removeAttribute("name");
context.getContextPath();
context.getRealPath("web.xml");

(2)、ServletConfig对象

ServletConfig说明:
使用ServletContext对象可以获取web.xml中的全局配置文件,在web.xml中,每个Servlet也可以进行单独的配置。

<servlet>
        <servlet-name>ServletConfigServlet</servlet-name>
        <servlet-class>com.xx.ServletConfigServlet</servlet-class>
        <init-param>
            <param-name>paramName1</param-name>
            <param-value>value1</param-value>
        </init-param>
        <init-param>
            <param-name>paramName2</param-name>
            <param-value>value2</param-value>
        </init-param>
</servlet>

ServletConfig基本操作:

ServletConfig config = this.getServletConfig();
config.getInitParameter("paramName");

//获取所有的key
Enumeration<String> initParameterNames = config.getInitParameterNames();
while (initParameterNames.hasMoreElements()){
    String key = initParameterNames.nextElement();
    String value = config.getInitParameter(key);
}

9、过滤器

过滤器是能对web请求和web响应的头属性和内容进行操作的一种特殊web组件。过滤器本身并不直接生成web响应,而是拦截web请求和响应,以便查看、提取或以某种方式操作客户端和服务器之间交换的数据。
过滤器主要功能:

filter过滤器的使用:
(1)、定义filter过滤器需要实现javax.servlet.Filter接口,该接口定义了init()、doFilter()和destory()三个方法。这三个方法分别对应了过滤器生命周期中的初始化、过滤和销毁这三个阶段。

public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("filter init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("filter逻辑处理开始");
        //  ......过滤逻辑
        // 过滤链往下走,最后执行的是被过滤的servlet
        filterChain.doFilter(servletRequest,servletResponse);
        // ......过滤逻辑
        System.out.println("filter逻辑处理完成");
    }

    @Override
    public void destroy() {
        System.out.println("我是filter销毁功能");
    }
}

(2)、web.xml配置

<filter>
        <filter-name>filter</filter-name>
        <filter-class>com.xx.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
        <filter-name>filter</filter-name>
        <url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 可配置多个filter -->

应用场景:编码格式、登录拦截等

10、监听器

Servlet监听器用于监听一些重要事件的发生,监听器可以在事情发生前、发生后可以做一些必要的处理。监听器可以通过实现Servlet API提供的Listense接口来创建。

监听对象

Servlet API 提供的一些监听器接口

监听器web.xml配置

<listener>
        <listener-class>com.xx.listener.MyListener</listener-class>
</listener>
上一篇下一篇

猜你喜欢

热点阅读