JSP
java server page:java服务器页面。与HTML的静态网页相比,JSP具有动态显示页面的功能。
<!-- 第一个JSP页面 -->
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<!-- 其中%=%标签是输出脚本标签 -->
Now:<%=new Date() %>
</body>
</html>
JSP开发
jsp与servlet的关系
- 关系:jsp文件在容器中会转化为Servlet执行;jap是对Servlet的一种封装,本质上还是servlet
- 区别:与servlet相比,jsp可以很方便的编写或者修改html页面而不用去使用大量的println语句
jsp实现原理
Tomcat会将xxx.jsp文件转换为java代码,进而编译成.class文件,最终将运行结果通过response响应给客户端
jsp与HTML集成开发
脚本
脚本可以编写java语句,变量,方法或表达式
1、普通脚本/代码脚本:<% java 代码%>
注意:普通脚本可以使用所有的java语法,除了定义函数
脚本与脚本不可嵌套,脚本与htnl标签不可嵌套
<%
Integer a=10; //局部变量
System.out.println(a); //输出在eclipse的控制台
out.println(a); //输出到客户端语句
%>
2、声明脚本:<%! 定义变量,函数 %>
注意:声明脚本声明的变量是全局变量
声明脚本的内容必须在普通脚本<% %>中调用
如果声明脚本中的函数具有返回值,使用输出脚本调用<%=%>
<%!
int b=20;
//无返回值的方法
public void test(){
System.out.println("test方法");
}
//有返回值的方法
public int test1(){
return 100;
}
%>
<%
out.println(b);
test();
out.println(test1()); //方式1
%>
<%=
test1() //方式2
%>
3、输出脚本:<%= %>
注意:输出脚本可以输出带有返回值的函数
输出脚本不能加分号;结尾
<%=
test1() //方式2
%>
jsp指令
1、page指令:提供当前页面的使用说明。可以有多个
<%@page attribute1="value1" attribut2="value" ...%>
属性 | 描述 |
---|---|
contentType | 指定当前页面的MIME类型和字符编码格式 |
errorPage | 指定当前JSP页面发生异常时需要转向的错误处页面 |
isErrorPage | 指定当前页面是否可以作为一个JSP页面的错误处理页面 |
import | 导入需要使用的java类 |
language | 指定jsp页面所用到的脚本语言,默认是java |
session | 指定jsp页面是否使用session。默认为true, |
pageEncoding | 指定jsp页面的解码格式 |
2、include指令:在jsp文件中包含其他的jsp文件、html文件、或文本文件(静态包含)
如果此时main.jsp和header.jsp/footer.jsp中存在重名的变量,那么就会报错
header.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>header页面</title>
</head>
<body>
<h1>header页面</h1>
</body>
</html>
footer.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>footer页面</title>
</head>
<body>
<h1>footer页面</h1>
</body>
</html>
main.jsp包含以上两个jsp文件
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ include file="header.jsp" %>
<%@ include file="footer.jsp" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>main页面</title>
</head>
<body>
<h1>main页面</h1>
</body>
</html>
动作标签
动作标签指的是JSP页面在运行期间的命令
1、include:<jsp:include page=“相对URL地址” />
<jsp:include >动 作元素会将外部文件输出结果包含在jsp中(动态包含)
main.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<jsp:include page="header.jsp"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>main页面</title>
</head>
<body>
<h1>main页面</h1>
<%
String message="main";
%>
<%= message %>
</body>
</html>
<jsp:include page="footer.jsp"/>
header.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>header页面</title>
</head>
<body>
<h1>header页面</h1>
<%
String message="header";
%>
<%= message %>
</body>
</html>
footer.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>footer页面</title>
</head>
<body>
<h1>footer页面</h1>
<%
String message="footer";
%>
<%= message %>
</body>
</html>
使用了<jsp:include page>标签,使得每一个jsp中都包含了不同的message,但是并不会报错
2、useBean:用来加载一个JavaBean
语法:<jsp:useBean id="name" class="package.className"/>
设置属性:<jsp:setProperty name="" property="" value="">
获取属性:<jsp:getProperty name="" property="">
//新建一个类(注意被useBean标签使用的类必须有良好的封装)
package web.jsp;
public class User {
private String username;
private String password;
//无参构造器
public User(){
}
//有参构造器
public User(String username,String password) {
this.setUsername(username);
this.setPassword(password);
}
//set和get方法
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<!-- id=对象的名字,class=引用的类的名字-->
<jsp:useBean id="user" class="web.jsp.User"/>
<!-- 设置属性 -->
<jsp:setProperty name="user" property="username" value="张三"/>
<jsp:setProperty name="user" property="password" value="123456"/>
<!-- 获取属性 -->
<jsp:getProperty name="user" property="username"/>
<jsp:getProperty name="user" property="password"/>
</body>
</html>
3、forward:请求跳转到另一个页面
<jsp:forward page=“相对URL地址”>
<body>
<jsp:forward page="header.jsp"/>
</body>
4、param:在转发内部使用,做参数传递
<jsp:param name="" value="">
A传递参数
<body>
<jsp:forward page="header.jsp">
<jsp:param name="username" value="李四"/>
</jsp:forward>
</body>
B页面接收参数
<body>
<%
String name=request.getParameter("username");
%>
<%= name %>
</body>
内置对象
对象名 | 类型 | 说明 |
---|---|---|
request | javax.servlet.http.HttpServletRequest | |
response | javax.servlet.http.HttpServletRespones | |
session | javax.servlet.http.HttpSession | 由session="true"开关 |
application | javax.servlet.ServletContext | |
config | javax.servlet.ServletConfig | |
exeception | java.long.Throwable | 由isErrorPage="false"开关 |
out | javax.servlet.jsp.JspWriter | |
pageContext | javax.servlet.jsp.JspContext | |
oage | java.lang.Object当前对象this | 当前Servlet实例 |
四大阈对象
pageContext:当前jsp页面有效
request:一次请求有效
session:一次会话有效
application:整个web应用有效(除非服务器重启或关闭)
pageContext对象的作用
1、获取其他8个内置对象
<%
pageContext.getRequest();
pageContext.getResponse();
pageContext.getSession();
pageContext.getServletContext();
pageContext.getServletConfig();
pageContext.getOut();
pageContext.getException();
pageContext.getPage(); //当前的Servlet对象,即this
%>
2、操作其他作用域
<%
//当前jsp有效
pageContext.setAttribute("name", "张三");
pageContext.getAttribute("name");
//设置request对象有效
pageContext.setAttribute("age",20, PageContext.REQUEST_SCOPE);
Integer age=(Integer) request.getAttribute("age"); //通过resquest对象获取值
Integer age2=(Integer)pageContext.getAttribute("age", PageContext.REQUEST_SCOPE);
//session有效
pageContext.setAttribute("sex",'男', PageContext.SESSION_SCOPE);
Character sex=(Character)session.getAttribute("sex");
Character sex2=(Character)pageContext.getAttribute("sex",PageContext.SESSION_SCOPE);
//application有效
pageContext.setAttribute("height", 1.65, PageContext.APPLICATION_SCOPE);
Double height=(Double)application.getAttribute("height");
Double height2=(Double)pageContext.getAttribute("height",PageContext.APPLICATION_SCOPE);
//或者使用findAttribute方法来获取值,其寻找的作用域依次是;page->request->session->application
Integer age3=(Integer)pageContext.findAttribute("age");
Character sex3=(Character)pageContext.findAttribute("sex");
Double height3=(Double)pageContext.findAttribute("height");
%>
年龄:<%=age %>
性别:<%=sex %>
身高:<%=height %>
EL表达式
Expression Language:EI使JSP写起来更简单、简洁,主要用来获取作用域中的数据(改变getAttribute方式)
1、获取基本类型数据
<body>
<%
request.setAttribute("key1", "value1");
session.setAttribute("key2", "value2");
application.setAttribute("key3", "value3");
%>
<h2>通过作用域对象获取</h2>
<%=request.getAttribute("key1") %>
<%=session.getAttribute("key2") %>
<%=application.getAttribute("key3") %>
<hr/>
<!-- EI表达式的正规写法 -->
<h2>通过EI表达式获取</h2>
${requestScope.key1}
${sessionScope.key2}
${applicationScope.key3}
<hr/>
<!-- 简单写法 :前提是name都不同-->
${key1}
${key2}
${key3}
</body>
注意:通过作用域对象获取的值如果没有定义就是null,而且通过EI表达式获取的是空字符串“”
2、获取引用类型数据
<body>
<%
User user=new User("李四","123456");
request.setAttribute("user", user);
%>
<%
User u=(User)request.getAttribute("user");
out.println(u.getUsername());
out.println(u.getPassword());
%>
<hr/>
${user.username}
${user.password}
</body>
3、获取数组、集合元素(EI可以直接获取Array、List等集合元素)
<body>
<%
int[] array=new int[]{1,2,3,4,5};
request.setAttribute("array", array);
List<String> nums=new ArrayList<>();
nums.add("aaa");
nums.add("bbb");
nums.add("ccc");
request.setAttribute("list", nums);
Map<String,String> map=new HashMap<>();
map.put("CN","中国");
map.put("CN","美国");
map.put("IT","意大利");
request.setAttribute("map", map);
%>
<!-- EI表达式访问数组 -->
${array[1]}
${array[2]}
${array[0]}
${array[3]}
<br/>
<!-- EI访问集合 -->
${list[0]}
${list[1]}
${list.get(2)}
<br/>
${map["CN"]}
${map["UN"]}
${map.IT}
</body>
JSTL标准标签库
JSTL:JSP标准标签库,可对EI获取到的数据进行逻辑操作;可与EI合作完成数据的展示
使用条件:
- 导入两个jar包:standard.jar jstl.jar(拷贝到WEB-INF/lib文件下)
- 在jsp页面引入标签库<%@ taglib uri=“http://java.sun.com/jsp/jstl/core” prefix=“c”%>
1、if标签
<body>
<%
request.setAttribute("name", "张三"); //存储
%>
${name} //获取值
<c:if test="${name eq '张三'}"> //如果等于张三
<h1>欢迎你,${name}</h1> //输出
</c:if>
<c:if test="${name ne '张三'}"> //如果不等于张三
<h1>用户名错误</h1>
</c:if>
<!-- 多重if -->
<%
request.setAttribute("age", 20);
%>
${age}
<c:choose>
<c:when test=" ${age<18}"><h1>少年</h1></c:when>
<c:when test="${age>=18 && age<30}">青年</c:when>
<c:when test="${age>=30 && age<50}">中年</c:when>
<c:otherwise>老年</c:otherwise>
</c:choose>
</body>
2、foreach标签
<%
List<String> list=new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
request.setAttribute("list", list);
%>
<c:foreach var="s" items="list">
<h1>${s}</h1>
</c:foreach>
<!-- 引用类型 -->
<%
List<User> user=new ArrayList<>();
user.add(new User("张三","123456"));
user.add(new User("张三","123456"));
user.add(new User("张三","123456"));
user.add(new User("张三","123456"));
request.setAttribute("users", "user");
%>
<c:foreach var="user" items="users">
${user.username}:${user.password}</br>
</c:foreach>
3、url标签
所有设涉及到页面调转或重定向调转时,都应该使用url重写
<c:url context='${pageContext.request.contextPath}' value='/xxx'/>
其中context表示当前请求的路径,value表示要跳转到的页面路径
MVC框架
MVC又称为编程模式,是一种软件设计思想,将数据操作、页面展示、业务逻辑分为三个模块,独立完成,相互调用。
三层
1.视图(View):视图即是用户看到并与之交互的界面,比如Html(静态资源),jsp(动态资源)等等
2.控制器(Controller):控制器就是控制请求的处理逻辑,对请求进行处理,负责流程的调转(转发和重新定向)
3.模型层(Model):对客观世界的一种代表和模拟业务
优点
- 低耦合性:模块和模块之间关联性不强,不与某一种具体实现产生密不可分的关联性
- 高维护性:基于低耦合性,可做到不同层级的功能模块灵活变换、插拔
- 高重用性:相同的数据库操作,可以服务于不同的业务处理,将数据作为独立模块,提高重用性
分页
package web.utils;
/*
* 以后进行分页查询的时候,由于SQL语句需要输入的是起始行statrRows和页大小pageSize
* 这样就可以直接传入一个Page page对象,然后调用page对象的page.getStatrRows()和page.getPageSize()方法来获取这两个数值
* */
public class Page{
private Integer pageIndex;//页码
private Integer pageSize;//页大小 一页显示的数据行数
private Integer totalCounts;//数据总行数 从数据库查询到的
private Integer totalPage;//总页数
//statrRows=(pageIndex-1)*pageSize
private Integer statrRows;//起始行 从哪一行开始显示数据
//两参构造器,用户可以自己指定页大小
public Page(Integer pageIndex,Integer pageSize) {
this.pageIndex=pageIndex;
this.setPageSize(pageSize);
this.setStatrRows((pageIndex-1)*pageSize); //设置起始行
}
//但实际开发中,页大小通常是程序员固定好的
public Page(Integer pageIndex) {
this(pageIndex, 5); //设定页大小是5条
}
//pageIndex
public Integer getPageIndex() {
return pageIndex;
}
public void setPageIndex(Integer pageIndex) {
this.pageIndex = pageIndex;
}
//statrRows
public Integer getStatrRows() {
return statrRows;
}
public void setStatrRows(Integer statrRows) {
this.statrRows = statrRows;
}
//totalCounts
public Integer getTotalCounts() {
return totalCounts;
}
public void setTotalCounts(Integer totalCounts) {
this.totalCounts = totalCounts; //获取了总条数以后,就可以求得总页数
this.setTotalPage(totalCounts % pageSize ==0? totalCounts / pageSize :totalCounts / pageSize +1);
}
//totalPage
public Integer getTotalPage() {
return totalPage;
}
public void setTotalPage(Integer totalPage) {
this.totalPage = totalPage;
}
//pageSize
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
}