【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
{
    @Override
    public 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 here
        System.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。所以被引入的文件可以包含等内容。

weixin073智慧旅游平台开发微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
python017基于Python贫困生资助管理系统带vue前后端分离毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
weixin102旅游社交微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值