牛!阿里面试官嫌面试者技术差,竟彻夜怒肝万字JSP面试通关手册

204 阅读7分钟

Hello,今天给各位童鞋们分享JSP,赶紧拿出小本子记下来吧!

image.png

1. JSP入门

  1. JSP全名为Java Server Pages,java服务器⻚⾯。JSP是⼀种基于⽂本的程序,其特点就是HTML和Java代码共同存在!

  2. JSP本身就是⼀种Servlet,Tomcat访问任何的资源都是在访问Servlet!

JSP就是封装了Servlet的java程序

  • 编译原理:

浏览器第⼀次请求1.jsp时,Tomcat会将1.jsp转化成1_jsp.java这么⼀个类,并

将该⽂件编译成class⽂件。编译完毕后再运⾏class⽂件来响应浏览器的请求。

  • 生命周期:

运⾏时只有⼀个实例,JSP初始化和销毁时也会调⽤Servlet的init()和destroy()⽅法

  • JSP脚本(java代码)

使用 <% %> 括起来

表达式输出(各种类型的变量):<%=%>

  • JSP指令

<%@指令 属性名="值" %>

  • page指令

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

  • 中⽂乱码问题

在page指令中指定contentType="text/html;charset=UTF-8"

  • 跳转到错误页面(404, NullPointerException)
<error-code>404</error-code>

<location>/error.jsp</location>
<exception-type>java.lang.NullPointerException</exception-type>

<location>/error.jsp</location>
  • include指令,静态包含页面

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

把⽂件的代码内容都包含进来,再编译

  • include行为,动态包含

<jsp:include page="head.jsp"/>

先编译被包含的⻚⾯,再将⻚⾯的结果写⼊到包含的⻚⾯中

  • param行为

当使⽤ jsp:include 和 jsp:forward⾏为 引⼊或将请求转发给其它资源时

可以使⽤jsp:param⾏为向这个资源传递参数。

<jsp:include page="head.jsp"> jsp:param</jsp:param> jsp:include

  • forward行为

<jsp:forward page="head.jsp">

<jsp:param name="username" value="lwclick"/>

</jsp:forward>

访问1.jsp⻚⾯就跳转到head.jsp⻚⾯中

<%

String ss = request.getParameter("username");

%>

获取到的参数是:

<%=ss%>

2. 内置对象、属性范围

2.1. 九个内置对象:

  • pageContext

  • pageContext.getSession() ,pageContext.getPage()… 获取其他8个内置对象

  • set/get/removeAttribute(多了一个scope),多了一个find

page —> request --> session --> application

page

  • page是HttpJasPage对象

  • page对象相当于普通java类的this

config

  • config其实就是ServletConfig

request

  • request其实就是HttpServletRequest

  • set/get/removeAttribute

response

  • response其实就是HttpServletResponse

session

  • session其实就是HttpSession

  • page指令配置如下信息,session将不可使⽤ <%@page session=“false” %>

  • set/get/removeAttribute

application

  • application其实就是ServletContext对象

  • set/get/removeAttribute

exception

  • exception是java.lang.Exception类的对象

out

  • out对象⽤于向浏览器输出数据,与之对应的是Servlet的PrintWriter对象。(out带缓存)

  • 在JSP⻚⾯输出都是⽤表达式(<%=%>)

2.2. 四种属性范围(set/get/removeAttribute)

  • page【只在⼀个⻚⾯中保存属性,跳转⻚⾯⽆效】

  • requet【只在⼀次请求中保存属性,服务器跳转有效,浏览器跳转⽆效】

⽤户看完就没⽤了

  • session【在⼀个会话范围中保存属性,⽆论何种跳转均有效,关闭浏览器后⽆效】

⽤户⽤完了等⼀会⼉还有⽤

  • application【在整个服务器中保存,所有⽤户都可以使⽤】

⽤户⽤完了,还要给其它⽤户⽤

3. JavaBean

  1. 实体类
  2. ⼀张表使⽤一个bean类

规则:

  • 有无参的构造函数

  • 成员属性私有化

  • 封装的属性如果需要被外所操作,必须编写public类型的setter、getter⽅法

jsp:useBean

在指定的域范围内查找指定名称的JavaBean对象

存在则直接返回该JavaBean对象的引⽤

不存在则实例化⼀个新的JavaBean对象并将它以指定的名称存储到指定的域范围中

<jsp:useBean id="实例化对象的名称" class="类的全名" scope="保存范围"/>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<jsp:useBean id="person" class="domain.Person" scope="page"/>

<%

person.setName("lwclick");

System.out.println(person.getName());

%>

jsp:setProperty

获取表单的信息,然后导入到javaBean对象 设置属性的值

<jsp:setProperty name=“对象名称” property="*"/> ⾃动匹配

<jsp:setProperty name=“对象名称” property=“属性名称”/> 指定属性

⽤户名:<input type="text" name="username">

年龄:<input type="text " name="age">

<input type="submit" value="提交">

<jsp:useBean id="person" class="domain.Person" scope="page"/>

<%--指定属性名称为age--%>

<jsp:setProperty name="person" property="age"/>

<%

System.out.println(person.getAge());

%>

JavaBean属性名要和表单的name的名称⼀致

jsp:getProperty

输出内容

<jsp:getProperty name="对象名" property="属性名"/>

<%--使⽤jsp:getProperty输出--%>

<jsp:getProperty name="person" property="username"/>

<jsp:getProperty name="person" property="age"/>

4. EL表达式

  • EL表达式是用 “${}” 括起来的脚本,主要用来读取数据,进行内容的显示!

  • 如果找不到相应的对象属性,返回的是空白字符串“”,而不是null

demo1.jsp

<%

//向session设置⼀个属性

session.setAttribute("name", "aaa");

System.out.println("向session设置了⼀个属性");

%>

demo2.jsp

${name}

  • 获取域对象的数据

application.setAttribute("name", "aaa");

${name}

  • 获取JavaBean的属性

<jsp:useBean id="person" class="domain.Person" scope="session"/>

<jsp:setProperty name="person" property="age" value="22"/>

${person.age}

  • 获取集合的数据–list

<%

List<Person> list = new ArrayList();



Person person1 = new Person();

person1.setUsername("lwclick");



Person person2 = new Person();

person2.setUsername("hello");



list.add(person1);

list.add(person2);



session.setAttribute("list",list);

%>

${list[0].username}

  • 获取集合的数据–map

<%

   Map<String, Person> map = new HashMap<>();



   Person person1 = new Person();

   person1.setUsername("lwclick");



   Person person2 = new Person();

   person2.setUsername("hello");



   map.put("aa",person1);

   map.put(1,person2);



   session.setAttribute("map",map);

%>

${map.aa.username}

${map["1"].username}

  • 简单运算

<%

List<Person> list = null;

%>

${list==null?"list集合为空":"list集合不为空"}

  • 如果获取到的数据为null,输出空⽩字符串""!这个特点可以让我们进行数据回显操作

<%

User user = new User();

user.setGender("male");

//数据回显

request.setAttribute("user",user);

%>

<input type="radio" name="gender" value="male"

${user.gender=='male'?'checked':'' }>男

<input type="radio" name="gender" value="female"

${user.gender=='female'?'checked':'' }>⼥

fn⽅法库全都是跟字符串有关的

5. JSTL

JSP Standard Tag Library 即JSP标准标签库。

集合的遍历、数据的输出、字符串的处理、数据的格式化

5.1 core标签库

流程控制、迭代输出,前缀⼀般是c

c:out

value属性:指定要输出的内容

escapeXml:将特殊字符进行HTML编码后再输出,默认true

default:如果value的值为null时输出的默认值

<%

session.setAttribute("name", "zhongfucheng");

%>

<c:out value="${name}" default="您要的数据找不着" escapeXml="true"/>

c:set

value:指定属性值

var:指定要设置的web域属性的名称(Integer、Double、String等类型的数据)

scope:指定属性所在的web域

target:执行要设置属性的对象(JavaBean或Map对象的数据)

property:当前要为对象设置的属性名称

c:remove

删除域范围

<%--创建出JavaBean对象,设置为session范围的属性--%>

<jsp:useBean id="person" class="domain.Person" scope="session"/>

<%--获取到person对象,设置age属性的值为32--%>

<c:set target="${person}" property="age" value="32"/>

${person.age}

<%--删除session属性--%>

<c:remove var="person" scope="session"></c:remove>

${person.age==null?"存在session的person对象被删除了!":"我还在呢!"}

c:catch

处理程序中产⽣的异常

<%--创建出JavaBean对象,设置为session范围的属性--%>

<jsp:useBean id="person" class="domain.Person" scope="session"/>

<c:catch var="message">

<%--target属性只能是EL表达式,现在是字符串,获取不到对象,肯定会抛出异常的--%>

<c:set target="person" property="age" value="32"/>

</c:catch>

${message}

c:if

test:决定是否处理标签体中的内容的条件表达式

var:用于指定test属性的执行结果保存到某个web域中的某个属性的名称

scope:指定将test属性的执行结果保存到哪个web域中

<%--如果带过来的名字是lwclick,那么可以登陆--%>

<c:if test="${param.name=='lwclick'}">

⽤户名:<input type="text" name="username"><br>

密码:<input type="password" name="password"><br>

<input type="submit" value="登陆">

</c:if>

<%--如果带过来的名字是ouzicheng,那么就是注册--%>

<c:if test="${param.name=='ouzicheng'}">

⽤户名:<input type="text" name="username"><br>

密码:<input type="password" name="password"><br>

<input type="submit" value="注册">

</c:if>

c:choose(相当于 if-else)

if else流程就需要使⽤choose标签,choose标签需要联合when和otherwise标签⼀起使⽤

<c:choose>

<c:when test="${param.name=='lwclick'}">

	你好啊,lwclick

</c:when>



<c:when test="${param.name=='ouzicheng'}">

	你好啊,ouzicheng

</c:when>



<c:otherwise>

	你是谁啊?别随便过来!

</c:otherwise>

</c:choose>

c:forEach

var:指定将当前迭代到的 元素 保存到page这个web域中的属性名称

items:将要迭代的集合对象

begin:如果指定items属性,就从集合的第begin个元素开始迭代(从0开始编号)

​ 如果没有指定,就从begin指定的值开始迭代,直到end值结束

end

step:迭代的步长

varStatus:当前被遍历对象的信息

index【返回当前是第⼏个对象,从0开始计数】

count【已经遍历多少个对象了,从1开始计数】

current【当前被迭代的对象】

<c:forEach var="list" items="${list}" varStatus="varStatus" >

${list}您的下标是:${varStatus.index}<br>

</c:forEach>

image.png

image.png c:forTokens

类似于String类的split() 和 for循环的⼀种集合,items属性⾥⾯是字符串,这个字符串会被delims属性的内容分割成多个字符串

<c:forTokens items="lwclick,lw,lr,xiaoming" var="name" delims="," >

${name}

</c:forTokens>

c:import

类似于JSP⾏为jsp:include/ 和JSP指令<%include>

url【指定要包含的路径,Internet所有的url都可以】

context【访问同⼀个web容器的其他资源,以"/"开头】

var【保存导⼊的⽂件的内容,以String类型存储】

socpe【保存的范围,默认是page】

charEncoding【字符编码】

varReader【保存导⼊⽂件的内容,以Reader类型存储】

<c:out value="${net}" escapeXml="true"></c:out>

c:param

c:param标签可以嵌套在c:import、c:url或c:redirect标签内,为这些标签所使⽤的URL地址附加参数。

c:url

value:指定要构造的URL

var:指定将要构造的URL结果保存到web域中的属性名称

scope:指定将构造出的URL结果保存到哪个web域中

<c:url value="2.jsp" var="url">

<c:param name="name" value="中国!">

</c:param>

</c:url>

我经过了URL地址重写!

c:redirect

用于实现Redirect功能,当然了,此标签也能够配合param标签使⽤!

重定向到2.jsp,带了⼀个参数:

<c:redirect url="2.jsp" >

<c:param name="name" value="zhongfucheng">

</c:param>

</c:redirect>

5.2 自定义标签

某些复杂类型转换,或者逻辑处理的时候,JSTL标签库完成不了,需要⾃定义标签!

  1. 编写⼀个实现Tag接⼝的Java类【标签处理器类】

  2. 在WEB-INF⽬录下创建tld(Tag Library Descriptor)⽂件,在tld⽂件中对标签处理类(实现Tag接⼝的Java类)进⾏描述

5.3 简单标签

实现了SimpeTag接⼝的标签

6. 面试题

6.1. jsp静态包含和动态包含的区别

include指令是静态包含。静态包含的意思就是:把⽂件的代码内容都包含进来,再编译!

include⾏为是动态包含。其实include⾏为就是封装了request.getRequestDispatcher(String url).include(request,response),先编译被包含的页面,再将页面的结果写⼊到包含的页面中

6.2. jsp有哪些内置对象?作⽤分别是什么?

  1. request ⽤户端请求,此请求会包含来⾃GET/POST请求的参数
  2. response ⽹⻚传回⽤户端的回应
  3. pageContext ⽹⻚的属性是在这⾥管理,代表的编译后JSP内容
  4. session 与请求有关的会话期
  5. application servlet 正在执⾏的内容
  6. out ⽤来传送回应的输出
  7. config servlet的构架部件
  8. page JSP⽹⻚本身
  9. exception 针对错误⽹⻚,未捕捉的例外

6.3. jsp和servlet的区别、共同点、各⾃应⽤的范围?

JSP是Servlet技术的扩展,本质上就是Servlet的简易⽅式。JSP编译后是“类servlet”。

Servlet和JSP最主要的不同点在于:Servlet的应⽤逻辑是在Java⽂件中,并且完全从表示层中的HTML⾥分离开来。⽽JSP的情况是Java和HTML可以组合成⼀个扩展名为.jsp的⽂件。

JSP侧重于视图,Servlet主要⽤于控制逻辑。

6.4. 属性作用域范围

page【只在⼀个⻚⾯中保存属性,跳转⻚⾯⽆效】

requet【只在⼀次请求中保存属性,服务器跳转有效,浏览器跳转⽆效】

session【在⼀个会话范围中保存属性,⽆论何种跳转均有效,关闭浏览器后⽆效】

application【在整个服务器中保存,所有⽤户都可以使⽤】

6.5. 五种JSTL常⽤标签

<c:if>,<c:item>,<c:foreach>,<c:out>,<c:set>

6.6. JSP是如何被执⾏的?执⾏效率⽐SERVLET低吗?

当客户端向⼀个jsp⻚⾯发送请求时,Web Container将jsp转化成servlet的源代码(只在第⼀次请求时),然后编译转化后的servlet并加载到内存中执⾏,执⾏的结果response到客户端

jsp只在第⼀次执⾏的时候会转化成servlet,以后每次执⾏,web容器都是直接执⾏编译后的servlet,所以jsp和servlet只是在第⼀次执⾏的时候不⼀样,jsp慢⼀点,以后的执⾏都是相同的

6.7. 说出Servlet和CGI的区别?

Servlet处于服务器进程中,只会有⼀个servlet实例,每个请求都会产⽣⼀个新的线程,⽽且servlet实例⼀般不会销毁

CGI:来⼀个请求就创建⼀个进程,⽤完就销毁,效率低于servlet

6.8. 避免jsp页面自动生成session

<%@ page session="false" %>

6.9. jsp的设计模式

模式:指的就是在开发中将显示层、控制层、数据层的操作统⼀交给JSP或者JavaBean来进⾏处理!

⽆效】

session【在⼀个会话范围中保存属性,⽆论何种跳转均有效,关闭浏览器后⽆效】

application【在整个服务器中保存,所有⽤户都可以使⽤】

好啦,今天的文章就到这里,希望能帮助到屏幕前迷茫的你们