9大默认对象

JSP容器根据servlet API而提供了某些隐含对象。可以使用标准的变量来访问这些对象,可以在JSP页面直接使用这九大对象

page this 封装页面对象,是Object类型的,该对象代表了正在运行的由JSP文件产生的类对象,相当于this。一般情况下不建议使用该对象

是Object类型的,所以可以合法调用的方法都是Object中定义的方法

toString equals hashcode wait notify notifyAll

在jsp页面种声明了一个方法pp

<%!
public void pp(){}
%>
//页面种进行调用
<% page.pp(); %>  语法错误,因为page是Object类型的,所以按照Object进行检查
<% this.pp(); %>  语法正确

request ServletRequest,封装请求对象,代表的是来自客户端的请求HttpServletRequest。包括从GET/POST请求传递过来的参数

封装的数据有3部分: header parameter attribute


getHeader(“Accept”):String getIntHeader getDateHeader


getParameter(“name”):String getParameterValues(“hobby”):String[]


setAttribute(“name”,Object) getAttribute(“name”) removeAttribute(“name”)


上传数据

1、表单<form method="post" enctype="multipart/form-data">

2、在Servlet中则可以通过getInputStream或者getReader获取输入流以处理客户端启动的文件

3、引入jspSmartupload组件简化上传处理开发


getRequestDisapatcher(“bbb.jsp”).forward(request,response)

  • 地址栏不变
  • 共享request

response ServletResponse,封装响应对象,代表的是对客户端的响应HttpServletResponse。网页传回客户端的信息

设置响应头

setHeader(“name”,“value”) setIntHeader setDateHeader

  • 避免客户端缓存
  • 以附件方式打开

setContentType(“text/html;charset=utf-8”)

MIME多用途互联网邮件扩展—用来识别文件内容类型 text/html image/jpeg


getWriter() getOutputStream()


response.sendRedirect(“bb.do”); 重定向

  • 地址栏自动变化
  • 不共享request

application ServletContext,封装应用程序对象,负责提供应用程序在服务器中运行时的一些全局信息,是一个容器级的共享对象数据

session HttpSession 封装会话对象,代表服务器与客户端所建立的会话,在不同的JSP页面中保留客户信息的情况下用于跟踪用户状态

config ServletConfig 封装代码配置对象,该对象提供一些该Servlet的配置信息,是javax.servlet.ServletConfig接口的实现

getInitParameter(“name”):String


web.xml

<servlet>
    <servlet-name>index1</servlet-name>
    <jsp-file>/index.jsp</jsp-file>
    <init-param>
        <param-name>name</param-name>
        <param-value>yanjun</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>index1</servlet-name>
    <url-pattern>/bbb.do</url-pattern>
</servlet-mapping>

exception 异常信息的对象,封装异常对象,代表了JSP文件运行时所产生的并且没有被捕获的例外对象,此对象不能在一般JSP文件中直接使用,而只能在使用了<%@ page isErrorPage="true "%>的JSP文件中使用

在页面种使用exception默认对象的要求当前页面必须配置<%@ page isErrorPage="true "%>


<%=exception%>

<%=exception.getMessage()%>

<% exception.printStackTrace(new PrintWriter(out)); %>

out 等价于response.getWriter() 封装输出对象,用来向客户端自定义输出内容,代表了向客户端发送数据的对象,是javax.servlet.jsp.JspWriter接口的实现。JspWriter是带缓冲的版本

out.println("…")/print("…")/newLine()------out.println("<br/>");

pageContext 包装页面上下文对象,代表的是当前页面运行的一些属性,例如可以获取session、request、response、exception、ServletContext和ServletConfig的引用。是javax.servlet.jsp.PageContext接口的实现

application对象

application对象实现了用户间数据的共享,可存放全局变量。它开始于服务器的启动,直到服务器的关闭,在此期间,此对象将一直存在;这样在用户的前后连接或不同用户之间的连接中,可以对此对象的同一属性进行操作;在任何地方对此对象属性的操作,都将影响到其他用户对此的访问。服务器的启动和关闭决定了application对象的生命。它是ServletContext类的实例

获取application对象的引用

getServletConfig().getContext()
    
request.getSession().getServletContext()

一般注意引用application 变量进行修改操作时,必须使用同步。并且,需要测试一个application属性是否已经存在

  • 因为一个应用对应一个application对象,是访问当前应用的所有用户共享
  • 一个服务器中可以部署多个应用

常规方法:

1、作为容器在多用户之间共享数据的方法

setAttribute(“name”,Object) getAttribute removeAttribute

2、获取指定文件或者文件夹的绝对路径

String str=application.getRealPath("");  //获取当前当前应用所在根目录的路径

String str=application.getRealPath("/upload/");  //获取当前当前应用所在根目录下的upload文件夹的绝对路径
  • 查找文件夹一定会有返回值,和文件夹是否存在没有关联
<%@ page import="java.io.File" %>
<%
String str=application.getRealPath("/upload/");
File ff=new File(str);
if(!ff.exists())
    ff.mkdirs();
%>

3、获取上下文的初始化参数

web.xml

 <context-param>
        <param-name>counter</param-name>
        <param-value>123</param-value>
</context-param>

获取方法

Object obj=application.getInitParameter("counter");
out.println(obj);

4、用于读取应用路径下的文件

InputStream is=application.getResourceAsStream("bb.properties");  //该文件位于webapp根目录下
Properties ps=new Properties();
ps.load(is);
String val=ps.getProperty("abc");
out.println(val);

最终练习:计数器的实现1 – 功能不完善

servlet负责准备需要显示的数据

public class WelcomeServlet extends HttpServlet {
    @Override
    public void init() throws ServletException {
        //读取xml配置的初始化参数值
        //这是这个Servlet的独有配置信息,就是<servlet>标签的子标签
        String s1=this.getServletConfig().getInitParameter("counter");
        long l1= IntUtils.converterLong(s1);
        //这个是当前应用范围内所有Servlet都可以读取的全局配置参数
        String s2=this.getServletContext().getInitParameter("counter");
        long l2=IntUtils.converterLong(s2);
        l2=Math.max(l1,l2);
        //读取properties文件中的计数值
        long l3=0;
        InputStream is=this.getServletContext().getResourceAsStream("counter.data");
        if(is!=null){
            DataInputStream dis=new DataInputStream(is);
            try {
                l3=dis.readLong();
                l2=Math.max(l2,l3);
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                try {
                    dis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //比较两次的计数值,将较大的值存储在application中
        this.getServletContext().setAttribute("counter",l2);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("welcome.jsp").forward(request,response);
    }
}

jsp页面显示数据

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <%!  //声明代码段中不能直接使用9大默认对象,定义方法需要传递参数
         String add(ServletContext application) {
                 Long l1 = 0L;
             synchronized (application) {
                 Object ll = application.getAttribute("counter");
                 if (ll != null && ll instanceof Long)
                     l1 = (Long) ll;
                 l1++;
                 application.setAttribute("counter", l1);
             }
             StringBuilder sb=new StringBuilder();
             String ss=l1+"";
             for(int i=0;i<ss.length();i++){
                sb.append("<img src='images/"+ss.charAt(i)+".png'>");
             }
             return sb.toString();
         }
    %>
</head>
<body>
<%=this.add(application)%>
</body>
</html>

session

session对象指的是客户端与服务器的一次会话,从客户端连到服务器的一个Web Application开始,直到客户端与服务器断开连接为止。它是HttpSession类的实例,一个浏览器窗口对应一个session

1、实现在当前应用中跨页面数据传输

session.setAttribute(“name”,Object) getAttribute(“name”):Object removeAttribute(“name”)

2、session数据存储在服务器端,所以需要有一个标识值用于区分不同用户。这个值存储在客户端的内存Cookie中session.getId():String

3、清空session,例如退出登录

session.invalidate() 清空session对象里的东西,并不指清除这个session对象本身

用户登录成功后需要有一种标志表示当前用户已经登录

  • session.setAttribute(“user”,user);

退出登录

  • session.invalidate();

4、针对非正常退出应用,针对session有个超时设置

web.xml

<session-config>
    <session-timeout>30</session-timeout>   这里的单位为分钟,Tomcat即使不作配置,默认就是30分钟
</session-config>

一般如果安全性要求高,则时长设置短一些;如果要求对客户友好,则时长设置长一些

session.getCreateTime()

5、if(!session.isNew()) name=(String)session.getAttribute(“username”);

需求:猜测数字

定义Servlet的doGet方法用于生成一个猜数目标值

  • 采用request传递数据,则为了跟踪记录目标值,则需要使用隐藏域—安全性低
  • 采用session实现多页面之间的数据共享
  • 采用application数据共享是不合理的,因为application适用于跨用户数据共享,但是这里实际上是不同用户猜自己的目标值

实际上传递数据有4种领域<jsp:useBean id="now" class="java.util.Date" scope="page/request/session/application"/>

  • page只在当前页面范围内有效
  • request在请求转发时可以在多个页面之间共享数据
  • session针对单一用户的跨页面数据共享
  • application在当前应用范围内跨用户数据共享

选择依据:范围越小越好,因为范围小时会自动垃圾回收,以避免手工管理,同时解决内存空间

 @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Random r=new Random();
        int target=r.nextInt(900)+100;
       HttpSession session=request.getSession();
//考试点  request.getSession(boolean)和request.getSession()之间的区别:
/* getSession()等价于getSession(true)表示获取和当前用户相关的session对象,如果有则重用;如果没有则新建
    getSession(false)表示有则重用,如果没有不会新建,返回null
    一般从应用编程方面来说,使用getSession()方法
*/
        session.setAttribute("target",target);
        request.getRequestDispatcher("input.jsp").forward(request,response);
}

jsp显示表单,要求用户录入数据

<form action="guess.do" method="post">
    <input name="num"/>
    <input type="submit" value="验证"/>
</form>

Servlet接收数据

  • 接收数据 request.getParameter
  • 数据校验
  • 调用javaBean完成业务逻辑处理
  • 根据业务方法的执行结果跳转对应的页面
 @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String ss = request.getParameter("num");
        Map<String, String> map = new HashMap<>();
        Integer num = null;
        try {
            num = Integer.parseInt(ss);
        } catch (Exception e) {
            map.put("num", "输入数据不合法!");
        }
        if (map.size() > 0) {
            request.setAttribute("error", map);
            request.getRequestDispatcher("input.jsp").forward(request, response);
            return;
        }
        //业务逻辑处理
        HttpSession session = request.getSession();
        Integer target = null;
        Object obj = session.getAttribute("target");
        if (obj != null && obj instanceof Integer) {
            target = (Integer) obj;
            List<Integer> list = new ArrayList<>();
            if (target == num) {
                request.setAttribute("msg", "猜对了!");
            } else {

                Object obj2=session.getAttribute("history");
                if(obj2!=null && obj2 instanceof List)
                    list=(List<Integer>)obj2;
                list.add(num);
                session.setAttribute("history",list);

                if (target > num)
                    request.setAttribute("msg", "猜小了!");
                else if (target < num)
                    request.setAttribute("msg", "猜大了!");
            }


            request.getRequestDispatcher("input.jsp").forward(request, response);
        } else {
            response.sendRedirect("guess.do");
        }
    }

修改输入页面完成报错信息显示

<%@ page import="java.util.Map" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
    <title>Title</title>
    <script>
        function ff() {
            let num1 = document.getElementById("num1").value;
            let re = /^\d{1,18}$/;
            let bb = re.test(num1);
            if (!bb) {
                alert("请输入合法的整型值");
            }
            return bb;
        }
    </script>
    <%!
        private String getError(HttpServletRequest request,String key) {
            String msg = "";
            Object obj=request.getAttribute("error");
            if(obj!=null && obj instanceof Map){
                Map<String,String> map=(Map<String,String>)obj;
                if(map.containsKey(key))
                    msg=map.get(key);
            }
            return msg;
        }
    %>
</head>
<body>
<%=session.getAttribute("target")%>
<div>
    <%
        Object obj=session.getAttribute("history");
        if(obj!=null && obj instanceof List){
            List<Integer> list=(List<Integer>)obj;
            for(Integer temp:list)
                out.println(temp);
        }
    %>
</div>
<div id="div1"><%=request.getAttribute("msg")!=null?request.getAttribute("msg"):""%></div>
<form action="guess.do" method="post" οnsubmit="return ff();">
    <input name="num" id="num1"/><span id="span1"><%=this.getError(request,"num")%></span><br/>
    <input type="submit" value="验证"/>
</form>
</body>
</html>

比较笨的方式

@Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Random r=new Random();
        int target=r.nextInt(900)+100;
        request.setAttribute("target",target);
        request.getRequestDispatcher("input.jsp").forward(request,response);
    }

input.jsp显示一个表单,要求用户输入数据

<form action="guess.do" method="post">
    <input type="hidden" name="target" value="<%=request.getAttribute("target")%>"/>
    <input name="num"/><input type="submit" value="验证"/>
</form>

典型案例:购物车

pageContext

代表当前JSP页面的运行环境的对象;pageContext对象提供了对JSP页面内所有的对象及名字空间的访问,也就是说他可以访问到本页所在的SESSION,也可以取本页面所在的application的某一属性值,他相当于页面中所有功能的集大成者,它的本类名也叫pageContext

可以通过他获取其他八大隐式对象,例如:pageContext.getPage() ;

<%
JspWriter out1=pageContext.getOut();
ServletRequest request1=pageContext.getRequest();
ServletResponse response1=pageContext.getResponse();
HttpSession session1=pageContext.getSession();
ServletContext application1=pageContext.getServletContext();

Object page1=pageContext.getPage();
ServletConfig config1=pageContext.getServletConfig();
Exception exception1=pageContext.getException();
%>

pageContext 是一个域对象page,有生命周期:当访问JSP开始时创建pageConext对象,当访问JSP结束时销毁pageContext对象
作用范围:整个JSP页面

主要功能:在整个JSP页面中实现数据的共享

方法:
setAttribute(String name,Object value) ; //添加一个相应的域属性,
例如:request.setAttribute(“names”,names); //向request域中添加一个属性
getAttribute(String name) ;
removeAttribute(String name);//删除该属性

请求转发

pageContext.forward(“abc.jsp”);

  • pageContext.forward(“bbb.jsp?id=123”);
  • request.getRequestDispatcher(“bbb.jsp?id=123”).forward(request, response);

页面跳转

jsp页面跳转

不传递数据   get请求
<a href="bb.do">bb</a>

传递数据   get请求
<a href="bb.do?id=123">bb</a>

<form action="bb.do">  form表单默认提交方式为get
    <input type="submit" value="提交数据" />
</form>
post请求
<form action="bb.do" method="post">
    <input type="submit" value="提交数据" />
</form>

Servlet页面跳转

request.getRequestDispatcher("aa.jsp").forward(request,response);  //请求转发
//客户端不参与; 当前Servlet和目标地址共享request

response.sendRedirect("aa.jsp");//重定向
//客户端参与; 当前Servlet不共享request

跟踪用户的4大方法

隐藏域

<form action="dd.do">
	<input type="hidden" name="id" value="11"/>

URL重写

http://localhost:8080/dd.do?id=11

Cookie

用于实现客户端跟踪用户

在Servlet中,如果Cookie cookie = new Cookie(name,value) 调用Cookie对象的构造函数可以创建Cookie。Cookie对象的构造函数有两个字符串参数:Cookie名字和Cookie值。

名字和值都不能包含空格以及下列字符:[ ] ( ) = , " / ? @ : ;。

Cookie可以分为内存Cookie和文件Cookie。

  • 只是进行了new操作的话,当用户退出Browser时,cookie会被删除掉,而不会被存储在客户端的硬盘上

  • 如果要存储cookie,需加cookie.setMaxAge(200)。Cookie设置的生命周期单位是秒

然后需要使用response.addCooie(cookie)将cookie插入到一个Set-Cookie的HTTP请求报头中

由于浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB,因此Cookie不会塞满硬盘,更不会被用作“拒绝服务”攻击手段。

session的具体实现实际上依赖的就是内存Cookie

<%
Enumeration<String> names=request.getHeaderNames();
while(names.hasMoreElements()){
	String name=names.nextElement();
	String value=request.getHeader(name);
	out.println(name+"--->"+value+"<br/>");
}
%>

<%=session.getId()%>

显示内容中注意:

cookie--->JSESSIONID=B7F7F449BB653EC538E753F37513F785

用户打开页面显示上次访问时间,一年内有效

存储文件cookie

<%
Date now=new Date();
DateFormat df=new SimpleDateFormat("yyyy-MM-dd-hh:mm:ss");

Cookie ck=new Cookie("lasttime",df.format(now));
ck.setMaxAge(10);  //设置最大存活周期,单位为秒
response.addCookie(ck);
%>

读取cookie


<%
Cookie[] cks=request.getCookies();//获取所有的cookie
for(Cookie temp:cks){
	out.println(temp.getName()+"::::"+temp.getValue()+"<br/>");
}
%>

###Session

用于实现服务器端跟踪用户,但是需要客户端的内存Cookie的支持,每次提交时需要传递一个Session的编号,用于区分不同用户

用户提交数据的预处理

  • 客户端验证

    采用js实现

        <script>
            function ff(){
                let num1=document.getElementById("num1").value;
                let re=/^\d{1,18}$/;
                let bb=re.test(num1);
                if(!bb){
                    alert("请输入合法的整型值");
                }
                return bb;
            }
        </script>
    <form action="guess.do" method="post" onsubmit="return ff();">
        <input name="num" id="num1"/>
        <input type="submit" value="验证"/>
    </form>
    

    优点:

    • 是在客户端上执行,不会对服务器造成压力
    • 不需要网络数据传输,效率高

    缺点:

    • 很容易被绕过,所以安全性低
  • 服务器端验证

    采用java实现,运行在服务器端,一般和客户端验证规则一致

    优点:

    • 不能绕过,所以安全性高

    缺点:

    • 是在服务端上执行,会对服务器造成压力
    • 需要网络数据传输,验证效率低
  • 业务验证

    采用Java实现,运行在服务器端,一般执行一些和业务规则相关的验证,以保证数据安全可靠

作业:

  • 抄写demo31–20遍
    • servlet—jsp—servlet—db
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值