JavaWeb基础

news2025/7/25 10:01:34

Servlet 是在服务器上运行的小程序。这个词是在 Java applet的环境中创造的,Java applet 是一种当作单独文件跟网页一起发送的小程序,它通常用于在客户端运行,结果得到为用户进行运算或者根据用户互作用定位图形等服务。

服务器上需要一些程序,常常是根据用户输入访问数据库的程序。这些通常是使用公共网关接口(Common Gateway Interface,CGI)应用程序完成的。然而,在服务器上运行 Java,这种程序可使用 Java 编程语言实现。在通信量大的服务器上,JavaServlet 的优点在于它们的执行速度更快于 CGI 程序。各个用户请求被激活成单个程序中的一个线程,而无需创建单独的进程,这意味着服务器端处理请求的系统开销将明显降低。

实现过程

最早支持 Servlet 技术的是 JavaSoft 的 Java Web Server。此后,一些其它的基于 Java 的 Web Server 开始支持标准的 Servlet API。Servlet 的主要功能在于交互式地浏览和修改数据,生成动态 Web 内容。这个过程为:

客户端发送请求至服务器端;

服务器将请求信息发送至 Servlet;

Servlet 生成响应内容并将其传给服务器。响应内容动态生成,通常取决于客户端的请求;

服务器将响应返回给客户端。

Servlet 看起来像是通常的 Java 程序。Servlet 导入特定的属于 Java Servlet API 的包。因为是对象字节码,可动态地从网络加载,可以说 Servlet 对 Server 就如同 Applet对 Client 一样,但是,由于 Servlet 运行于 Server 中,它们并不需要一个图形用户界面。从这个角度讲,Servlet 也被称为 FacelessObject。

一个 Servlet 就是 Java 编程语言中的一个类,它被用来扩展服务器的性能,服务器上驻留着可以通过“请求-响应”编程模型来访问的应用程序。虽然 Servlet 可以对任何类型的请求产生响应,但通常只用来扩展 Web 服务器的应用程序。Servlet根据请求,动态的去生成要返回的html,并不是早就准备好的html文档。

Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,当在一台机器上配置好Apache 服务器,可利用它响应HTML(标准通用标记语言下的一个应用)页面的访问请求。实际上Tomcat是Apache 服务器的扩展,但运行时它是独立运行的,所以当你运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。

诀窍是,当配置正确时,Apache 为HTML页面服务,而Tomcat 实际上运行JSP 页面和Servlet。另外,Tomcat和IIS等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器,独立的Servlet容器是Tomcat的默认模式。不过,Tomcat处理静态HTML的能力不如Apache服务器

这里注意两个问题:

  1. tomcat启动乱码问题

  1. tomcat的启动成功的判断方法

  1. 修改端口和调整乱码问题

定位到服务配置文件中

定位到日志文件中

过程简述:

1.首先从浏览器输入网址发出请求,请求发送到tomcat

2.tomcat根据映射假名匹配,匹配到后找到真名

3.根据真名再匹配servlet的具体路径

4.找到后Servlet处理请求,并且返回响应到浏览器

5.浏览器加载响应。

放在webapp目录中的WEB-INF中的sub文件不能随便被外部访问,里面放html,是访问不到的。

这样就可以访问了,一般推荐采用绝对路径,不采用相对路径。

注意上下文问题:就是servlet的映射的根路径的控制www.localhost:8080/xxxxx/url-pattern

一般都设置为忽略不常用。

        String[] specs = request.getParameterValues("spec");
        PrintWriter out=response.getWriter();
        for(String spec:specs){
            out.println("<h2>spec:"+spec+"</h2>");
        }

以下是两种请求的处理方式。

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name");
        String mobile = req.getParameter("mobile");
        PrintWriter out = resp.getWriter();
        out.println("GET");
        out.println("<h1>"+name+"</h1>");
        out.println("<h1>"+mobile+"</h1>");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name");
        String mobile = req.getParameter("mobile");
        PrintWriter out = resp.getWriter();
        out.println("POST");
        out.println("<h1>"+name+"</h1>");
        out.println("<h1>"+mobile+"</h1>");
    }
public class FirstServlet extends HttpServlet {
    //第一阶段装载,读取xml文件,加载配置信息,并未创建

    //第一次访问(地址栏输入)的时候才会创建servlet实体对象
    public FirstServlet() {
        System.out.println("正在创建...");
    }
    //创建之后初始化
    @Override
    public void init() throws ServletException {
        System.out.println("正在初始化");
    }
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("正在处理。。");
    }
    //在tomcat关闭前会自动的关闭销毁
    @Override
    public void destroy() {
        System.out.println("正在销毁");
    }
//    注意全局有且仅有一个servlet对象实例,有多个请求时,单例多线程。
}
在类上注解写上不用配置web.xml了
@WebServlet("/anno")
public class AnnotationServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().println("im annotation servlet!");
    }
}

Uniform Resource Locator

Uniform Resource Identifier

HTTP 协议的 Header 是一块数据区域,分为请求头和响应头两种类型,客户端向服务区发送请求时带的是请求头,而服务器响应客户端数据时带的是响应头。

请求头里主要是客户端的一些基础信息,UA(user-agent)就是其中的一部分,而响应头里是响应数据的一些信息,以及服务器要求客户端如何处理这些响应数据的指令。请求头里面的关键信息如下:

1) accept

表示当前浏览器可以接受的文件类型,假设这里有 image/webp,表示当前浏览器可以支持 webp 格式的图片,那么当服务器给当前浏览器下发 webp 的图片时,可以更省流量。

2) accept-encoding

表示当前浏览器可以接受的数据编码,如果服务器吐出的数据不是浏览器可接受的编码,就会产生乱码。

3) accept-language

表示当前使用的浏览语言。

4) Cookie

很多和用户相关的信息都存在 Cookie 里,用户在向服务器发送请求数据时会带上。例如,用户在一个网站上登录了一次之后,下次访问时就不用再登录了,就是因为登录成功的 token 放在了 Cookie 中,而且随着每次请求发送给服务器,服务器就知道当前用户已登录。

5) user-agent

表示浏览器的版本信息。当服务器收到浏览器的这个请求后,会经过一系列处理,返回一个数据包给浏览器,而响应头里就会描述这个数据包的基本信息。

响应头里的关键信息有:

1) content-encoding

表示返回内容的压缩编码类型,如“Content-Encoding :gzip”表示这次回包是以 gzip 格式压缩编码的,这种压缩格式可以减少流量的消耗。

2) content-length

表示这次回包的数据大小,如果数据大小不匹配,要当作异常处理。

3) content-type

表示数据的格式,它是一个 HTML 页面,同时页面的编码格式是 UTF-8,按照这些信息,可以正常地解析出内容。content-type 为不同的值时,浏览器会做不同的操作,如果 content-type 是 application/octet-stream,表示数据是一个二进制流,此时浏览器会走下载文件的逻辑,而不是打开一个页面。

4) set-cookie

服务器通知浏览器设置一个 Cookie;通过 HTTP 的 Header,可以识别出用户的一些详细信息,方便做更定制化的需求,如果大家想探索自己发出的请求中头里面有些什么,可以这样做:打开 Chrome 浏览器并按“F12”键,唤起 Chrome 开发者工具,选择 network 这个 Tab,浏览器发出的每个请求的详情都会在这里显示。

根据请求头进行判断是哪一种设备,就返回哪种设备的页面。

通过请求头判断处理方式,这里有一句话要注意,设置编码方式,否则中文字符串会乱码?号。

@WebServlet("/ua")
public class UserAgentServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String ua = req.getHeader("User-Agent");
        String output = "";
        if(ua.toLowerCase().indexOf("window nt")!=-1){
            output = "<h1>这是PC页面</h1>";
        }else {
            output = "<h1>这是移动端页面";
        }
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out=resp.getWriter();
        out.println(output);
    }
}

401代表没有登陆,403代表没有权限

@WebServlet("/ua")
public class UserAgentServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String ua = req.getHeader("User-Agents");
        String output = "";
        if(ua==null){
            resp.getWriter().println("请求头不存在");
            return;
        }
        if(ua.toLowerCase().indexOf("window nt")!=-1){
            output = "<h1>这是PC页面</h1>";
        }else {
            output = "<h1>这是移动端页面";
        }
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out=resp.getWriter();
        out.println(output);
    }
}
@WebServlet("/ct")
public class ContentTypeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String output = "<h1><a href='http://www.baidu.com'><span>百度</span>";
        response.setContentType("aplication/x-msdownload;charset=utf-8");
        response.getWriter().println(output);
    }
}
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().println("我是主页");
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }
}

@WebServlet("/login")
public class CheckLoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        if(username.equals("admin")&&password.equals("123456")){
            System.out.println("登录成功");
            //请求转发
            //request.getRequestDispatcher("/index").forward(request,response);
            //响应重定向
            response.sendRedirect("/index");
        }else {
            System.out.println("用户登录失败");
        }
    }
}
<body>
    <form action="/login" method="post">
      <input name="username">
      <input name="password" type="password">
      <input type="submit">
    </form>
</body>

方式一请求转发的形式

方式二响应重定向的方式

两者的区别:

请求转发:一个是一次即可请求完成,紧密相关,因为由一个tomcat管理,只能在应用的内部进行转发

响应重定向:不是紧密相连的对象,默认get方式,因为两次响应,可以跳到其他服务器管理站点如百度

登录后主页面显示账号名称实例:

@WebServlet("/login")
public class CheckLoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        if(username.equals("admin")&&password.equals("123456")){
            System.out.println("登录成功");
            request.setAttribute("username",username);
            request.setAttribute("password",password);
//            请求转发,总体一个请求,可以设置和获取属性
            request.getRequestDispatcher("/index").forward(request,response);
//            //响应重定向,一共两个请求,会出现Null的情况
//            response.sendRedirect("/index");
        }else {
            System.out.println("用户登录失败");
        }
    }
}
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        String username = (String)request.getAttribute("username");
        response.getWriter().println("我是主页"+username);
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }
}

Cookie

@WebServlet("/cookie/random")
public class RandomServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Integer random = new Random().nextInt(10000);
        Cookie cookie = new Cookie("random" , String.valueOf(random));
        cookie.setMaxAge(60*60*24);
        response.addCookie(cookie);
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().println("<h2>随机数" +  random+ "已生成</h2>");
    }
}
@WebServlet("/cookie/show")
public class CookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie[] cookies = request.getCookies();
        Integer random=-1;
        if(cookies==null){
            response.getWriter().println("无cookie");
            return;
        }
        for(Cookie c:cookies){
            if (c.getName().equals("random")) {
                random=Integer.parseInt(c.getValue());
            }
        }
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().println(random);
    }
}

为什么说session是和浏览器窗口绑定的?

因为当我把窗口关闭,cookie默认消除,此时向tomcat发送请求的时候,因为cookie没了,所以此时会创建一个新的session,原来的30min会自动销掉。

public class CheckLoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        if(username.equals("admin")&&password.equals("123456")){
            System.out.println("登录成功");
            //为请求开辟一片内存空间,并设置属性及值,设置同时设置cookie的sessionid
            HttpSession session = request.getSession();
            session.setAttribute("username",username);
            //响应设置好cookie的sessionid,响应重定向到index
            response.sendRedirect("/index");
        }else {
            System.out.println("用户登录失败");
        }
    }
}
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        //根据cookie来查找session空间,并获取属性
        HttpSession session = request.getSession();
        String username=(String) session.getAttribute("username");
        response.getWriter().println("我是主页"+username);
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }
}
@WebServlet("/servletcontext/init")
public class ServletContextInitServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = req.getServletContext();
        servletContext.setAttribute("copyright","xxxx");
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().println("ServletContext已初始化");
    }
}
@WebServlet("/servletcontext/indx")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        ServletContext context = req.getServletContext();
        String copyright = (String)context.getAttribute("copyright");
        resp.getWriter().println(copyright);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/394817.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Jenkins最新版安装调试

清理旧的jenkins&#xff1a; find / -name jenkins* 一项一项的清理&#xff1a;rm -rf /var/log/jenkins* 下载最新版jenkins镜像&#xff1a;jenkins-redhat-stable安装包下载_开源镜像站-阿里云 上传到服务器&#xff1a; 安装命令&#xff1a; yum install -y jenkins…

Excel不愧是宝藏游戏机

你玩过95版Excel自带的游戏彩蛋吗&#xff1f; 众所周知&#xff0c;微软有做彩蛋的传统&#xff0c;这个传统最早是在1979年由比尔盖茨写下的basic复活节彩蛋开始的&#xff0c;当时你只需要输入“WAIT6502,1″,就可以跳出“MICROSOFT!”字符串。到后来&#xff0c;全体微软开…

Redis学习(六):主从复制,发布订阅和实际可能遇到缓存失效的情况

Redis发布订阅 Redis发布订阅&#xff08;Public/Subscribe&#xff09;是一种消息通信模式&#xff1a;发送者发送消息&#xff0c;订阅者接收消息。 Redis客户端可以订阅任意数量的频道。 这张图里有三个角色&#xff1a; 消息发送者频道&#xff08;消息队列&#xff09;…

AIGC时代,大模型微调如何发挥最大作用?

人工智能的快速发展推动了大模型的广泛应用&#xff0c;它们在语言、视觉、语音等领域的应用效果已经越来越好。但是&#xff0c;训练一个大模型需要巨大的计算资源和时间&#xff0c;为了减少这种资源的浪费&#xff0c;微调已经成为一种流行的技术。微调是指在预训练模型的基…

2023年3月全国DAMA-CDGA/CDGP数据管理认证火热报名中...

弘博创新是DAMA中国授权的数据治理人才培养基地&#xff0c;贴合市场需求定制教学体系&#xff0c;采用行业资深名师授课&#xff0c;理论与实践案例相结合&#xff0c;快速全面提升个人/企业数据治理专业知识与实践经验&#xff0c;通过考试还能获得数据专业领域证书。 DAMA认…

【iOS】—— 浅看block源码

block 文章目录block如何通过终端clang生成源码cpp文件block实质截获自动变量全局变量和静态变量的截获__block说明符iOS开发“强弱共舞”——weak和strong配套使用解决block循环引用问题如何通过终端clang生成源码cpp文件 之前在学习block中学习的比较浅&#xff0c;只看了oc…

sentinel源码入门

sentinel是一个流量治理组件&#xff0c;主要用来做降级、熔断和限流&#xff0c;以及监控等&#xff0c;sentinel的使用相对来说比较简单&#xff0c;这篇博客主要介绍sentinel的源码 入口 在使用sentinel的时候&#xff0c;我们需要引入sentinel的相关jar包&#xff0c;然后…

如何使用码匠连接 ClickHouse

目录 在码匠中集成 ClickHouse 在码匠中使用 ClickHouse 关于码匠 ClickHouse 数据源是一种列式数据库管理系统&#xff0c;由俄罗斯 Yandex 公司开发和维护。它专注于高性能、高并发、高可扩展性和低延迟的数据处理&#xff0c;特别是在海量数据的 OLAP&#xff08;联机分析…

性能分析利器:火焰图

什么是火焰图 火焰图&#xff08;FlameGraph&#xff09;是是由 Linux 性能优化大师 Brendan Gregg 发明的。通过 perf 等工具分析得到结果&#xff0c;看起来就像是火焰&#xff0c;这也是它的名字的由来。火焰图以一个全局的视野来看待时间分布&#xff0c;它从底部往顶部&am…

Dockerfile部署SpringBoot项目

Dockerfile部署SpringBoot项目 文章目录 利用Dockerfile部署SpringBoot项目 1、创建一个SpringBooot项目并且打成jar包2、在Linux中创建一个文件夹&#xff0c;来做docker测试3、将jar包上传到Linux中4、编写Dockerfile文件5、制作镜像6、启动容器7、查看容器启动日志8、访问接…

高效能自动化港口数字化码头智慧港航,中国人工智能企业CIMCAI世界港航人工智能领军者,成熟港口码头人工智能产品中国人工智能企业

打造高效能自动化港口数字化码头智慧港航&#xff0c;中国人工智能企业CIMCAI中集飞瞳世界港航人工智能领军者&#xff0c;成熟港口码头人工智能产品全球顶尖AI科技CIMCAI成熟AI产品全球前三船公司及港口落地&#xff0c;包括全球港口/堆场智能闸口验箱&#xff0c;全球港口岸边…

Vulnhub系列:Raven 1

该篇为Vulnhub系列靶机渗透&#xff0c;本次靶机存在4个flag。下面开始我们今天的渗透之旅。Raven靶机有很多种思路&#xff0c;我将对其进行一一整理。首先进行信息收集&#xff0c;利用arp-scan和nmap&#xff0c;进行靶机的ip及端口扫描发现了22、80、111端口。下面访问80端…

【LeetCode】剑指 Offer 23. 链表中环的入口节点 p139 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/c32eOV/ 1. 题目介绍&#xff08;23. 链表中环的入口节点&#xff09; 给定一个链表&#xff0c;返回链表开始入环的第一个节点。 从链表的头节点开始沿着 next 指针进入环的第一个节点为环的入口节点。如果链表无环&#x…

怎么清空回收站?3分钟解决!

真实案例&#xff1a;回收站清空不了怎么办&#xff1f;怎样清空回收站里的文件&#xff1f; “各位大神&#xff0c;怎么恢复回收站里清空的文件&#xff1f;我按照百度上的方法&#xff0c;还是不行。” 当你在电脑上删除文件时&#xff0c;它们通常会被移到回收站&#xf…

mpi4py 运行过程中出现Read -1, expected xxx, errno = 1 解决方案

目录 问题描述 代码1&#xff08;串行&#xff09; 代码2&#xff08;并行&#xff09; 代码2执行时所用指令 错误信息 解决方案 解决方案1 解决方案2 问题描述 今天正在学习使用mpi4py&#xff0c;在对比运行以下2个代码时疯狂报错&#xff1a; 代码1&#xff08;串…

HTML 脚本

HTML 脚本 JavaScript 是可插入 HTML 页面的编程代码。 JavaScript 使 HTML 页面具有更强的动态和交互性。 JavaScript 插入 HTML 页面后&#xff0c;可由所有的现代浏览器执行。 在线实例 插入一段脚本 如何将脚本插入 HTML 文档。 使用 <noscript> 标签 如何应对不…

非接触式流量监测设备——雷达流速仪

一、设备概述 雷达流速仪是一款非接触且可连续测量流速、水位、流量的一体式流量监测设备。它采用雷达平面微波技术&#xff0c;通过非接触方式测量水体的流速和水位。根据内置的软件算法&#xff0c;计算并输出实时断面流量及累计流量&#xff1b;可用于泵站、河道、灌渠、地…

扬帆优配|三大油气巨头都嗨了,龙头总市值盘中破万亿

近期组织盯上哪些股&#xff1f; 3月7日早盘&#xff0c;周期板块大幅上涨。石油板块涨超4%遥遥领先&#xff0c;海越能源涨停。油气巨头我国石油盘中涨近6%&#xff0c;总市值一度突破万亿元。我国石化盘中涨幅到达6.86%&#xff0c;股价创四年来新高。我国海油盘中涨停&#…

Rocketmq技术详解

Rocketmq技术详解 运维部署 docker-compose.yml version: 3.5 services:rmqnamesrv:image: foxiswho/rocketmq:servercontainer_name: rmqnamesrvports:- 9876:9876volumes:- ./logs:/opt/logs- ./store:/opt/storenetworks:rmq:aliases:- rmqnamesrvrmqbroker:image: foxisw…

后疫情时代,EIoT助力实体零售ESG战略落地

多点智能物联总经理刘汉彻 2023一开年&#xff0c;烟火气回归&#xff0c;各行各业都在摩拳擦掌&#xff0c;准备在后疫情元年“大干一场”。对企业而言&#xff0c;“降本增效”已成为跨行业的共同认知&#xff0c;实体零售也给自身的发展标定了方向&#xff1a;“彻底回归商…