Java学习日志Day36_Servlet里面的两个重要的对象_请求转发以及重定向的原理_jsp的基本使用

一、Servlet里面的两个重要的对象

  1. ServletConfig:某个serlvet的配置对象
    获取初始化参数

    1). 获取ServletConfig对象呢?
    GenericServlet:抽象的父类中:
    public ServetConfig getServietConfig(){return this.config}

    2). ServletConfig:获取配置参数
    ServletConfig config = this.getServletConfig();

    3). 获取初始化参数
    String getInitParameter(String var1);//参数名称获取参数值
    String value = config.getInitParameter(“encoding”);
    System.out.println(value);

web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

<!--servlet基本配置-->
    <servlet>
        <servlet-name>ServletConfigDemo</servlet-name>
        <servlet-class>com.qf.servletconfig_01.ServletConfigDemo</servlet-class>
	</servlet>
<!--servlet的映射配置-->
    <servlet-mapping>
        <servlet-name>ServletConfigDemo</servlet-name>
        <url-pattern>/configDemo</url-pattern>
    </servlet-mapping>

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

/* ServletConfig对象 :Servlet的配置对象
 */
public class ServletConfigDemo  extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //ServletConfig:获取配置参数
        ServletConfig config = this.getServletConfig();
        
        //获取初始化参数
        //String getInitParameter(String var1);//参数名称获取参数值
        String value = config.getInitParameter("encoding");
        System.out.println(value);

        System.out.println("------------------------------------");
        
        //public java.util.Enumeration<E> getInitParameterNames():获取servlet的所有初始化参数名称
        Enumeration<String> ens = config.getInitParameterNames();
        while(ens.hasMoreElements()){
            String name = ens.nextElement();
            String v = config.getInitParameter(name);
            System.out.println(name+"---"+v);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

4). html:超文本标记语言
书写html标签:一定存在的标签

xml:可扩展标记语言 (作为配置文件去使用的!)

早期用来代替html语言,没有替代成功!
非常注重结构(必须有开始,有结束)
作为"小型数据库"
用户可以自定义标签

特点:一个xml文件有且只能有一个根标签

  1. ServletContext: (全局对象)
    全局对象:ServletContext
    每一个web应用程序都有自己的上下文: 工程名称
    包含在url地址上
    http://localhost:8080/EE_day36_war_exploded/
    EE_day36_war_exploded:上下文路径
<!--全局参数-->
    <context-param>
        <param-name>AAA</param-name>
        <param-value>AAA'value</param-value>
    </context-param>

<!--一个servlet里面可以配置很多的初始化参数-->
        <!--初始化参数-->
        <init-param>
            <!--参数名称-->
            <param-name>encoding</param-name>
            <!--参数值-->
            <param-value>utf-8</param-value>
        </init-param>

        <init-param>
            <param-name>path</param-name>
            <param-value>d:/a.txt</param-value>
        </init-param>

        <load-on-startup>1</load-on-startup>

作用1:1)加载全局参数

	获取ServletContext对象
       抽象的父类中
      public ServletContext getServletContext() {
        return this.getServletConfig().getServletContext();
     }
   
    ServletContext context = this.getServletContext();
    
    加载全局参数(后期读取配置文件 : springmvc底层基于Servlet (前端控制器:DispatcherServlet))
        String getInitParameter(String var1);:初始化的全局参数
       Enumeration<String> getInitParameterNames();
    String value = context.getInitParameter("AAA");//参数名称获取参数内容
    System.out.println(value);///EE_day36_war_exploded

    Http协议:将获取上下文路径的方法,封装在请求对象中
    
     xx.jsp
       <a href="${域对象获取上下路径}/login.jsp">超链接</a>          浏览器行为  (当前jsp页面中 的超链接,图像加载:带上上下文路径)
举例:
	<servlet>
        <servlet-name>ServletContextDemo</servlet-name>
        <servlet-class>com.qf.servletcontext_02.ServletContextDemo</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletContextDemo</servlet-name>
        <url-pattern>/contextDemo</url-pattern>
    </servlet-mapping>

public class ServletContextDemo extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
            
        String path = request.getContextPath();
        System.out.println(path);///EE_day36_war_exploded
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }
}

作用2:2)可以获取上下路径

<%--
pageContext
    getReuqest()---->Request对象
        request--->称为 pageContext的bean对象(javabean导航)

        HttpServletRequest
            public String getContextPath()    getXXX() ----xXX:就称为bean属性
                    contextPath--->称为HttpServletRequest的bean属性
	--%>
<%-- <a href="${pageContext.request.contextPath}/login.jsp">登录</a>--%>
举例:
	<servlet>
        <servlet-name>ServletContextDemo2</servlet-name>
        <servlet-class>com.qf.servletcontext_02.ServletContextDemo2</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletContextDemo2</servlet-name>
        <url-pattern>/contextDemo2</url-pattern>
    </servlet-mapping>

public class ServletContextDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //1)获取Servletcontext对象
        ServletContext servletContext = this.getServletContext(); //全局对象

        //2)String getContextPath():获取上下文路径
        String path = servletContext.getContextPath();
        System.out.println(path);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}

作用3:3)可以作为"域对象"
传递的数据可以在不同servlet之间通过域对象进行数据共享!

举例:
	<servlet>
        <servlet-name>ServletContextDemo3</servlet-name>
        <servlet-class>com.qf.servletcontext_02.ServletContextDemo3</servlet-class>
    </servlet>
   
    <servlet-mapping>
        <servlet-name>ServletContextDemo3</servlet-name>
        <url-pattern>/demo1</url-pattern>
    </servlet-mapping>

/* 域对象:可以在不同的servlet之间进行数据共享!
 */
public class ServletContextDemo3 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //获取全局对象
        ServletContext servletContext = this.getServletContext();
        //给当前域对象添加属性和内容
        //void setAttribute(String var1, Object var2);
        List<String> list = new ArrayList<String>() ;
        list.add("高圆圆") ;
        list.add("文章") ;
        list.add("马伊琍") ;

        servletContext.setAttribute("list",list);//存储的属性名称 "见名知意"
        System.out.println("保存成功...");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
举例:
	<servlet>
	    <servlet-name>ServletContextDemo4</servlet-name>
	    <servlet-class>com.qf.servletcontext_02.ServletContextDemo4</servlet-class>
	 </servlet>
    <servlet-mapping>
        <servlet-name>ServletContextDemo4</servlet-name>
        <url-pattern>/demo2</url-pattern>
    </servlet-mapping>

public class ServletContextDemo4 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //获取全局对象
        ServletContext servletContext = this.getServletContext();
        // Object getAttribute(String var1);
        List<String> list = (List<String>) servletContext.getAttribute("list");
        for(String str:list){
            System.out.println(str);
        }
        System.out.println("获取成功....");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }
}

作用4:4)有请求转发的作用

							子实现类:
	HttpServletRequest				HttpServletRequestWrapper
    HttpServletResponse				HttpServletResponseWrapper

原理:
    1)获取全局对象
    ServletContext servletContext = this.getServletContext();
    
    2)获取分发对象
    RequestDispatcher getRequestDispatcher(String var1)
    	参数:客户端发送的请求 通过分发对象访问服务器的内部资源文件(servet,jsp,html)
    	服务器行为:通过服务器进行内部转发  		路径: 无需带上下文路径
    RequestDispatcher rd = servletContext.getRequestDispatcher("/WEB-INF/hello.html");
    void forward(ServletRequest var1, ServletResponse var2)		转发到上面的地址上
    rd.forward(request,response);
    
   3).因为request对象本身域对象
    request.setAttribute("XXX","XXX");

    4).简写方式:ServletRequest接口中
    RequestDispatcher getRequestDispatcher(String var1); 获取分发对象
举例:
	<servlet>
        <servlet-name>ServletContextDemo5</servlet-name>
        <servlet-class>com.qf.servletcontext_02.ServletContextDemo5</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletContextDemo5</servlet-name>
        <url-pattern>/demo3</url-pattern>
    </servlet-mapping>

public class ServletContextDemo5 extends HttpServlet {

    protected void doGet(HttpServletRequest request,  HttpServletResponse response)
            throws ServletException, IOException {

        //因为request对象本身域对象
        request.setAttribute("name","高圆圆");

        //简写方式:ServletRequest接口中
        //RequestDispatcher getRequestDispatcher(String var1); 获取分发对象
        request.getRequestDispatcher("/get.jsp").forward(request,response);

        System.out.println("请求转发已完成....");
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }
}
  1. 域对象:从小到大
    pageContext :page域 (在某个jsp页面下有效)
    HttpServletRequest :request域 在一次请求有效
    HttpSession session域: 在一次会话中有效
    ServletContext applcation域 :范围最大的
    域对象

二、请求转发的原理以及重定向原理

  1. 请求转发的原理:
    web容器: 请求对象获取分发对象: RequestDispatcher里面的forward()来完成转发的请求
    请求转发
  <%--  <%
        String str = (String) request.getAttribute("name");
        //System.out.println(str);
        out.write(str);
    %>--%>

优化:${requestScope.name}

扩展:
Request&&Response
2. 重定向的原理—本质:响应头:location + 302(进一步请求)
1). 重定向:后台跳转页面的一种方式
2). 重定向原理(属于浏览器行为:需要带上下文路径)

      设置使用响应头location头
      void setHeader(String var1, String var2);
      response.setHeader("location",request.getContextPath()+"/adv.html");
      
      加上一个响应的状态:302(在一次请求)
      void setStatus(int var1);
      response.setStatus(302); 		//再次发送请求

   	  优化:
      在响应对象:ServletRseonse中
      void sendRedirect(String var1) throws IOExceptio

重定向

举例:
	<servlet>
        <servlet-name>ResponDemo1</servlet-name>
        <servlet-class>com.qf.response_03.ResponDemo1</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ResponDemo1</servlet-name>
        <url-pattern>/resDemo1</url-pattern>
    </servlet-mapping>

public class ResponDemo1 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        System.out.println("开始解析...");

        response.sendRedirect(request.getContextPath()+"/adv.html");
        
        System.out.println("解析完成,准备通过浏览器再一次发送请求");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
  1. 响应头:
    定时刷新头:refresh

    有定时刷新和经过多少秒后进行页面跳转
    
举例:
	<servlet>
        <servlet-name>ResponseDemo2</servlet-name>
        <servlet-class>com.qf.response_03.ResponseDemo2</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ResponseDemo2</servlet-name>
        <url-pattern>/resDemo2</url-pattern>
    </servlet-mapping>

public class ResponseDemo2 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
       // response.setHeader("refresh","3");//每3秒页面刷新

        //经过多少秒后进行页面跳转
        response.getWriter().write("注册成功!3秒后跳转主页");
        response.setHeader("refresh","3;"+request.getContextPath()+"/index.jsp");
        System.out.println("定时刷新");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
            doGet(request,response);
    }
}
  1. 注解的本质就是一个接口:interface
    当前接口中的方法名----在注解中 叫"注解的属性"

    jdk提供很多的内置注解

@Override: 标记某个方法是否是否重写的方法(重写的类还是重写接口的方法)
@Deprecated:标记某个方法是否是过时的
@FunctionalInterface :标记某个接口是否是函数式接口
@SuppressWarnings:压制警告 (项目部署上线的时候:代码不能出现黄色警告线问题)

内置注解中会依赖于元注解

       @Target:标记当前内置注解能够在哪个范围上使用
           public @interface Target {
                    ElementType[] value();        返回值类型:枚举数组
                           ElementType:    枚举规定的范围
                                       TYPE,       类/接口上使用
                                       FIELD,      成员变量上使用
                                       METHD       成员方法上使用
    		 }
       @Retention:规定的注解的保留阶段(三个阶段)
               public @interface Retention {

                           RetentionPolicy value();
                }
                			RetentionPolicy:枚举
                       		SOURCE, 编译阶段
                       		CLASS,  类的加载阶段
                       		RUNTIME 运行阶段   (我们自定义注解的时候:考虑运行阶段)
        @Documented:文档相关的注解

注解中的属性----接口的方法名

定义注解中的属性的类型可以分为哪些?
基本数据类型
String类型
枚举类型
注解类型
以上类型的数组方式

注意事项:
如果当前注解有且仅有一个属性的时候,
并且名称value,那么给value属性是可以省略名称value,直接返类型赋值

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {

    int age() ;  //age属性:返回值类型 基本类型
    String name() ; //name属性:返回值String类型
    MyEnum my() ; //my属性:返回值枚举类型

    String[] strs() ;//strs属性:返回值 数组
}

//抽象的人类
public abstract class Person {

    public abstract  void work() ;
}

@SuppressWarnings("all")
public class Worker extends Person {
    @Override //内置注解
    public void work() {
        System.out.println("工人都需上班...");
    }

    /*@MyAnno()
    public void eat(){

    }*/


    /*@Override   //eat()并非重写方法
    public void eat(){
        System.out.println("工人都需要吃饭");
    }*/
}

//如果某个接口中只有一个抽象方法的时候,标记这个接口为函数式接口
@FunctionalInterface
public interface Love {

     void love() ;
    // void method() ;
}

public enum MyEnum {

    LEFT,  //左
    RIGHT;//右
}

//要使用MyAnno注解
@MyAnno(age=21,name="高圆圆",my=MyEnum.LEFT,strs = {"a","b","c"})
public @interface MyAnnotation2 {

}

使用注解优化:好处将相关的属性信息定义在注解中—通过反射执行

    如何解析自定义注解呢?反射的方式完成
    
    注解作用在哪个类上,获取当前字节码文件对象
     Class clazz = Test.class ;

     解析注解
    Class类中public <A extends Annotation> A getAnnotation(Class<A> annotationClass)
    参数为:当前注解类型的字节码文件对象
    返回值:相当于获取到了MyAnnotation注解(接口)获取子实现类对象
    MyAnnotation myAnnotation = (MyAnnotation) clazz.getAnnotation(MyAnnotation.class);
    String className = myAnnotation.className(); //调用方法(注解中的属性)
    String methodName = myAnnotation.methodName();

    通过Class.forName(className)
    Class myClazz = Class.forName(className);
    System.out.println(myClazz);		//class com.qf.annotation_05.Student
    直接创建该类实例
    Object obj = myClazz.newInstance();
	System.out.println(obj);

    myClazz获取成员方法Method
    Method method = myClazz.getMethod(methodName);
    调用
    method.invoke(obj) ;
举例:
@Target(ElementType.TYPE) //作用在类上
//保留的运行阶段
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    //定义两个 属性
    String className() ;
    String methodName() ;
}

public class Student {
    public void love(){
        System.out.println("love Java...");
    }
}

public class Worker {
    public void love(){
        System.out.println("love Java,love Life...");
    }
}

/* jdk提供的内置注解或者他们依赖的元注解 或者开发者自定义的注解都继承自己公共接口 Annotation
 */
@SuppressWarnings("all")
@MyAnnotation(className = "com.qf.annotation_05.Worker",methodName = "love")
public class Test {

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

        //创建一个学生类
        Student s = new Student() ;
        s.love();

        //工人类
        Worker w = new Worker();
        w.love();
        System.out.println("---------------------------------");

        //使用注解优化:好处将相关的属性信息定义在注解中---通过反射执行
        //如何解析自定义注解呢?反射的方式完成
        //注解作用在哪个类上,获取当前字节码文件对象
         Class clazz = Test.class ;

         //解析注解
        //Class类中public <A extends Annotation> A getAnnotation(Class<A> annotationClass)
        //参数为:当前注解类型的字节码文件对象
        //返回值:相当于获取到了MyAnnotation注解(接口)获取子实现类对象
        MyAnnotation myAnnotation = (MyAnnotation) clazz.getAnnotation(MyAnnotation.class);
        String className = myAnnotation.className(); //调用方法(注解中的属性)
        String methodName = myAnnotation.methodName();

        //通过Class.forName(className)
        Class myClazz = Class.forName(className);
        //System.out.println(myClazz);//class com.qf.annotation_05.Student
        //直接创建该类实例
        Object obj = myClazz.newInstance();
		//System.out.println(obj);

        //myClazz获取成员方法Method
        Method method = myClazz.getMethod(methodName);
        //调用
        method.invoke(obj) ;
    }
}

三、jsp的基本使用

jsp脚本注释 是不会被解析的
而html注释:是会被解析

jsp:Java Server Page :Java服务页面(能够书写java代码的html页面)

jsp应用场景:主要通过servlet获取业务数据,在jsp做数据展示的!

jsp经历两个阶段 ----- 都有web容器来完成
1)翻译阶段
hello.jsp----->翻译成hello_jsp.java文件
2)编译阶段
hello_jsp.java---->通过jvm 进行编译hello_jsp.class

idea默认部署的web工程的所有的jsp文件:
C:\Users\zhangyang.IntelliJIdea2019.1\system\tomcat\Unnamed_EE_day36\work\Catalina\localhost\EE_day36_war_exploded\org\apache\jsp

举例:
<%--jsp的脚本

    --%>
<%
        //创建日期对象
          Date date = new Date() ;
          //后台输出
    System.out.println(date); //日期格式
        //向浏览器打印内容
        out.println(date);
%>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

igfff

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值