【Java Web学习笔记】Servlet

编程入门 行业动态 更新时间:2024-10-03 10:45:00

【Java Web<a href=https://www.elefans.com/category/jswz/34/1770117.html style=学习笔记】Servlet"/>

【Java Web学习笔记】Servlet

Servlet

(1)Servlet与Tomcat的关系

图略

(2)概念

不能独立运行,要依赖于Web容器的一种Java服务器程序。

(3)Servlet开发的三种方式

需求:
1.进行Servlet开发,tomcat服务器向客户端发送信息。
步骤:
1.创建web应用。
2.将Servlet部署到web.xml

1. 实现Servlet接口
public class FirstServlet implements Servlet
{   //该函数用于Servlet初始化,并将其装载内存中//该函数只运行一次,需要在server.xml文件中进行配置<load-on-start>.public void init(ServletConfig config)throws ServletException{   }//得到ServletConfig对象public ServletConfig getServletConfig(){   }//该函数是服务函数,业务逻辑代码就是在这里编写//每次启动服务都会调用该函数//当调用doGet或者doPost才构造ServletRequest和ServletResponse对象public void service(ServletRequest req,ServletResponse res)
throws ServletException,java.io.IOException{   }//获取Servlet的配置信息public java.lang.String getServletInfo(){   }//该函数用于销毁Servlet//只运行一次public void destroy(){  }
}
2. 继承GenericServlet

相对于Servlet来说,是需要继承server函数即可。

GenericServlet抽象类,给出了一些设计servlet的一些骨架,定义了servlet的生命周期,还有一些得到的名字,配置初始化参数的方法,其设计是和应用层协议无关的。

3. 继承HttpServlet(常用)
public class FirstHttpServlet extends HttpServlet
{//两个底层都代用了server函数//Http协议中的get请求和post请求//与<form action="提交给?" method="get ro post?"/>中有关protected void doGet(HttpServletRequest req,HttpServletResonse resp)throws ServletException,java.io.IOException{resp.getWriter().println("HttpServlet");}protected void doPost(HttpServletRequest req,HttpServletResonse resp)throws ServletException,java.io.IOException{resp.getWriter().println("HttpServlet");}
}

(4)Servlet细节

1. Servlet的部署
<!—进行servlet的注册-->
<!-在android开发中的每个Activity都必须要注册—>
<servlet><!--servlet-name 可以自定义,但是默认为类名--><servlet-name>MyServlet</servlet-name><!--servlet-class 用于指定servlet存放在哪一个包中(包名+类名),一定要明确--><servlet-class>name.liushiyao.myservlet.MyServlet</servlet-class>
</servlet><!-- servlet 的映射(对一个已经注册的Servlet的映射)-->
<!--一个注册号的Servlet可以被多次映射-->
<servlet-mapping><!-- 该servlet-name 一定要去上面的servlet-name 相同--><servlet-name>MyServlet</servlet-name><!--url 的资源文件名(斜杠必须有)--><url-pattern>/ab</url-pattern>
</servlet-mapping>

注:
1. 如果url中没有加“/”运行时会出现错误。
2.在IDEA中(应该是JavaEE6的新特性,使用了annotation),可以使用@WebServlet(name = “LastTime”, urlPatterns ={“/LastTime”,”/LastTime2”})进行WebServlet的映射,且可以实现多对一映射,而不需要在web.xml中进行注册。

2. 通配符

    1) /*2) *.拓展名注:1)比2)优先级高。

3. 单例多线程

当Servlet被第一访问后,就被加载到内存中,以后该实例对各个请求都是用的是同一个内容。JSP也是单例模式。
servlet是多线程的,没有采用同步机制,是不安全的。同一个Servlet可以同时处理多个客户端的请求,比如同时有两个用户A和用户B登录时,会启动两个负责登录的Servlet线程,并通过触发Service方法来处理请求。在两个线程中,接收到的用户名是不同的,也就是说,多线程里的Servlet,可能其中的变量不相同。

4. servlet中的配置

需求:当我们的网站启动的时候,可能会要求初始化一些数据(创建临时表),或者要求定时备份数据,发送邮件。
解决办法:可以通过<load-on-startup>配合,线程知识搞定。通过配置<load-on-startup>,启动一个servlet中的init函数,且只运行一次。

在web.xml文件中进行配置

<!-- 配置init启动的优先级(必须配置,否者init()不会执行) -->
<load-on-startup>1</load-on-startup>
<!—数值代表启动的顺序-->

【模拟定时发送电子邮件】

//用于发送电子邮件的线程
public class Send extends Thread
{@Overridepublic void run() {int count = 0;while(true){try {//====每隔10s发送电子邮件Thread.sleep(10*1000);System.out.println("第"+(++count)+"份邮件被发送");} catch (InterruptedException e) {e.printStackTrace();}}}
}
//使用init函数进行线程的启动
public void init() throws ServletException {// Put your code hereSystem.out.println("ServletInit 的init函数运行。。。");Send send = new Send();send.start();
}

ServletConfig对象

1. 用途
    用于读取Servlet的一些配置信息。

在web.xml文件中。

<!-- 使用UTF-8编码 -->
<!-- 局部servlet有效 -->
<init-param><param-name>encoding</param-name><param-value>utf-8</param-value>
</init-param>

注:String contextString = this.getServletConfig.getInitParameter(“encoding”);
要使被所有的servlet读取,应该在之外定义:

<!—所有servlet有效 -->
<context-param><param-name></param-name><param-value></param-value>
</context-param>

注:通过String contextString = this.getServletContext().getInitParameter(“encode”);获取
因为该属性属于全局变量,而ServletContext也是属性全局的,所以要通过getServletContext获取,而不是通过getServletConfig获取。

【获取ServletConfig中的数据】
1. 获取单一的数据在Servlet中

response.setContentType("text/html;charset=utf-8");//默认编码
PrintWriter printWriter = response.getWriter();
//获取param参数内容
String encodingString  = this.getServletConfig().getInitParameter("encoding");
request.setCharacterEncoding(encodingString);
printWriter.println(encodingString);
printWriter.close();
  1. 获取所有的数据
//获取所有的param的enum对象
Enumeration<String> enum1 = this.getServletConfig().getInitParameterNames();
while (enum1.hasMoreElements()) {String string = (String) enum1.nextElement();System.out.println(string);System.out.println(this.getServletConfig().getInitParameter(string));
}

HttpResponse对象

所有的信息多会封装到response中,返回给web服务。web服务器会将response信息进行拆解,形成http相应信息,返回给浏览器。
1. getWrite();与getOutputStream()
注:一个是字符流,一个是字节流。虽然说两者可以相互转换,但是针对不同的数据针对性的使用。

两个流不能同时使用。否则会出现如下异常:
java.lang.IllegalStateException: getWriter() has already been called for this response
org.apache.catalina.connector.Response.getOutputStream(Response.java:605)
org.apache.catalina.connector.ResponseFacade.getOutputStream(ResponseFacade.java:197)
name.liushiyao.userlogin.Download.doGet(Download.java:37)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

注:会自动关闭IO,所以不能同时出现getWrite();getOutputStream();

2. sendRedirect();

sendRedirect( 重定向)发生在浏览器的跳转,服务器根据逻辑,发送一个状态码,告诉浏览器去重新请求那个地址。

实现界面的跳转,并可以随带字符串信息。
1. 实现跳转:

//执行调转到登录成功界面(java中其中一种跳转方式)
//"/web应用名/servlet"
response.sendRedirect("/UserLogin/MainFrame");
  1. 携带字符串信息:
response.sendRedirect("/UserLogin/MainFrame?uname="+
name+"&upassword="+password

注:url与字符串信息之间通过“?”进行连接。
不同的字符串之间通过“&”连接。
sendRedirect不能实现对象的传递。但是可以通过session传递(也不能说是“传递”,只是在服务器内存中存储的session)。

User u = new User(name,password);
request.getSession().setAttribute("u",u);
  1. 获取对象:
    User us = (User)request.getSession().getAttribute("u");out.println(us.getName()+"||"+us.getPassword());

HttpRequest对象

该对象表示浏览器的请求,即http请求信息。但web服务器等到该请求后,会把浏览器请求的信息封装成HttpRequest对象。因此可以通过该对象获取用户的各种请求信息。
1. getRequestURL();
String uri = request.getRequestURI();
String url = request.getRequestURL().toString();
System.out.println("uri"+uri);
System.out.println("url"+url);

输出:

uri  /RequestDemo/RequestInfo
url  http://localhost:8080/RequestDemo/RequestInfo
2. getQueryString();

以GET方法获取参数信息(参数+值)。

    String quary = request.getQueryString();System.out.println("query:"+quary);

输出:
query:name=123

注:这个的参数时url后面带的所有信息,而request.getParameter(“age”);则是当个属性所带的值

3. getRemoteAddr();

可以获取用户的ip地址。(利用该函数可进行ip封杀)

4. getRemotePort();

获取用户的端口。

int localport = request.getLocalPort();
int port = request.getRemotePort();
System.out.println("localport:"+localport);
System.out.println("port:"+port);
5. getParameterValues();

获得传过来的参数名相同的一个数组;
String[] string = request.getParameterValues(“checkbox”);

6. getRequestDispatcher();

request转向函数。

request.getRequestDispatcher("/MainFrame").forward(request, 
response);

实现原理:

  1. sendReDirect与forward的区别?

    forward(转向):发生在服务器的跳转,服务器请求资源,直接访问目标地址的URL,把URL的响应再发送给浏览器,浏览器根本不知道服务器发送的内容是从哪里来的,所以地址栏中的URL还是原来的。


答:(1)叫法不同:sendReDirect()叫重定向(转发);forward叫转向。
(2)实际发送的位置不同:sendReDirect发生在浏览器;forward发生在服务器
(3)用法不同:response.sendReDirect(“/web应用/资源URI”);需要加‘/web应用名’(根据其原理可以知道)
request.getRequestDispather(“/资源URI”).forward(request,response);
不需要加web应用名
(4)范围不同:sendReDirect 与浏览器之间
forward 与web服务器之间。

注:1.所谓的一次http请求:就是没有重回到浏览器或者重新启动则叫为“一次http请求”。
2.request.setAttribute(“key”,”123”);//存储此请求中的属性。在请求之间重置属性。此方法常常与 RequestDispatcher 一起使用。
3. //效果同request.getRequestDispather request.getServletContext().getRequestDispatcher(“/OtherServlet”).forward(request,response);
4. 使用sendReDirect可以防止刷新带来的再次访问servlet(因为sendReDirect需要web应用名)

1. 概念
cookie是客户端技术,服务器把每个用户的数据以cookie的形式写给用户各自的浏览器。 Cookie包含属性(String)和值(String)。

注:1. Cookie只能保存字符串(键值对)
2. 客户端在发送Http请求时,会携带该Web应用的Cookie。
3. Cookie必须设置setMaxAge,否则Cookie在浏览器关闭时被销毁(setMaxAge(0)则销毁Cookie)。
4. 可以被多个浏览器共享。
5. 如果Cookie重名,会覆盖之前的数据。
6. 当web创建多个Cookie时,会保存在同一个文件中,并且存在时间可以不一样。
7. 创建Cookie时禁止使用“ 空格、逗号”等。

2. Cookie的用途
账号和密码的保存(需要加密)、用户的喜好、设置等等。
3. Cookie的限制
一个浏览器只能存放300个Cookie,一个web站点最多存储20个Cookie,且 每个大小限制在4K。
4.禁用Cookie
如果用户禁用Cookie,可以使用URL重写技术跟踪回话。
5. Cookie的生命周期
Cookie的生命周期指的是累积时间,即从开始创建时间到设置的结束时间的长度。

Session

1. 概念
Session(域对象)是服务器端技术,当用户打开浏览器,访问服务器。服务器为每一个浏览器提供一个Session对象。 Session包含属性(String)和值(Object)。

注:1. 只要不关闭浏览器,不同的页面就会处于同一个Session中,而这个Session默认的生存时间是1800s(30分钟,可以在web.xml中修改)。
2. session是存放在服务器的内存中的
3. session被特定的一个浏览器所独享
4. 当同一个session中的属性名相同时则会覆盖前一个属性值

2. Session的生命周期
  1. 在web.xml中可以进行生存时间的设定
<session-config><session-timeout>20</session-timeout>
</session-config>
  1. 使用httpSession.setMaxInactiveInterval(60);
    //该时间设置的是“发呆时间”—用户没有操作Session的时间
  2. 当关闭或重启Tomcat时都会删除Session(Session是保存在内存中的)或者使用 invalidate(); 删除Session中所有的属性和对象(强制性的,用于安全退出)
  3. 单独删除一个对象
    httpSession.removeAttribute(“name”);
3. Session的原理

服务器如何为特定的浏览器分配特定的Session?
答:通过ID
实现流程:
1. 当浏览器第一次访问Servlet时,Cookie中是没有携带JSESSIONID
(Cookie JSESSIONID=D7561FE5F83BACF4E0091BCDADE04078),
2. 访问Servlet之后,会生成Session并分配Session ID,通过Cookie写入浏览器中;
3. 当用户再次访问Servlet,http请求会携带带有JSESSIONID的cookie,此时服务器就能准确的知道该浏览器是与那个Session相关联的。

6. Cookie与Session的区别?

①存在的位置不同:
Cookie:存在客户端(临时文件夹)
Session:存在服务器的内存中(一个Session域对象为一个用户浏览器服务)
②安全性
Cookie:是以明文方式存放在客户端,安全性较弱(可以通过加密的方式进行加密)
Session:是存在服务器中的内存中,安全性较强。、
③网络通信量
Cookie:会传递信息给服务器(每次在Http请求中都会携带Cookie,所以会增加网络压力)(所以获取Cookie时是从Request中获取 的)
Session:session是存在服务器的内存中的,所以不存在网络通信压力问题。
④生命周期
Cookie:是累积时间,即为绝对时间
Session:是“发呆时间”,即相对时间(当浏览器没有对session进行操作时的间隔时间)。session失效是指无法访问session的属性(API解释:使此会话无效,然后取消对任何绑定到它的对象的绑定。)。相关应用(安全退出)
⑤访问范围
Cookie:浏览器共享
Session:浏览器独享
注:Session会占用服务器的内存,所以要根据实际情况进行取舍。

ServletContext

1. 概念
Web容器在启动时,它会为每一个Web应用程序都创建一个对应的ServletContext对象,它代表web应用。
注:可以被多个用户共享(同一个Web应用中的所有Servlet)
2. 获取ServletContext

//方法一(通过this)
ServletContext servletContext = this.getServletContext();
//方法二(通过getServletConfig)
ServletContext servletContext1 = this.getServletConfig().getServletContext();

3. 添加ServletContext属性

servletContext.setAttribute(“name”,”刘石尧”);

4. 读取ServletContext属性

String string = (String) servletContext.getAttribute(“name”);

5. 删除ServletContxt 属性

if (servletContext.getAttribute(“name”) != null){
servletContext.removeAttribute(“name”);
out.println(“已删除 name”);
}

6. 使用ServletContext的使用原则

需要数据共享,而且存储的大小不大又不想出入数据库,可以使用ServletContext。

7. ServletContext的生命周期

ServletContext是长期存放在服务器中的内存中的,所有不将过大的数据存放在ServletContext中。

8.获取web.xml中的设置参数

context.getInitParameter("param");

会话跟踪

会话跟踪是一种灵活,轻便的机制,使Web上的状态变成成为可能。
可是使用session,Cookie,地址重写和隐藏域实现。

JSP

JSP九大内置对象

内置对象对象名称类型作用域
request请求对象javax.servlet.ServletRequesRequest
response响应对象javax.servlet.SrvletResponsePage
pageContext页面上下文对象javax.servlet.jsp.PageContextPage
session会话对象javax.servlet.http.HttpSessionSession
application应用程序对象javax.servlet.ServletContextApplication
out输出对象javax.servlet.jsp.JspWriterPage
config配置对象javax.servlet.ServletConfigPage
page页面对象javax.lang.ObjectPage
exception例外对象javax.lang.Throwablepage

注:“exception” 对象则代表了JSP文件运行时所产生的例外对象,此对象不能在一般JSP文件中直接使用,而只能在使用了“<%@ page isErrorPage=”true “%>”的JSP文件中使用。

作用域

作用域范围说明
page有效范围只在当前jsp页面里从把变量放到pageContext开始,到jsp页面结束,你都可以使用这个变量。
request有效范围是当前请求周期所谓请求周期,就是指从http请求发起,到服务器处理结束,返回响应的整个过程。在这个过程中可能使用forward的方式跳转了多个jsp页面,在这些页面里你都可以使用这个变量。
session有效范围是当前会话所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。这个过程可能包含多个请求响应。也就是说,只要用户不关浏览器,服务器就有办法知道这些请求是一个人发起的,整个过程被称为一个会话(session),而放到会话中的变量,就可以在当前会话的所有请求里使用。
application有效范围是整个应用整个应用是指从应用启动,到应用结束。我们没有说“从服务器启动,到服务器关闭”,是因为一个服务器可能部署多个应用,当然你关闭了服务器,就会把上面所有的应用都关闭了。

  application作用域里的变量,它们的存活时间是最长的,如果不进行手工删除,它们就一直可以使用。
  

注:application里的变量可以被所有用户共用。如果用户甲的操作修改了application中的变量,用户乙访问时得到的是修改后的值。这在其他scope中都是不会发生的,page, request,session都是完全隔离的,无论如何修改都不会影响其他人的数据。

jsp注释

1. <%-- JSP中的注释,看不见 --%>
2.  // 注释,看不见
3.   /*注释,看不见*/
4. <!--显式注释-->

JSP语法

脚本

<% java代码 %>:在<%%>中定义局部变量或者调用方法,但不能定义方法。

<%!%>:可以在<%!%>中声明方法、属性、全局变量。

<%=%>:称作jsp表达式,用于将已经声明的变量或者表达式输出到网页上面。

include指令

静态include:
从外部引入一个jsp文件(只含指令和内容本身,不需要body等其他内容),编译成同一个servlet。属于静态引入。

<%@ include file="B.jsp" %>

动态include:

<jsp:include />

注:动态引入,会翻译成两个servlet。所以被引入的文件可以包含等内容。

更多推荐

【Java Web学习笔记】Servlet

本文发布于:2024-03-15 12:42:13,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1770091.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:学习笔记   Java   Web   Servlet

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!