【jsp】基础知识总结

【jsp】基础知识总结

1._JSP

1.1._什么是JSP

JSP(Java Server Pages)是JavaWeb服务器端的动态资源。它与HTML页面的作用是相同的,显示数据和获取数据。

1.2._jsp组成

JSP=HTML+Java脚本+JSP动作标签(包含EL表达式)

1.3._jsp脚本

本质上就是Java代码片段

分类:

<%...%>:Java语句<%=…%>:Java表达式out.print(...);<%!...%>:Java定义类成员

内置对象(无需创建就可以使用的对象):

out对象在JSP页面中无需创建就可以使用,它的作用是用来向客户端输出;<%=…%>与out.print()功能是相同的,它们都是向客户端输出

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

jsptest

JSP演示

<%

// Java语句

String s1 = "hello jsp";

// 不会输出到客户端,而是在服务器端的控制台打印

System.out.println(s1);

%>

输出变量:<%=s1 %>

输出int类型常量:<%=100 %>

输出String类型常量:<%="你好" %>

使用HTML直接输出常量100

在一个JSP中多个<%…%>可以一起使用

1.4._JSP原理

JSP是特殊的Servlet(查看编译后的JSP源码)类,当JSP页面首次被访问时,容器(Tomcat)会先把JSP编译成Servlet,然后再去执行Servlet。所以JSP其实就是一个Servlet。

JSP生成的Servlet存放在tomcat的work目录下,它是JSP的“真身”。我们打开看看其中的内容,了解一下JSP的“真身”。即下面目录下的work

打开此目录,你会发现,在JSP中的静态信息(例如等)在“真身”中都是使用out.write()完成打印!这些静态信息都是作为字符串输出给了客户端。

1.5._JSP注释

<%-- ... --%>, 在JSP编译成.java时会被忽略的,即JSP注释。 可以在JSP页面中使用html注释:,但这个注释在JSP编译成的.java中是存在的,它不会被忽略,而且会被发送到客户端浏览器。

2._jsp指令

JSP指令用来设置与整个JSP页面相关的属性。

语法格式:指令格式:<%@指令名 attr1="" attr2="" %>。

一般都会把JSP指令放到JSP文件的最上方,但这不是必须的。

常用指令:

page:定义页面的依赖属性,比如脚本语言、error页面、缓存需求等等;include:包含其他文件;taglib:引入标签库的定义,可以是自定义标签。

2.1._page指令

page指令是最为常

用的指定,也是属性最多的属性,page指令没有必须属性,都是可选属性,例如<%@page %>,没有给出任何属性也是可以的。

关于pageEncoding和contentType:

pageEncoding

指定当前JSP页面的编码这个编码是给服务器看的,服务器需要知道当前JSP使用的编码,不然服务器无法正确把JSP编译成java文件这个编码只需要与真实的页面编码一致即可 contentType

设置响应字符流的编码设置content-type响应头 无论是page指令的pageEncoding还是contentType,它们的默认值都是ISO-8859-1,ISO-8859-1是无法显示中文的,所以JSP页面中存在中文的话,一定要设置这两个属性两者关系

当pageEncoding和contentType只出现一个时,那么另一个的值与出现的值相同。如果两个都不出现,那么两个属性的值都是ISO-8859-1。

import属性:对应java代码中的import语句,用来导入包。

2.2._include指令

include指令表示静态包含,即目的是把多个JSP合并成一个JSP文件。include指令只有一个属性:file,指定要包含的页面a.jsp页面中使用include指令包含了b.jsp,那么在编译a.jsp时,会把两个文件合并成一个文件再编译成.java。

2.3._taglib指令

学习jstl标签使用,后面再讲

3._JSP九大内置对象

3.1._简要说明

JSP内置对象:在JSP中无需创建就可以使用的9个对象。

九大内置对象如下:

out(JspWriter):等同与response.getWriter(),用来向客户端发送文本数据config(ServletConfig):对应”真身”中的ServletConfigpage(当前JSP的真身类型):当前JSP页面的“this”,即当前对象pageContext(PageContext):页面上下文对象,它是最后一个没讲的域对象exception(Throwable):只有在错误页面中可以使用这个对象request(HttpServletRequest):即HttpServletRequest类的对象(注意)response(HttpServletResponse):即HttpServletResponse类的对象(注意)application(ServletContext):即ServletContext类的对象(注意)session(HttpSession):即HttpSession类的对象,不是每个JSP页面中都可以使用,如果在某个JSP页面中设置<%@page session=”false”%>,说明这个页面不能使用session

使用情况

极少使用:config、page、exception不是每个JSP页面都可以使用:exception、session

3.2._pageContext

主要功能:

域对象功能代理其它域对象功能获取其他内置对象

3.2.1._域对象功能

表示当前页面 和其他域对象一样,他们都有共同的方法:

void setAttribute(String name, Object value)Object getAttribute(String name)void removeAttribute(String name)

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

测试Page域对象

<%

//在page域中存放数据

pageContext.setAttribute("name", "zhangsan");

%>

<%

//从page域中获取数据

System.out.println(pageContext.getAttribute("name"));

%>

3.2.2._代理其他域对象

可以使用pageContext向request、session、application对象中存取数据,“一个顶四个”

void setAttribute(String name, Object value, int scope):在指定范围中添加数据

Object getAttribute(String name, int scope):获取指定范围的数据

void removeAttribute(String name, int scope):移除指定范围的数据

pageContext.setAttribute("x", "X");

pageContext.setAttribute("x", "XX", PageContext.REQUEST_SCOPE);

pageContext.setAttribute("x", "XXX", PageContext.SESSION_SCOPE);

pageContext.setAttribute("x", "XXXX", PageContext.APPLICATION_SCOPE);

Object findAttribute(String name):依次在page、request、session、application范围查找名称为name的数据,如果找到就停止查找。这说明在这个范围内有相同名称的数据,那么page范围的优先级最高

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

pageEncoding="UTF-8"%>

Insert title here

<%

pageContext.setAttribute("key", "page_value");

request.setAttribute("key", "request_value");

session.setAttribute("key", "session_value");

application.setAttribute("key", "app_value");

%>

<%

//全域查找

String value = (String)pageContext.findAttribute("key");

out.print(value);

%>

3.2.3._获取其他内置对象

一个pageContext对象等于所有内置对象,即1个当9个。这是因为可以使用pageContext对象获取其它8个内置对象。

JspWriter getOut():获取out内置对象

ServletConfig getServletConfig():获取config内置对象

Object getPage():获取page内置对象

ServletRequest getRequest():获取request内置对象

ServletResponse getResponse():获取response内置对象

HttpSession getSession():获取session内置对象

ServletContext getServletContext():获取application内置对象

Exception getException():获取exception内置对象

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

Title

<%

//获取application对象

System.out.println(pageContext.getServletContext().getContextPath());

%>

4._JSP动作标签(了解)

动作标签的作用是用来简化Java脚本的,JSP动作标签是JavaWeb内置的动作标签,它们是已经定义好的动作标签,我们可以拿来直接使用。

4.1._include标签

语法:

作用:包含其它JSP页面

与include指令区别:

include指令是在编译级别完成的包含,即把当前JSP和被包含的JSP合并成一个JSP,然后再编译成一个Servlet;include动作标签是在运行级别完成的包含,即当前JSP和被包含的JSP都会各自生成Servlet,然后在执行当前JSP的Servlet时完成包含另一个JSP的Servlet。它与RequestDispatcher的include()方法是相同的。

被包含的JSP:a.jsp

在此界面导入其他页面

forward标签的作用是请求转发!forward标签的作用与RequestDispatcher.forward()方法相同

5._EL表达式

EL:Expression Language,表达式语言。在JSP页面中可以直接使用,从JSP2.0开始,代替JSP脚本,非Java开发人员也可以使用。

用于替换作用域对象.getAttribute("name"), 并将从域中获取的数据进行显示;EL用来代替<%=...%>,<%=...%>代表输出。

5.1._EL表达式应用(获取基本类型、字符串)

${scope.name}获取具体某个作用域中的数据;

${name}获取作用域中的数据,逐级查找(pageContext、request、session、application)

EL和JSP脚本的区别

<%=request.getAttribute() %> 没有找到返回null${requestScope.name}没找到返回""

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

el初步

<%

//在request域总存放数据 String

pageContext.setAttribute("name", "Bob");

request.setAttribute("name", "Zhangsan");

request.setAttribute("age", 10);

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

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

%>

<%-- 使用EL表达式获取某个域中的数据并在网页上显示

作用域 xxxScope

--%>

${requestScope.name}

${requestScope.age}


<%--

全域查找

如果没有限定xxxScope,会按照pageContext,request,session,application的顺序进行查找

--%>

${name}


<%--

JSP脚本和EL表达式的区别

--%>

<%=request.getAttribute("abc")%>

${requestScope.abc}


5.2._EL表达式应用(获取引用类型)

使用EL获取作用域中的对象调用属性时,只能访问对象的get方法,必须遵守命名规范定义

创建实体类

/**

* 表示Person的实体类

*/

public class Person {

private Integer id;

private String name;

private Integer age;

//set,get

//toString

}

EL表达式演示

<%@ page import="com.qf.entity.Person" %>

<%@ page import="java.util.List" %>

<%@ page import="java.util.ArrayList" %>

<%@ page import="java.util.Map" %>

<%@ page import="java.util.HashMap" %>

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

el表达式处理复杂类型

<%

Person p = new Person();

p.setId(100);

p.setName("Tom");

p.setAge(20);

Person p1 = new Person();

p1.setId(200);

p1.setName("zs");

p1.setAge(21);

//将Person对象存放在域当中

request.setAttribute("person", p);

int[] arr = {1, 2, 100, 50};

request.setAttribute("arr", arr);

List names = new ArrayList<>();

names.add("zs");

names.add("ls");

names.add("ww");

request.setAttribute("names", names);

List persons = new ArrayList<>();

persons.add(p);

persons.add(p1);

request.setAttribute("persons", persons);

Map map = new HashMap<>();

map.put("name", "zs");

map.put("addr", "qd");

request.setAttribute("map", map);

%>

<%--

通过EL表达式在页面上显示对象中的属性

前提:属性要有对应的set和get方法

--%>

${requestScope.person.id}

${requestScope.person.name}

${requestScope.person.age}


<%--

int[]

1 2 100 1000

List

"111" "222" "333"

List

Map

--%>

<%--

通过EL表达式在页面上显示数组中的元素

--%>

${requestScope.arr[3]}


<%--

通过EL表达式在页面上显示集合中的元素,集合中存放的是简单类型(基本数据类型 + String)

--%>

${names[2]}


<%--

通过EL表达式在页面上显示集合(List, Map)中的元素,集合中存放的是复杂类型(除了String类型之外的引用数据类型)

--%>

${persons[0].id}

${persons[0].name}

${persons[0].age}


${map.name}

${map.addr}

${map["addr"]}


5.3._EL表达式运算符

操作符描述.访问一个Bean属性或者一个映射条目[]访问一个数组或者集合的元素+加-减或负*乘/ or div除% or mod取模== or eq测试是否相等!= or ne测试是否不等< or lt测试是否小于> or gt测试是否大于<= or le测试是否小于等于>= or ge测试是否大于等于&& or and测试逻辑与|| or or测试逻辑或! or not测试取反empty测试是否空值

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

el_运算符

<%

request.setAttribute("num", 15);

request.setAttribute("name", "");

%>

<%-- el运算符 --%>

${num + 1}

${num - 1}

${num * 10}

${num / 10}

${num div 10}

${num % 3}

${num mod 3}


${num == 15}

${num eq 15}

<%-- eq equals --%>

${num != 15}

${num ne 15}

<%-- ne not equals --%>

${num lt 20}

<%-- lt less than --%>

${num gt 20}

<%-- gt great than --%>


${true or false}


${empty name}

关于empty关键字

<%

String s1="";

pageContext.setAttribute("s1", s1);

String s2=null;

pageContext.setAttribute("s2", s2);

String s3="abcdefg";

pageContext.setAttribute("s3", s3);

List list1 = new ArrayList();

pageContext.setAttribute("list1", list1);

%>

${empty s1}

${empty s2}

${empty s3}

${empty list1}

5.4._EL的隐式对象

EL 表达式语言定义了11个隐式对象

隐含对象描述pageScopepage作用域requestScoperequest作用域sessionScopesession作用域applicationScopeapplication作用域paramrequest对象的参数,字符串paramValuesrequest对象的参数,字符串集合headerHTTP信息头,字符串headerValuesHTTP信息头,字符串集合initParam上下文初始化参数cookieCookie值pageContext当前页面的pageContext域对象

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

Title

<%--

访问服务器某个位置的时候

协议://主机名:端口 http://localhost:8080

项目名:在实际开发中不能写死 - “动”

资源的位置

--%>

<%--登录--%>

登录

6._JSTL

6.1._目前存在的问题

EL主要是用于作用域获取数据,虽然可以做运算判断,但是得到的都是一个结果,做展示;

EL不存在流程控制。比如判断;

EL对于集合只能做单点访问,不能实现遍历操作。比如循环。

6.2._什么是JSTL

JSTL(Java server pages standarded tag library,即JSP标准标签库)是由JCP(Java community Proces)所制定的标准规范,它主要提供给Java Web开发人员一个标准通用的标签库,并由Apache的Jakarta小组来维护。开发人员可以利用这些标签取代JSP页面上的Java代码,从而提高程序的可读性,降低程序的维护难度。

JSTL是apache对EL表达式的扩展(也就是说JSTL依赖EL),JSTL是标签语言;

不是JSP的内置标签,使用时需要导包

6.3._JSTL的作用

可对EL获取到的数据进行逻辑操作;

与EL合作完成数据的展示。

6.4._如何使用JSTL

导入Jar包,standard.jar 和 jstl.jar;在JSP页面引入标签库<% @taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c">

6.5._JSTL核心标签

6.5.1._输入输出

out标签

value:可以是字符串常量,也可以是EL表达式default:当要输出的内容为null时,会输出default指定的值

set标签

remove标签

案例

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

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

jstl输入输出

<%--

JSTL

增强EL表达式的功能,实现复杂的逻辑操作

--%>

<%-- 输出 --%>

hello world


<%-- 定义变量

int age = 10;

在域对象中存放数据,默认在page域中存放

scope:指定数据存放在哪个域中

--%>

${pageScope.name}

${age}

6.5.2._分支结构

if标签

hello

choose标签

优秀

良好

及格

不及格

6.5.3._循环结构

forEach标签

${i}

${str }

7._MVC设计模式

7.1._经典的MVC

MVC是软件工程中的一种架构模式,是一种软件设计思想,将数据操作、页面展示、业务逻辑分为三个层级(模块),独立完成,相互调用 ,MVC并不是Java独有的,现在几乎所有的B/S的架构都采用了MVC模式,三个层级如下:

视图View:视图即是用户看到并与之交互的界面,比如HTML(静态资源),JSP(动态资源)等等;控制器Controller:控制器即是控制请求的处理逻辑,对请求进行处理,负责流程跳转(转发和重定向);模型Model:对客观世界的一种代表和模拟(业务模拟、对象模拟)。

优点:

低耦合性:模块与模块之间的关联性不强,不与某一种具体实现产生密不可分的关联性;高维护性:基于低耦合性,可做到不同层级的功能模块灵活更换、插拔;高重用性:相同的数据库操作,可以服务于不同的业务处理。将数据作为独立模块,提高重用性。

7.2._JavaWeb经典三层框架

WEB层:包含JSP和Servlet等与WEB相关的内容

业务层:业务层中不包含JavaWeb API,它只关心业务逻辑

数据层:封装了对数据库的访问细节,进行最细粒度的增删改查的操作

调用关系:web层调用—业务层(Service)—数据层(Dao)—DB

业务处理从前到后开发时要从后向前进行

关于业务:

转账对DAO层方法的组合

注意:

业务层(Service)不要出现Java Web API,业务层代码是可重用的,甚至可以应用到非Web环境中;业务层不要出现JDBC相关的API;JavaBean作为实体类贯穿web层、业务层、数据层,各层之间通过JavaBean或者JavaBean的组合进行数据交互。

7.3._基于JavaWeb三层架构升级登录案例

准备工作:

建库建表新建项目拷贝Jar包到项目的WEB-INF发lib目录下准备jdbc配置文件,放置在src下JdbcUtils工具类放在utils包下。

7.3.1._建库建表

SQL语句如下

CREATE DATABASE webtest;

USE webtest;

DROP TABLE IF EXISTS user;

CREATE TABLE user (

id int(11) NOT NULL AUTO_INCREMENT,

username varchar(20),

password varchar(20),

PRIMARY KEY (id)

);

INSERT INTO user VALUES (1, 'zhangsan', '123456');

INSERT INTO user VALUES (2, 'lisi', '123456');

对应的实体类User

public class User {

private Integer id;

private String username;

private String password;

//set和get

//toString

}

7.3.2._Dao层

Dao层接口

import com.qfedu.entity.User;

import java.sql.SQLException;

public interface UserDao {

User findByUsernameAndPassword(String username, String password) throws SQLException;

}

Dao层接口实现类

import com.qfedu.dao.UserDao;

import com.qfedu.entity.User;

import com.qfedu.utils.JdbcUtils;

import org.apache.commons.dbutils.QueryRunner;

import org.apache.commons.dbutils.handlers.BeanHandler;

import java.sql.SQLException;

public class UserDaoImpl implements UserDao {

@Override

public User findByUsernameAndPassword(String username, String password) throws SQLException {

String sql = "select * from user where username=? and password=?";

Object[] params = {username, password};

QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());

User user = qr.query(sql, new BeanHandler(User.class), params);

return user;

}

}

7.3.3._Service层

Service层接口

import com.qfedu.entity.User;

public interface UserService {

User login(String username, String password);

}

Service层实现类对象

import com.qfedu.dao.UserDao;

import com.qfedu.dao.impl.UserDaoImpl;

import com.qfedu.entity.User;

import com.qfedu.service.UserService;

import java.sql.SQLException;

public class UserServiceImpl implements UserService {

private UserDao userDao = new UserDaoImpl();

@Override

public User login(String username, String password) {

User user = null;

try {

user = userDao.findByUsernameAndPassword(username, password);

} catch (SQLException throwables) {

throwables.printStackTrace();

}

return user;

}

}

7.3.4._servlet

用于登录验证的Servlet

import com.qfedu.entity.User;

import com.qfedu.service.UserService;

import com.qfedu.service.impl.UserServiceImpl;

import javax.servlet.*;

import javax.servlet.http.*;

import javax.servlet.annotation.*;

import java.io.IOException;

@WebServlet(name = "LoginServlet", value = "/LoginServlet")

public class LoginServlet extends HttpServlet {

private UserService userService = new UserServiceImpl();

@Override

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

//获取登录信息

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

String password = request.getParameter("password");

String code = request.getParameter("code");

HttpSession session = request.getSession();

//使用用户输入的验证码和生成的验证码进行比较

String generateCode = (String)session.getAttribute("generateCode");

//忽略大小写比较强

if(generateCode.equalsIgnoreCase(code)) {

//登录验证

User user = userService.login(username, password);

if(user != null) {

//将成功登录的用户信息放在Session中

session.setAttribute("username", "admin");

request.getRequestDispatcher("/success.jsp").forward(request, response);

} else {

request.setAttribute("errorMsg", "用户名或密码错误,请重新登录");

request.getRequestDispatcher("/login.jsp").forward(request, response);

}

} else {

request.setAttribute("errorMsg", "验证码错误,请重新登录...");

request.getRequestDispatcher("/login.jsp").forward(request, response);

}

}

@Override

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

doGet(request, response);

}

}

用于生成验证码的Servlet

import cn.dsna.util.images.ValidateCode;

import javax.servlet.*;

import javax.servlet.http.*;

import javax.servlet.annotation.*;

import java.io.IOException;

@WebServlet(name = "CodeServlet", value = "/CodeServlet")

public class CodeServlet extends HttpServlet {

@Override

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

//生成验证码

ValidateCode codeImg = new ValidateCode(200, 30, 4, 5);

String code = codeImg.getCode();

System.out.println(code);

//将生成的验证码存放在session中

request.getSession().setAttribute("generateCode", code);

//发送给浏览器

codeImg.write(response.getOutputStream());

}

@Override

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

doGet(request, response);

}

}

用于退出登录的Servlet

import javax.servlet.*;

import javax.servlet.http.*;

import javax.servlet.annotation.*;

import java.io.IOException;

@WebServlet(name = "LogoutServlet", value = "/LogoutServlet")

public class LogoutServlet extends HttpServlet {

@Override

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

//让session失效

request.getSession().invalidate();

//重定向到login.jsp

response.sendRedirect(request.getContextPath() + "/login.jsp");

}

@Override

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

doGet(request, response);

}

}

7.3.5._相关页面

登录页面login.jsp

注意这个页面中引入jquery用于实现单击刷新验证码,如果加载jquery不能运行成功,删除out目录重试。

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

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

登录

${errorMsg}

用户登录

验证码

成功页面success.jsp

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

success

欢迎${username}

注销

您还没有登录,请先登录

相关文章

鼠疫的类型,及其临床症状有哪些
bet5365亚洲版

鼠疫的类型,及其临床症状有哪些

🕒 07-27 👁️ 2795
斗鱼接连收到嗨氏和张大仙的法律禁令,背后指向的是什么?
苹果手表如何测血压
bet5365亚洲版

苹果手表如何测血压

🕒 10-30 👁️ 2860