图解:
<%-- jsp注释 --%>
jsp的注释能注释静态内容和java代码,且不会显示在源码上,更加安全;
html注释通过查看网页源代码仍可看到;
html注释只能注释静态内容(html、css、js),而里面如0有java代码仍能运行
推荐使用jsp的注释。
<% Java代码片段 %>
格式:<%! 全局成员 %>
特点和作用:在脚本声明中书写的Java代码,会翻译在类的成员位置上,用来声明成员变量或具有返回值的成员方法
注意事项:声明方法的时候,不要声明与jsp翻译的java文件中默认的一些方法或者变量同名的方法或者变量
格式:<%= 输出页面的内容 %>
特点:脚本表达式书写的java代码,会翻译到java文件中的_jspService方法内,被out.print()输出到页面
这里的out对象是一个字符输出流
作用:代替response向页面输出内容
注意事项:
;
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
jsp基本语法
1.脚本片段
<%
//在jsp内可以编写java代码
//使用集合存储列表
List userList = new ArrayList<>();
userList.add("明明");
userList.add("大黄");
userList.add("狗蛋");
userList.add("jojo");
%>
序号
姓名
<%--如果按照原来的做法,在html需要一个个的添加td。而使用jsp可以直接插入Java代码--%>
<%for (int i = 0; i < userList.size(); i++) {%>
<%out.write(i + 1);%>
<%out.write(userList.get(i));%>
<%}%>
2.脚本表达式
<%--脚本表达式可以将out.write()或者out.print()进行简化--%>
序号
姓名
<%for (int i = 0; i < userList.size(); i++) {%>
<%=i + 1%>
<%=userList.get(i)%>
<%}%>
3.脚本声明
<%--在成员位置声明变量或者方法--%>
<%!
/*定义方法*/
public int sum(int i, int j) {
return i + j;
}
%>
<%--调用方法--%>
1+2的和:<%=sum(1, 2)%>
EL(Expression Language):代替jsp中脚本表达式的功能,简化对java代码的操作。
${域里面的key或者表达式}
el对象.域对象name
获取(重要)。如果不指定则按默认处理。域对象 | 对应的el对象 |
---|---|
request | requestScope |
session | sessionScope |
servletContext | applicationScope |
使用el获取域对象数据
<%
//往各个域里面存储数据
request.setAttribute("requestName","requestAdmin");
session.setAttribute("sessionName","sessionAdmin");
request.getServletContext().setAttribute("servletContextName","servletContextAdmin");
%>
<%--使用el表达式获取域里面的数据--%>
从request里面获取数据:${requestName}
从session里面获取数据:${sessionName}
从servletContext里面获取数据:${servletContextName}
<%
//往各个域里面存储数据
request.setAttribute("name","requestAdmin");
session.setAttribute("name","sessio nAdmin");
request.getServletContext().setAttribute("name","servletContextAdmin");
%>
从域里面获取数据:${name}
<%--输出requestAdmin,el获取域里面的数据会依次从request/session/servletContext获取数据,查找到为止--%>
从session域里面name数据:${sessionScope.name}
从servletContext域里面name数据:${applicationScope.name}
从request域里面name数据:${requestScope.name}
获取数组:${数组名}
格式:${数组名[index]}
,其中index为元素的索引
如果元素是一个实体类对象,如果要获取对象的变量,格式为:${数组名[index].变量名}
获取集合:${List集合名}
、${Map集合名}
List集合获取元素与数组相同,${List集合名[index]}
Map集合根据key获取value:${Map集合名[key]}
或者${Map集合名.key}
注意事项:设置map集合数据的key,尽量不要出现”.“,如果出现,只能用[]获取
${JavaBean对象.属性名}
或${JavaBean对象[属性名]}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
el获取复杂数据
1.使用el获得数组的数据
<%
/*添加数据到数组中*/
User[] users = new User[2];
users[0] = new User("狗蛋",18);
users[1] = new User("明明",20);
//记得el必须要将数据添加到域对象中
request.setAttribute("users",users );
%>
获取数组里面第一个元素的name属性值:${users[0].name}
获取数组里面第一个元素的age属性值: ${users[0].age}
获取数组里面第二个元素的name属性值:${users[1].name}
获取数组里面第二个元素的age属性值:${users[1].age}
2.使用el获得list集合的数据
<%
/*添加数据到数组中*/
List list = new ArrayList<>();
list.add(new User("王全",20));
list.add(new User("dio",98));
//记得el必须要将数据添加到域对象中
request.setAttribute("list",list );
%>
获取List里面第一个元素的name属性值:${list[0].name}
获取List里面第一个元素的age属性值: ${list[0].age}
获取List里面第二个元素的name属性值:${list[1].name}
获取List里面第二个元素的age属性值:${list[1].age}
3.使用el获得map集合的数据
<%
/*添加数据到数组中*/
Map map = new HashMap<>();
map.put("zs",new User("张三",20));
map.put("ls",new User("李四",30));
//记得el必须要将数据添加到域对象中
request.setAttribute("map",map );
%>
获取Map里面第一个元素的name属性值:${map.zs.name}
获取Map里面第一个元素的age属性值: ${map.zs.age}
获取Map里面第二个元素的name属性值:${map[lisi].name}
获取Map里面第二个元素的age属性值:${map[lisi].age}
4.使用el获得JavaBean的数据
<%
//往域里面写javaBean
request.setAttribute("user",new User("JoJO",18));
//el获取javaBean数据时,".属性名"就会自动调用属性的get封装方法。
%>
获取user对象里面name属性值:${user.name}
获取user对象里面age属性值:${user.age}
Empty运算符:${empty 域里面的数据}
常用的Empty运算 | 运行结果 |
---|---|
${empty ""} |
如果数据为空字符串,则返回true |
${empty null} |
如果数据为null,返回true |
${empty list} |
如果list元素个数为0,返回true |
${empty str} |
如果字符串为空,返回true |
Empty运算符对应的取反方法
${not empty 域里面的数据}
三目运算符,用法与Java一致:${三目运算符}
javax.servlet.jsp.jstl.jar
jstl-impl.jar
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
其中:taglib是导入标签库,uri选择核心标签库core,prefix用于指定将要使用的标签起前缀名,一般是标签库的第一个字母
if(){}
属性名 | 是否支持el | 属性类型 | 属性描述 |
---|---|---|---|
test | √ | boolean | 编写el条件表达式(表达式结果为true执行,为false不执行) |
var | × | String | 设置保存test属性的结果保存的域对象的名称 |
scope | × | String | 指定保存test属性的结果的域对象。 |
标签用于指定多个条件选择的组合边界,它必须与
和
标签一起使用。三个标签组合发挥java代码if(){}else if(){} else{}
语句的作用
其中:
,相当于else{}。
,相当于if(){}
和else if(){}
。
标签含有test属性,作用与if相同
注意事项:三个标签必须组合使用,一组标签中不能出现两个
属性名 | 是否支持el | 属性类型 | 属性描述 |
---|---|---|---|
var | × | String | 在不循环对象的时候,保存的是控制循环的变量;在循环对象的时候,保存的是被循环对象中的元素 |
items | √ | 任何类型 | 指定要循环的对象 |
varStatus | × | String | 存储循环过程变量信息(循环索引、循环序号) |
begin | √ | int | 循环开始变量值 |
end | √ | int | 循环结束变量值 |
step | √ | int | 循环变量递增值,没有设置默认是1 |
格式:
<%--循环体代码--%>
格式:
<%--循环代码--%>
<%@ page import="model.User" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
if、choose、foreach
1.if标签
if标签示例1
测试if标签,获取test属性的值,从知道的session容器中获取:${sessionScope.flag}
<%
session.setAttribute("user","admin" );
%>
您好,欢迎${user}登录
您还没登录呢
2.choose标签
您好,欢迎${user}登录
您还没登录呢
3.foreach标签
5.1 有限循环次数
<%--循环打印5次--%>
<%="你好,java"%>
5.2 遍历集合
<%
List userList = new ArrayList();
userList.add(new User("王全",20));
userList.add(new User("dio",98));
userList.add(new User("JoJo",18));
//一定要往域里面放域对象
request.setAttribute("userList", userList);
%>
序号
人员姓名
人员年龄
${i.count}
${user.name}
${user.age}
图解
其中javabean就只用于负责封装数据
导入包,包括druid、JdbcTemplate、数据库驱动包、beanutils包。放到web/WEB-INF/lib目录下
准备好druid配置文件
准备好bootstrap资源,放在web目录下
构建架构
创建实体类
public class Contact {
private int id;
private String name;
private String sex;
private int age;
private String address;
private String qq;
private String email;
public Contact() {
}
public Contact(int id, String name, String sex, int age, String address, String qq, String email) {
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
this.address = address;
this.qq = qq;
this.email = email;
}
/*此处省略toString()和getter&setter,实际是有的*/
}
放入JDBCUtils工具类
/*
底层如果出现异常,要手动抛给上一层。通过web层展示出异常的情况,从而找对应的人维护。
下面用数据库最大的异常SQLException
*/
public class ContactDao {
private JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
public List<Contact> getAllContacts() {
String sql = "select * from contact;";
return jdbcTemplate.query(sql,new BeanPropertyRowMapper<Contact>(Contact.class));
}
public int addContactToDao(Contact contact) {
String sql = "insert into contact values(null,?,?,?,?,?,?);";
return jdbcTemplate.update(sql, contact.getName(), contact.getSex(),
contact.getAge(), contact.getAddress(), contact.getQq(), contact.getEmail());
}
public int deleteContactFromDao(String id) {
String sql = "delete from contact where id = ?;";
return jdbcTemplate.update(sql, id);
}
public int updateContactToDao(Contact updateContact) {
System.out.println("dao:" + updateContact);
String sql = "update contact set sex = ?,age = ?,address = ?,qq = ?,email = ? where id = ?;";
return jdbcTemplate.update(sql,updateContact.getSex(),updateContact.getAge(),updateContact.getAddress(),
updateContact.getQq(),updateContact.getEmail(),updateContact.getId());
}
public Contact findById(int id) {
String sql = "select * from contact where id = ?;";
return jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<>(Contact.class),id);
}
}
/*
业务层编写要求:
将异常手动抛到web层,由web层根据不同的异常做出不同的提示
(一方面给用户友好的提示,一方面给后台人员提醒是哪部分出问题,从而安排对应的程序员维护)
下面代码是手动抛最大的异常,实际工程可以细分
此外,deleteContact()、updateContact()可以不用返回值
*/
public class ContactService {
private ContactDao contactDao = new ContactDao();
public List<Contact> getContacts(){
return contactDao.getAllContacts();
}
public boolean addContact(Contact contact) throws Exception{
//如果联系人姓名为空,那么视为添加失败
if (contact.getName() != null) {
int rows = contactDao.addContactToDao(contact);
return rows > 0;
} else {
return false;
}
}
public boolean deleteContact(String id) throws Exception{
//根据id删除联系人
return contactDao.deleteContactFromDao(id) > 0;
}
public boolean updateContact(Contact updateContact) throws Exception{
//调用dao修改联系人
return contactDao.updateContactToDao(updateContact) > 0;
}
public Contact queryById(int id) throws Exception{
return contactDao.findById(id);
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--导入jstl包--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
Bootstrap模板
@WebServlet(urlPatterns = "/ContactServlet")
public class ContactServlet extends HttpServlet {
private ContactService service = new ContactService();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获得数据库的数据
List<Contact> contactList = service.getContacts();
//封装到request域中
request.setAttribute("contactList", contactList);
//请求转发到jsp中
request.getRequestDispatcher("list.jsp").forward(request,response );
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//*如果post方式的执行内容与get不同,则删掉下面代码重写即可
doGet(request, response);
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
添加用户
添加联系人页面
服务器端:
@WebServlet(urlPatterns = "/AddContactServlet")
public class AddContactServlet extends HttpServlet {
private ContactService service = new ContactService();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决响应乱码问题
response.setContentType("text/html;charset=utf-8");
//解决请求乱码问题
request.setCharacterEncoding("utf-8");
try {
Map<String, String[]> ContactMap = request.getParameterMap();
Contact contact = new Contact();
BeanUtils.populate(contact,ContactMap);
//使用service的添加联系人方法
boolean flag = service.addContact(contact);
if (!flag){
response.getWriter().write("alert('您还没有添加联系人姓名!请重新添加');");
} else {
//添加成功请求转发到ContactServlet
//request.getRequestDispatcher("/ContactServlet").forward(request,response);
//也可以用重定向。因为用请求转发的话添加完的路径仍为add,会为用户造成困扰,这里就建议用重定向
response.sendRedirect("/ContactServlet");
}
} catch (Exception e) {
//操作台打印异常给维护人员看
e.printStackTrace();
//给用户友好提示
response.getWriter().write("业务繁忙,请稍后再试");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//*如果post方式的执行内容与get不同,则删掉下面代码重写即可
doGet(request, response);
}
}
@WebServlet(urlPatterns = "/DeleteContactServlet")
public class DeleteContactServlet extends HttpServlet {
/*
思路:删除联系人前必须知道是哪个联系人,可以通过主键找出需要删除的联系人数据,所以在list.jsp中需要将主键传过来。
可以通过在请求参数中添加?id=${contact.id}来传递,这是利用了get提交方式发送请求参数
*/
private ContactService service = new ContactService();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求参数id
String id = request.getParameter("id");
//根据id删除联系人
try {
service.deleteContact(id);
} catch (Exception e) {
//操作台打印异常给维护人员看
e.printStackTrace();
//给用户友好提示
response.getWriter().write("业务繁忙,请稍后再试");
}
//删除完后直接跳转到ContactServlet
response.sendRedirect("/ContactServlet");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//*如果post方式的执行内容与get不同,则删掉下面代码重写即可
doGet(request, response);
}
注意:修改联系人首先得将需要修改的联系人信息全部显示,所以先要实现找到联系人的功能,在实现修改的功能
@WebServlet(urlPatterns = "/QueryByIDServlet")
public class QueryByIDServlet extends HttpServlet {
private ContactService service = new ContactService();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//根据Id获取信息
int id = Integer.parseInt(request.getParameter("id"));
Contact oldContact = null;
try {
oldContact = service.queryById(id);
} catch (Exception e) {
//操作台打印异常给维护人员看
e.printStackTrace();
//给用户友好提示
response.getWriter().write("业务繁忙,请稍后再试");
}
//将对象封装到域中
request.setAttribute("contact",oldContact );
//请求转发到update.jsp
request.getRequestDispatcher("update.jsp").forward(request,response );
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//*如果post方式的执行内容与get不同,则删掉下面代码重写即可
doGet(request, response);
}
}
此时,更新页面就能将需要修改的联系人信息显示出来
注意事项:非常重要的一点。由于联系人id不需要显示出来,而找到找到需要id(否则id永远为0,则永远找不到该联系人),所以需要使用隐藏input标签将id传递
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
String path = request.getContextPath();
String basePath =
request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
修改用户
修改联系人
服务器端
@WebServlet(urlPatterns = "/UpdateContactServlet")
public class UpdateContactServlet extends HttpServlet {
/*
思路:在修改联系人前首先要获得被修改的联系人信息,先将联系人原信息在update.jsp中显示,然后提交到UpdateContactServlet
再往数据库修改数据后返回到ContactServlet。
由于需要在update.jsp显示原信息,可以先根据要修改的联系人id跳转到查询QueryByIDServlet中获取信息,通过与对象将信息传输到update.jsp
*/
private ContactService service = new ContactService();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决请求乱码问题
request.setCharacterEncoding("utf-8");
//将修改数据封装到一个对象中
Map<String, String[]> updateMap = request.getParameterMap();
Contact updateContact = new Contact();
try {
BeanUtils.populate(updateContact,updateMap );
System.out.println(updateContact);
//将封装数据发送给数据库
service.updateContact(updateContact);
//重定向到ContactServlet
response.sendRedirect("/ContactServlet");
} catch (Exception e) {
//操作台打印异常给维护人员看
e.printStackTrace();
//给用户友好提示
response.getWriter().write("业务繁忙,请稍后再试");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//*如果post方式的执行内容与get不同,则删掉下面代码重写即可
doGet(request, response);
}
}