Marco's Java 之【Servlet基础】

Servlet

Servlet是一个运行在服务器端的Java小程序,通过HTTP协议用于接收来自客户端请求,并发出响应。

广义: 是指tomcat中的一个插件,一个可用于获取HTTP请求中的数据的插件
狭义: 就是一个实现了Servlet相关接口的类

web.xml中配置
 <servlet>
	<!--   为servlet取得别名   -->
	<servlet-name>servletSample</servlet-name>
	<!--   为servlet具体的对应类   -->
	<servlet-class>com.sxt.servlet.ServletSample</servlet-class>
</servlet>
<servlet-mapping>
	<!--   自己定义的servlet的别名,同servlet标签中的别名相互映射   -->
	<servlet-name>servletSample</servlet-name>
	<!--   在浏览器的地址栏上访问的路径  注意:  需要使用/  -->
	<url-pattern>/servletSample</url-pattern>	
</servlet-mapping>
Servlet中的方法

ServletRequest request: 代表着请求对象,该对象中有HTTP协议的请求部分的所有内容。它的实现类由服务器提供的,封装数据也是服务器来做的。
ServletResponse response: 代表着响应对象,该对象中由我们写数据(HTTP协议的响应部分)进去。它的实现类也是由服务器提供的。
service: 由服务器调用,每次请求都会调用一次。服务器采用的是多线程机制。

public void service(ServletRequest req,ServletResponse res) 
	throws ServletException,java.io.IOException
HttpServlet,GenericServlet,Servlet的关系

在这里插入图片描述
注意: 当我们自定义类继承HttpServlet时,只需要覆盖doGet和doPost方法即可,切记不要覆盖service()方法,因为当我们每次向Browser发出访问请求时,服务器都会调用该方法,因此如果我们覆盖了service()方法,那么访问将无法正常执行!

Servlet的执行过程

在这里插入图片描述

Servlet的生命周期

生命周期:

  • 诞生:用户第一次访问时,由容器创建他的实例。
  • 生存:一旦创建就驻留内存(单例)。每次用户的访问,容器都会调用sevice方法发出响应(多线程)
  • 死亡:应用被卸载或者Tomcat关闭了
 //用户第一次访问时,只执行一次
 public MyServlet(){
  System.out.println("调用了Servlet的构造方法");
 } 
 //用户第一次访问时,执行一次。 为servlet初始化一些信息
 public void init() throws ServletException {
  System.out.println("调用了Servlet的初始化方法");
 }
 // 每次访问都会调用service方法
 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  System.out.println("执行doGet方法");
 }
 public void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  doGet(request, response);
 }
 //调用一次。当服务器停止时  会调用destroy
 public void destroy() {
  System.out.println("调用Servlet的销毁方法");
 }

ServletContext

ServletContext 代表着当前应用。每个应用只有用一个ServletContext对象实例。

ServletConfig.getServletContext();//获取ServletContext实例对象

ServletContext的生命周期

  • 诞生:应用被加载时创建,有别于Servlet(用户第一次访问时创建)
  • 生存:随着应用的生存而生存,一旦被创建就一直驻留,Servlet属于单例
  • 死亡:随着应用的死亡而死亡(当应用被卸载或者Tomcat关闭)

域(存活范围)对象:
ServletContext是应用范围域对象,是Web四大域对象中最大的域对象。
注意: Servlet可以被创建多个,而ServletContext则只有一个且被所有的Servlet实例对象共用

/*获取WEB应用的初始化参数*/
ServletContext sc = getServletContext();
  String s = sc.getInitParameter("encoding");//获取指定的一个参数
  System.out.println(s);//输出UTF-8
  Enumeration<String> names = sc.getInitParameterNames();//获取参数名称,返回枚举
  while(names.hasMoreElements()){
   String contextName = names.nextElement();
   System.out.println(contextName+"="+sc.getInitParameter(contextName));
  }

读取资源的三种方式

ClassLoader读取: 只能读取classes或者类路径中的任意资源。但是不适合读取特别大的资源。

 private void readSrc() throws IOException {
  //得到类的字节码文件,在得到类得加载器
  ClassLoader loader = GetResource.class.getClassLoader();
  	//获取与src目录同级的resources目录下的properties文件
	URL url = loader .getResource("/resources/1.properties");
	//获取src目录下的properties文件
  	URL url = loader .getResource("/2.properties");
  	InputStream is = new FileInputStream(url.getPath());
  	Properties prop = new Properties();
  	prop.load(is);
  	System.out.println(prop.getProperty("I' marco"));
 }

ResourceBundle读取: 只能读取properties的文件,且只能读取classes内资源

private void readSrc(){
	//获取src目录下的properties文件
   	ResourceBundle rb = ResourceBundle.getBundle("2");
   	//获取与src目录同级的resources目录下的properties文件
   	ResourceBundle rb = ResourceBundle.getBundle("resource.1");
 	System.out.println(rb.getString("I' marco")); 
}

getServletContext().getRealPath读取: 可以读取应用中任何位置上的资源,但是只能在web应用中用

private void readSrc() throws IOException{
	//获取与src目录同级的resources目录下的properties文件
   	String realPath = getServletContext().getRealPath("/WEB-INF/classes/resources/1.properties");
   	//获取src目录下的properties文件
   	String realPath = getServletContext().getRealPath("/WEB-INF/classes/2.properties");
   	//获取Tomcat根目录下的properties文件
 	String realPath = getServletContext().getRealPath("/3.properties");
 	InputStream is = new FileInputStream(realPath);
 	Properties prop = new Properties();
 	prop.load(is);
 	System.out.println(prop.getProperty("I' marco"));
}

注意: 不要把Tomcat等服务器装在有空格的目录中


重定向和内部转发

重定向

格式:response.sendRedirect(URL);

使用重定向这种方式传参时,需要将传递的参数拼接在URL地址栏上,其本质上就是让浏览器带着这些参数去访问重定向地址,因此,他的参数传递就是GET请求方式。
由于他的本质就是GET请求,所以如果要进行参数传递,那么我们传递的数据就不能太大了,也不能传递对象。
最主要的问题就是,当我们用这种方式来传参时,非常的不安全。

response.sendRedirect(URL + "?userName=marco");

需要注意的是,当我们发出一次请求,其实请求的是两次,怎么理解呢?
譬如说当我们想访问一个页面,此时浏览器会向服务器发送第一次请求,那么服务器收到请求后,会返回你要访问的页面的地址,浏览器收到这个页面的地址后,会再次访问这个获取到的地址,因此请求是有两次。

这就好比,我们去医院看病,我们不知道具体的位置,那么就要去咨询前台的小姐姐,她会告诉你,就诊的位置在几楼,我们再去相应的位置即可。
在这里插入图片描述

内部转发

格式:request.getRequestDispatcher(URL).forward(request, response);
内部转发的方式也不会将参数带到页面上去,必需要通过设置request对象属性值来进行参数传递

request.setAttribute("userName","marco");
request.getRequestDispatcher(URL).forward(request, response);

因此通过内部转发的方式我们可以传输大量的数据到页面,然后在前端进行数据解析渲染,且通过这种方式,我们的数据不会显示在URL地址栏上,相对来说要安全的多。我们在做账号密码校验的时候,通常都要使用这种安全的方式。
那这种方式就好比你是某某公司的VIP客户,你要见你的客户经理,你到前台了,咨询前台,我要怎么去找我的客户经理,那这个小姐姐会直接去办公室找到对应的负责人,直接待人过来。服务器也是一样,他们在内部会进行信息的转发,无须让浏览器再次发出请求,而可以直接拿到响应的结果。

在这里插入图片描述

虽然内部转发的方式优点很多,但是缺点也很明显

内部转发的缺点:

  • 使用内部转发进行页面刷新,第一次请求的参数会再次提交,并且所有的中间的相关资源都会再执行一遍,这样过多的重复操作,会增加服务器的压力
  • 如果有人可以的通过这种方式对服务器施加压力,可能会导致服务器崩溃

那我们再稍微总结一下这两种传递方式的区别
1.请求转发后地址栏不会改变,可以继续使用request中的数据,而重定向的数据则是在地址栏上显示的,当重定向后,地址栏发生改变,request中的数据会丢失。
2.转发是服务器内部发生的跳转,整个过程只有一次请求,而重定向是客户端的跳转,整个过程包含两次请求,关于这一点,上面我们有提到。
3.转发的方式只能访问服务器内部的资源,而重定向则可以访问外部资源。

因此,当我们在选择这两种方式的时候,也需要慎重考虑,一般情况下,如果不知道该怎么去选择的时候,我们可以使用内部转发。但是如果想适度减少服务器的压力的情况下,我们可以在某些不需要大量传输数据,并且安全性要求没有那么高的情况下,我们可以选择使用重定向的方式,如果没有这类要求,安安稳稳使用内部转发就好啦

(1)普通用户端(全平台) 音乐播放核心体验: 个性化首页:基于 “听歌历史 + 收藏偏好” 展示 “推荐歌单(每日 30 首)、新歌速递、相似曲风推荐”,支持按 “场景(通勤 / 学习 / 运动)” 切换推荐维度。 播放页功能:支持 “无损音质切换、倍速播放(0.5x-2.0x)、定时关闭、歌词逐句滚动”,提供 “沉浸式全屏模式”(隐藏冗余控件,突出歌词与专辑封面)。 多端同步:自动同步 “播放进度、收藏列表、歌单” 至所有登录设备(如手机暂停后,电脑端打开可继续播放)。 音乐发现与管理: 智能搜索:支持 “歌曲名 / 歌手 / 歌词片段” 搜索,提供 “模糊匹配(如输入‘晴天’联想‘周杰伦 - 晴天’)、热门搜索词推荐”,结果按 “热度 / 匹配度” 排序。 歌单管理:创建 “公开 / 私有 / 加密” 歌单,支持 “批量添加歌曲、拖拽排序、一键分享到社交平台”,系统自动生成 “歌单封面(基于歌曲风格配色)”。 音乐分类浏览:按 “曲风(流行 / 摇滚 / 古典)、语言(国语 / 英语 / 日语)、年代(80 后经典 / 2023 新歌)” 分层浏览,每个分类页展示 “TOP50 榜单”。 社交互动功能: 动态广场:查看 “关注的用户 / 音乐人发布的动态(如‘分享新歌感受’)、好友正在听的歌曲”,支持 “点赞 / 评论 / 转发”,可直接点击动态中的歌曲播放。 听歌排行:个人页展示 “本周听歌 TOP10、累计听歌时长”,平台定期生成 “全球 / 好友榜”(如 “好友中你本周听歌时长排名第 3”)。 音乐圈:加入 “特定曲风圈子(如‘古典音乐爱好者’)”,参与 “话题讨论(如‘你心中最经典的钢琴曲’)、线上歌单共创”。 (2)音乐人端(创作者中心) 作品管理: 音乐上传:支持 “无损音频(FLAC/WAV)+ 歌词文件(LRC)+ 专辑封面” 上传,填写 “歌曲信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值