JavaEE

Servlet

Servlet生命周期

// 当一个类继承HttpServlet类时,那他就是一个servlet类
public class FirstServlet extends HttpServlet {
    
    //当servlet第一次被载入容器时执行,只执行一次
    //load-on-startup配置载入时机
    @Override
    public void init(){
        System.out.println("Servlet初始化");
    }
    	
     //每次请求都执行
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp){
        System.out.println("Servlet被请求,当存在此方法时不会在执行doGet,doPost方法");
    }
    
    //关闭服务器Servlet被销毁时执行
    @Override
    public void destroy() {
        System.out.println("Servlet被销毁");
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("我是GET请求方法");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("我是POST请求方法");
    }
}

配置servlet

<!-- Servlet配置 目的是让tomcat容器接纳Servlet
当输入URL,tomcat才能找到对应的Servlet -->
	<servlet>
		<!-- Servlet别名 -->
		<servlet-name>FirstServlet</servlet-name>
		<!-- Servlet全路径 -->
		<servlet-class>com.test.hello.FirstServlet</servlet-class>
    <!-- 
		标记容器是否在启动的时候就加载这个servlet。
    当值为0或者大于0时,表示容器在应用启动时就加载这个servlet;
    当是一个负数时或者没有指定时,则指示容器在该servlet被第一次请求时才加载。
    正数的值越小,启动该servlet的优先级越高。 -->
    <load-on-startup>1</load-on-startup>	
 </servlet>
	<!-- 路由-servlet映射规则 -->
<servlet-mapping>
    <!-- 上面配置的别名 -->
    <servlet-name>FirstServlet</servlet-name>
    <!-- 路由 -->
    <url-pattern>/</url-pattern>
</servlet-mapping>

请求路径优化

<%  String basePath = request.getScheme()+":"+"//"                //获取协议          +request.getServerName()+":"                          //获取域名          +request.getServerPort()                              //获取端口号          +request.getServletContext().getContextPath()+"/";    //获取工程目录 %> <form method="post" id="loginForm" action="<%=basePath %>login">              

请求和响应

  • 浏览器对服务器的一次访问称之为一次请求,请求用HttpServletRequest表示
  • 服务器给浏览器的一次反馈称为一次响应,响应用HttpServletResponse表示

ServletContext与ServletConfig

  • ServletContext对象表示整个JavaWeb工程
  • ServletConfig表示某个Servlet的配置信息
@WebServlet("/ContextOne")
public class ContextOne extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        // 往context域对象中存放数据
        context.setAttribute("username", "测试");
        // 取出context域对象中的数据
        Object result = context.getAttribute("username");
        // 打印取出的结果
        System.out.println("存放数据"+result);
        
        
        ServletConfig sc = this.getServletConfig();
        // 获取sc这个对象中封装的参数信息k-v
        String n = sc.getInitParameter("year");
        System.out.println("this year=" + n);
    }
}

// 当这个Servlet被请求时,下面的参数会被封装到ServletConfig对象中
<servlet>
    <servlet-name>ContextOne</servlet-name>
    <servlet-class>ContextOne</servlet-class>
    <init-param>
        <param-name>year</param-name>
        <param-value>2019</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>ContextOne</servlet-name>
    <url-pattern>/context</url-pattern>
</servlet-mapping>

重定向/转发

  • 转发调用的是HttpServletRequest对象方法
  • 重定向调用的是HttpServletResponse对象方法
  • 转发时URL地址不会变化 / 重定向会改变
  • 转发浏览器请求一次服务器/重定向请求两次
// 传递参数
@WebServlet( "/ForWord")
public class ForWord extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 转发带数据给某个jsp页面
         request.setAttribute("username", "王二麻子");
         request.getRequestDispatcher("/demo.jsp").forward(request, response);

        // 通过重定向带数据过去
//        ServletContext sc = request.getServletContext();
//        sc.setAttribute("goods", "娃娃");
//        response.sendRedirect("/FirstServlet/demo.jsp");
    }
}       

//接收参数

<body>
<!-- 取出ForWord中传递过来的数据 -->
<%
    String username = (String)request.getAttribute("username");
    out.print(username);
%>
<%
    String goods = (String)application.getAttribute("goods");
    out.print(goods);
%>
</body>

JSP

基本原理

JSP的本质是Servlet,当用户向指定Servlet发送请求时,Servlet利用输出流动态生成HTML页面,包括每一个静态的HTML标签和所有在HTML页面中出现的内容。

注释

jsp注释不会输出到浏览器<%—注释内容--%>
html注释可以被看到

内置对象

  • application: javax.servlet.ServletContext 的实例,该实例代表 JSP 所在的 Web 应用本身,可将信息保存在服务器中,直到服务器关闭,类似全局变量。
    • getAttribute(String attName)
    • setAttribute(String attName,String attValue)
    • getlnitParameter(String paramName)等。
  • config: javax.servlet.ServletConfig的实例,该实例代表该JSP的配置信息,主要作用是取得服务器的配置信息。
    • getlnitParameter(String paramName)
    • getlnitParameternames()等方法。
  • exception: java.lang.Throwable的实例,该实例代表其他页面中的异常和错误。只有3贞面 是错误处理页面,即编译指令page的isErrorPage属性为true时,该对象才可以使用。
    • getMessage()
    • printStackTrace()等。
  • out: javax.servlet.jsp.JspWriter的实例,该实例代表JSP页面的输出流,用于输出内容, 形成HTML页面。
  • page:代表该页面本身,也就是Servlet中的this,其类型就是生成的 Servlet类,能用page的地方就可用this。
  • pageContext: javax.servlet.jsp.PageContext的实例,该对象代表该JSP贞面上下文,该对象的作用是取得任何范围的参数。
    • getServletContext()-- 获取application内置对象;
    • getServletConfig()-- 获取config内置对象
  • request: javax.servlet.http.HttpServletRequest 的实例,该对象封装了一次请求,客户端的请求参数都被封装在该对象里。这是一个常用的对象,获取客户端请求参数必须使用该对象。
    • getParameter(String paramName)
    • getParameterValues(String paramName)
    • setAttribute(String attrName,Object attrValue)
    • getAttribute(String attrName)
    • setCharacterEncoding(String env)
  • response: javax.servlet.http.HttpServletResponse 的实例,代表服务器对客户端的响应。 通常很少使用该对象直接响应,而是使用out对象,除非需要生成非字符响应。而response 对象常用于重定向,
    • getOutputStream()
    • sendRedirect(java.lang.String location)等。
  • session: javax.servlet.http.HttpSession的实例,该对象代表一次会话。当客户端浏览器与站点建立连接时,会话开始;当客户端关闭浏览器时,会话结束。
    • getAttribute(String attrName)
    • setAttribute(String attrName, Object attrValue)

JSTL标签库

JSP页面前缀

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix="c"%>

表达式控制标签

  • out标签:用来输出数据对象(字符串、表达式)
<c:out value="字符串">
<c:out value="EL表达式">
  • set标签:把某一个对象存在指定的域范围内
<c:set value="值" var="变量名"  
[scope="page|request|session|application"]/>

<c:set var="变量名" [scope="page|request|session|application"]>
  值
</c:set>

<c:set target="JavaBean对象" property="属性名">
  值
</c:set>
含义:把一个值赋值给指定的JavaBean的属性名。
  • remove标签:移除指定变量
•<c:remove var="变量名"
[scope="page|request|session|application"]/>
  • catch标签:用于捕获嵌套在标签体中的内容抛出的异常
<c:catch var ="catchException">
   <% int x = 5/0; %>
</c:catch>

<c:if test = "${catchException != null}">
   <p>异常为 : ${catchException} <br />
   发生了异常: ${catchException.message}</p>
</c:if>

流程控制标签

  • if标签
<c:if test="<boolean>" var="<string>" scope="<string>">
   test属性用于存放判断的条件,一般使用EL表达式来编写
   var属性用来存放判断的结果,类型为true或false
   scopes属性用来指定var属性存放的范围
</c:if>

<c:set var="salary" scope="session" value="${2000*2}"/>
<c:if test="${salary > 2000}">
   <p>我的工资为: <c:out value="${salary}"/><p>
</c:if>
  • choose标签、when标签、otherwise标签
<c:choose>
    <c:when test="<boolean>">
        ...
    </c:when>
    <c:when test="<boolean>">
        ...
    </c:when>
    <c:otherwise>
        ...
    </c:otherwise>
</c:choose>

循环标签

  • forEach标签:迭代一个集合中的对象
<c:forEach
    items="<object>"  items指定要遍历的集合
    begin="<int>"  起始位置  0=第一个元素,1=第二个元素
    end="<int>" 终止位置
    step="<int>" 循环的步长
    var="<string>" 每个变量名字
    varStatus="<string>"> 每个对象的状态
....    
</c:forEach>

<c:forEach var="i" begin="1" end="5">
   Item <c:out value="${i}"/><p>
</c:forEach>

 <c:forEach items="${str}" var="s" begin="1" end="5" step="2" varStatus="status">
|每个变量的索引位置 int
        <c:out value="index属性:${status.index}"></c:out>
|计数,这个变量是第几个 int
        <c:out value="count属性:${status.count}"></c:out>
|这个元素是不是第一个 boolean
        <c:out value="first属性:${status.first }"></c:out>
|这个元素是不是最后一个 boolean
        <c:out value="last属性:${status.last }"></c:out>
|<br/>
</c:forEach>
  • forTokens标签:通过指定分隔符将字符串分隔为一个数组然后迭代它们
<c:forTokens
    items="<string>"  items指定要遍历的字符串
    delims="<string>" 指定分隔符
    begin="<int>" 起始位置 0=第一个元素,1=第二个元素
    end="<int>" 终止位置
    step="<int>" 循环的步长
    var="<string>" 每个变量名字
    varStatus="<string>"> 每个对象的状态
 ....   
</c:forTokens>

<c:forTokens items="google,runoob,taobao" delims="," var="name">
   <c:out value="${name}"/><p>
</c:forTokens>

URL操作标签

import标签:该标签可以把其他静态或动态文件包含到本JSP页面
URL为资源的路径,当引用的资源不存在时系统会抛出异常,因此该语句应该放在<c:catch></c:catch>语句块中捕获
与<jsp:include>的区别
<jsp:include>只能包含同一个web应用中的文件
<c:import>可以包含其他web应用中的文件,甚至是网络上的资源

<c:import
   url="<string>" 待导入资源的URL,可以是相对路径和绝对路径
   var="<string>"  用于存储所引入的文本的变量
   scope="<string>"  var属性的作用域
   varReader="<string>" 可选的用于提供java.io.Reader对象的变量
   context="<string>" 当使用相对路径访问外部context资源时,context指定了这个资源的名字。
   charEncoding="<string>"/>所引入的数据的字符编码集
   
<c:import var="data" url="http://www.baidu.com"/>
<c:out value="${data}"/> 会输出百度首页源代码
url标签,param标签:使用可选的查询参数来创造一个URL
<c:url 
  var="<string>"  代表URL的变量名
  scope="<string>" var属性的作用域
  value="<string>" URL值
  context="<string>"/>  本地网络应用程序的名称
  <c:param name="参数名" value="值"> 附加参数?
</c:url>

redirect标签:重定向url,可带参数

<c:redirect url=”url” [context=”context”]/>
<c:redirect url="<string>" [context=”context”]>
    <c:param name="参数名" value="值">
</c:redirect>

其他

相对路径获取
${pageContext.request.contextPath}
页面拆分
<jsp:include page="/common/header.jsp" />
<jsp:include page="/common/menu.jsp" />

SpringMVC

<!-- 配置视图解析器,可以显式设置,也可以不设置,不设置会依据SpringMVC的默认设置 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
</bean>


<!--Servlet -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

Filter

实现对web资源的请求的拦截,完成特殊的操作,尤其是对请求的预处理

  • Web资源权限访问控制
  • 请求字符集编码处理
  • 内容敏感字符词汇过滤
  • 响应信息压缩

生命周期

  • web应用启动时,服务器创建Filter的实例对象,以及对象的初始化操作--init()只运行一次
  • 当请求访问与过滤器相关联的Web资源时,过滤器拦截请求,完成指定功能--doFilter()每次访问都执行
  • Filter对象创建过会驻留内存,在web应用被移除或停止时销毁--destroy()
<!--第一步注册,指定过滤器唯一标识和指定的类-->
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>filter.CharacterEncodingFilter</filter-class>
    <!--配置过滤器初始化参数-->
    <init-param>
        <param-name>charset</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<!--第二步配置映射,指定过滤器过滤哪些请求 *代表全部请求-->
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
    // filter-mapping子元素dispather,符合配置的访问方式才会触发过滤器,可以配置多项
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

dispatcher

  • REQUEST 默认方式(也就是直接访问这个页面)
  • INCLUDE
<jsp:include page="/b.jsp"></jsp:include>
--------------------------------------------
<filter-mapping>
    <filter-name>TestFilter</filter-name>
    <url-pattern>/b.jsp</url-pattern>
    <dispatcher>INCLUDE</dispatcher>
</filter-mapping>
//测试inlude访问
  • FORWARD
<%request.getRequestDispatcher("/b.jsp").forward(request,response);%>
--------------------------------------------
<dispatcher>FORWARD</dispatcher>
//测试forward访问--请求转发时候触发

//重定向是REQUEST方式
<%response.sendRedirect(request.getContextPath()+"/b.jsp");%>
//测试重定向
  • ERROR
<filter-mapping>
    <filter-name>TestFilter</filter-name>
    <url-pattern>/b.jsp</url-pattern>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>
<error-page>
    <error-code>404</error-code>
    <location>/b.jsp</location>
</error-page>
//测试404错误---访问一个不存在的资源
//或者在访问页面<%response.sendError(404); %>

过滤器链

在一个web应用中,多个过滤器组合称为一个过滤器链
调用顺序取决于过滤器在web.xml中的顺序

Listener

Servlet规范定义的一种特殊类;用于监听ServletContext,HttpSession,ServletRequest等域对象的创建,销毁及其属性发生变化的事件;监听器可以在事件发生前后进行一些操作

  • 统计在线人数---监听session对象
  • 页面访问量--监听request对象
  • 应用启动时完成信息初始化工作---缓存
  • 与Spring结合
<!--监听器配置-->
<listener>
    <listener-class>listener.FirstListener</listener-class>
</listener>
------------------------------------
public class FirstListener implements ServletContextListener{
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ContextListener init");
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ContextListener destroy");
    }
}
//ContextListener init 应用启动触发
//ContextListener destroy 应用被移除触发(redeploy)

监听器分类

按监听对象

  • ServletContext对象监听器--上下文

  • HttpSession对象监听器------会话

  • ServletRequest对象监听器--请求

  • 按事件分类
    域对象自身的创建和销毁事件监听器

  • ServletContextListener

    配置参数
    <context-param>
            <param-name>app_name</param-name>
            <param-value>ServletContext监听器</param-value>
     </context-param>
        
    获取配置
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        String appName = servletContextEvent.getServletContext().getInitParameter("app_name");
        System.out.println("init--------"+appName);
    }
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        String appName = servletContextEvent.getServletContext().getInitParameter("app_name");
        System.out.println("destroyed--------"+appName);
    }
    
  • HttpSessionListener

    为了看到效果配置session有效期在web.xml
    <!--配置session过期时间 1分钟-->
    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>
    --------------------------------------    
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        System.out.println("session init");
        //获取sessionId
        String sessionId=httpSessionEvent.getSession().getId();
        //获取session创建时间
        Date createTime=new Date(httpSessionEvent.getSession().getCreationTime());
        System.out.println("Id="+sessionId+"  time:"+createTime);
    }
    
    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        System.out.println("session destroy");
        String sessionId=httpSessionEvent.getSession().getId();
        System.out.println("Id="+sessionId);
    }
    
  • ServletRequestListener

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
        System.out.println("Request init");
        HttpServletRequest hres = (HttpServletRequest)servletRequestEvent.getServletRequest();
        String path =hres.getRequestURI();
        System.out.println("请求路径"+path);
    }
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
        System.out.println("Request destory");
    }
    --------------访问首页----------
    请求路径/FirstListener/index.jsp
    Request destory
    

域对象中属性的创建,替换,消除事件监听器

  • ServletContextAttributeListener(session/Request同理)

    @Override
    public void attributeAdded(ServletContextAttributeEvent scae) {
        System.out.println("属性添加name:"+scae.getName()+" value"+scae.getValue());
    }
    @Override
    public void attributeRemoved(ServletContextAttributeEvent scae) {
        System.out.println("属性删除name:"+scae.getName()+" value"+scae.getValue());
    }
    @Override
    public void attributeReplaced(ServletContextAttributeEvent scae) {
        System.out.println("属性修改name:"+scae.getName()+" value"+scae.getValue());
    }
    --------------------------------
    <% application.setAttribute("goodName","相机");%>//1.jsp
    <% application.setAttribute("goodName","手机");%>//2.jsp
    <%  application.removeAttribute("goodName");%>//3.jsp
    -------------------------------
    依次访问--说明传入参数是表示更改前的值
    属性添加name:goodName value相机
    属性修改name:goodName value相机
    属性删除name:goodName value手机
    
  • 绑定到session中某个对象的状态事件监听器--不需要在web.xml中注册

    • HttpSessionBindingListener
public class FiveListener implements HttpSessionBindingListener {
    //当监听器对象绑定至Http会话调用
    @Override
    public void valueBound(HttpSessionBindingEvent hsbe) {
        System.out.println("绑定属性"+hsbe.getName());
    }
   //当监听器对象从http会话内修改,移除或会话销毁时调用
    @Override
    public void valueUnbound(HttpSessionBindingEvent hsbe) {
        System.out.println("解除绑定"+hsbe.getName());
    }
}
-------------------------
<% session.setAttribute("user", new FiveListener());%>//1.jsp
<%session.removeAttribute("user");%>//2.jsp
//依次访问
绑定属性user
解除绑定user
posted @ 2022-05-11 11:20  Ranger-dev  阅读(10)  评论(0编辑  收藏  举报