jsp学习笔记之零零散散的记录(总)

jsp学习笔记,不定时更新

一.JSP的页面元素:

html、java代码(脚本Scriptlet)、指令、注释

1. 脚本Scriptlet

a. <% java语句;局部变量%>

b. <%! 方法;全局变量%>

c. <%= 输出表达式%>= <%out.print("输出内容");%>(tomcat中默认,Maven会报错但是可运行)

ps:out.println无法换行,要想换行:

ps:一般而言,修改web.xml、配置文件、java ,需要重启服务
但如果修改jsp、html、css、js,不需要重启

2.指令

JSP指令用来设置整个JSP页面相关的属性,如网页的编码方式和脚本语言。
语法格式如:<%@ page attribute="value" %>

JSP中的三种指令标签:
在这里插入图片描述
在这里插入图片描述
例如:<%@ page contentType="text/html;charset=UTF-8" language="java" import="java.util.Date"%>

3.注释

a. html注释<!-- 注释-->,可以被客户在浏览器查看源码看到

b. jsp注释<%–注释–%>

c. java注释//注释/*注释*/

二. jsp内置对象(自带的,不需要new也能用)

jsp共有九个内置对象:request/out/pageContext/response//session/application/config/page/exception

1.out:输出对象,

向客户端输出内容

2.request:请求对象,

储存客户端向服务器发出的请求信息

a.常见方法:

  1. String getParameter(String name):根据请求字段名key,返回字段值value
  2. String[ ] getParameterValues(String name):根据请求字段名key,返回多个字段值value,常见的有:checkbox(多选按钮)
  3. setCharacterEncoding(“编码格式utf-8”),设置请求的编码,默认值看版本
  4. getRequestDispatcher(“b.jsp”).forward(request,response);请求转发的方式跳转页面 A —》B
  5. ServletContext getServerContext();获取项目的ServletContext对象

b.示例:

register.jsp👇

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="show.jsp">
        用户名:<input type="text" name="uname" /><br/>
        密码:<input type="password" name="upwd" /><br/>
        年龄:<input type="text" name="uage" /><br/>
        爱好:<br/>
        <input type="checkbox" name="uhobbies" value="足球"/>足球、
        <input type="checkbox" name="uhobbies" value="篮球"/>篮球、
        <input type="checkbox" name="uhobbies" value="游戏"/>游戏<br/>
        <input type="submit" value="注册">
    </form>
</body>
</html>

show.jsp👇

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>展示</title>
</head>
<body>
<%
    //设置编码
    request.setCharacterEncoding("utf-8");
    String name = request.getParameter("uname");
    int age = Integer.parseInt(request.getParameter("uage"));
    String upwd = request.getParameter("upwd");

    String[] hobbies = request.getParameterValues("uhobbies");
%>
注册成功,信息如下:<br/>
姓名:<%=name %><br/>
年龄:<%=age%><br/>
密码:<%=upwd%><br/>
爱好:
<%
    if (hobbies != null){
   
        for (String hobby : hobbies) {
   
            out.print(hobby + "&nbsp");
        }
    }
%>
</body>
</html>

在这里插入图片描述
在这里插入图片描述
http://localhost:8081/show.jsp?uname=123&upwd=q23&uage=1233&uhobbies=%E8%B6%B3%E7%90%83&uhobbies=%E7%AF%AE%E7%90%83&uhobbies=%E6%B8%B8%E6%88%8F

输入以上地址一样可以访问show.jsp,不需要register.jsp。
method="get"方式 、地址栏 、超链接 请求方式都是GET提交

c.post与get请求方式的区别

GET 在地址栏显示请求信息 POST不显示
文件上传必须是POST

d.统一请求的编码 request

1.get方式请求 如果出现乱码,解决:
i. 统一每一个变量的编码(不推荐)

在这里插入图片描述

ii. 修改server.xml

在这里插入图片描述

2.post方式请求 如果出现乱码,解决:

在这里插入图片描述

3.response:相应对象

a.response的方法:

返回值 方法 用处
void addCookie(Cookie cookie); 服务端向客户端增加一个 cookie
void sendRedirect(“a.jsp”); 重定向(页面跳转的一种方式)
void setContetType(String type); 设置服务端响应的编码
. . .
. . .
. . .

b.示例:

response.sendRedirect(“a.jsp”);重定向,数据丢失,地址栏改变
request.getRequestDispatcher(“a.jsp”);请求转发,数据还在,地址栏没变化

c.请求转发和重定向的区别:

在这里插入图片描述
具体可以看:请求转发和重定向

4.1.Cookie(客户端,不是内置对象):

由服务端产生再发送给客户端保存,相当于本地缓存。
提高访问效率,安全性差

a.生成Cookie :name=value

javax.servlet.http.Cookie
public Cookie ( String name , String value)

String getName()
String getValue()
void setMaxAge(int expiry);最大有效期(秒)

b.发送Cookie

1、服务器准备Cookie:response.addCookie(Cookie cookie)
2、转发Cookie:页面跳转(转发、重定向)
3、客户端获取Cookie:request getCookies();
要点:

a、获取cookie都是获取全部的,不能单独获取
b、服务端增加cookie:response对象 ; 客户端获取cookie:request对象

c.示例

Cookie.jsp👇

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>模拟服务端增加cookie</title>
</head>
<body>
    <%
//        生成cookie
        Cookie cookie1 = new Cookie("name","zs");
        Cookie cookie2 = new Cookie("pwd","abc");
//        添加cookie
        response.addCookie(cookie1);
        response.addCookie(cookie2);
//        从页面跳转到客户端(转发/重定向)
        response.sendRedirect("result.jsp");
    %>
</body>
</html>

result.jsp👇

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>模拟客户端接收cookie</title>
</head>
<body>
        <%
//            客户端接收所有的cookie
            Cookie[] cookies = request.getCookies();
            for (Cookie cookie : cookies) {
   
                out.print(cookie.getName() + "--"+cookie.getValue() + "<br>");
            }
        %>

</body>
</html>

访问http://localhost:8081/Cookie.jsp后重定向自动跳转到result.jsp👇
在这里插入图片描述
在这里插入图片描述
可以看到除了自己设置的两个cookie外还有一个jessionid的cookie为系统自动产生

心态炸裂!这里两个小时的内容因为测试cookie功能,全被删除了!!!都是心血!!心好累啊!再简单再写一点点吧

😭

4.2 session:服务端(内置对象):

一次会话 👇
浏览网站 开始→关闭
电子邮件 浏览→写邮件→发邮件→退出

a.session的机制

客户端第一次请求服务端时,(先匹配JSESSIONID - sessionID)

  1. 服务端会产生一个session对象(用于保存该客户的信息) ;
    并且每个session对象都会有一个唯一的 sessionId( 用于区分其他session) ;
  2. 服务端由会产生一个cookie,并且 该cookie的name= JSESSIONID,value=服务端sessionId的值;
  3. 然后服务端会在响应客户端的同时将该cookie发送给客户端,至此客户端就有了一个cookie (JSESSIONID);
  4. 因此,客户端的cookie就可以和服务端的session一一对应( JSESSIONID - sessionID)

客户端第二次请求服务端时,服务端会先用客户端的cookie中的JSESSIONID去服务端的session中匹配sessionID,如果匹配成功,说明不是第一次访问,就无需登录
在这里插入图片描述

b.session的方法:

返回值 方法 用处
String getId() : 获取sessionId
void invalidate() : 使session失效 (退出登录、注销)
void setAttribute() 后面再写
object getAttribute() 后面再写
void setMaxInactiveInterval(秒) :设置最大有效非活动时间
int getMaxInactiveInterval() :获取最大有效非活动时间

c.示例

login.jsp👇

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登陆页面</title>
</head>
<body>
    <form action="check.jsp">
        用户名:<input type="text" name="uname" /><br/>
        密码:<input type="password" name="upwd"/><br/>
        <input type="submit" value="登陆"><br/>
    </form>
</body>
</html>

check.jsp👇

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登陆后页面</title>
</head>
<body>
<%
    //设置编码
    request.setCharacterEncoding("utf-8");
    String name = request.getParameter("uname");
    String pwd = request.getParameter("upwd");

    if(name.equals("zs")&&pwd.equals("123")) {
   
        //只有登陆成功,session中才有值
        session.setAttribute("uname",name);
        session.setAttribute("upwd",pwd);
        //看下sessionID
        System.out.println("sessionID"+session.getId());
        //创建发送cookie
        Cookie cookie = new Cookie("uname",name);
        response.addCookie(cookie);


        //设置有效非活动时间(秒)
        session.setMaxInactiveInterval(20);
        //登陆成功转到欢迎页面
        request.getRequestDispatcher("welcome.jsp").forward(request,response);
    }else {
   
        //登陆失败,返回登陆页面
        response.sendRedirect("login.jsp");
    }
%>
</body>
</html>

a.jsp👇

<html>
<head>
    <title>其中一个页面</title>
</head>
<body>
    <%
        out.print(session.getAttribute("uname"));
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
   
            if (cookie.getName().equals("JSESSIONID")) {
   
                System.out.println("JSESSIONID"+"--"+cookie.getValue());
            }
        }

    %>

</body>
</html>

invalidate.jsp👇

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注销功能</title>
</head>
<body>
    <%
        //session失效
        session.invalidate();
        response.sendRedirect("login.jsp");
        //session.removeAttribute("uname");
    %>
</body>
</html>

welcome.jsp👇

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>欢迎页面</title>
</head>
<body>
欢迎您:
    <%
        String name = (String) session.getAttribute("uname");
        //如果用户没有通过登陆访问welcome.jsp,则name为null
        //没有登陆跳回登陆页面
        if (name != null) {
   
            out.print(name);

            System.out.println();
    %>
        <a href="invalidate.jsp">注销</a>
    <%
        } else {
   
            response.sendRedirect("login.jsp");
        }
    %>
</body>
</html>

在这里插入图片描述

d. cookie和session的区别 (!)

区别 session cookie
保存的位置 服务端 客户端
安全性 较为安全 较不安全
保存的内容 object String

5. application:(全局对象)

a.方法

返回值 方法 用处
String getContextPath(): 虚拟路径
String getRealPath(String name): 绝对路径(虚拟路径相相对的绝对路径)

虚拟路径、绝对路径👇
在这里插入图片描述

b.示例

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>显示页面</title>
</head>
<body>
<%="当前项目的虚拟路径:" + application.getContextPath() + "<br>"%>
<%="虚拟路径相对应的绝对路径:" + application.getRealPath("/applicationDemo") + "<br>"%>
</body>
</html>

6.1pageContext:

6.2 四种范围对象

a. 对比

四种范围对象 (小->大) 有效范围
pageContext JSP页面容器 当前页面有效
request 请求对象 同一次请求有效
session 会话对象 同一次会话有效
appliation 全局对象 全局有效(整个项目有效)

尽量使用最小范围

  1. pageContext 当前页面有效(页面跳转后无效)
  2. request 同一次请求有效;其他请求无效(请求转发后有效; 重定向后无效)
  3. session 同一次会话有效 (无论怎么跳转,都有效;关闭/切换浏览器后无效;从登陆->退出之间全部有效
  4. application 全局变量;整个项目运行期间都有效(切换浏览器仍然有效);关闭服务、其他项目无效

尽量使用最小范围

b. 共有方法

返回值 方法 用处
Object getAttribute (String name) 根据属性名 获取 属性值
void setAttribute(String name, 0bject obj) 根据属性名 设置 属性值(新增,修改)
void removeAttribute(String name): 根据属性名 删除 对象

7.config:

8.page:

9. exception:

三. JDBC(连接java代码和数据库 )

1. 概念

Java - DataBase - Connectivity
Java — 数据库 ------ 连接对象

可以为多种关系型数据库DBMS 提供统一的访问方式
目的:用java操作数据库
在这里插入图片描述

  1. JDBC API:提供各种操作访问接口,Connection、Statement、PreparedStatement、ResultSet
  2. JDBC DriverManager:管理不同的数据库驱动
  3. 各种数据库驱动(jar包):各种相应的数据库厂商提供(第三方公司提供),作用:连接、直接操作数据库

2. JDBC API

在这里插入图片描述
通过下列 类/接口 实现:
DriverManager :管理JDBC驱动
Connection:连接
Statement ( PreparedStatement ):增删改查
CallableStatement:调用数据库中的 存储过程/存储函数
Result:就是返回的结果集
在这里插入图片描述

a. Connection产生操作数据库的对象

  1. Connection产生Statement对象:createStatement();
  2. Connection产生PreparedStatement对象:prepareStatement();
  3. Connection产生CallableStatement对象:prepareCall();

b. 产生的对象怎么操控数据库的

Statement操作数据库
  1. 增删改:statement.executeAdd();
  2. 查询:statement.executeQuery();
PreparedStatement操作数据库

public interface PreparedStatement extends Statement {
因为继承接口,Statement有的PreparedStatement都有

  1. 增删改:statement.executeAdd();
  2. 查询:statement.executeQuery();

比statement更多的赋值操作

ResultSet保存结果集
select * from xxx 
       👆  *  =  ResultSet
方法 功能
resultSet.next(); 光标下移,判断是否有下一条数据:T/F
resultSet.previous(); 光标上移,判断是否有上一条数据:T/F
resultSet.getxxx(字段名/位置); 获取具体的字段值

c. PreparedStatement 和 Statement使用时的区别

PreparedStatement Statement
sql(可能存在占位符?) sql
在创建PreparedStatement对象时候,将sql语句预编译PreparedStatement(sql) 无预编译
executeUpdate() executeUpdate(sql)
setxxx()替换占位符
防止sql注入 会被sql注入

推荐使用PreparedStatement,有预编译,当需要重复录入数据时,PreparedStatement只需要预编译1次,而Statement需要编译相对多次

什么是sql注入?
例: xxxx为任意值
用户名: xxxx ’ or 1=1 –
密码: xxxx
select count(*) from login where uname = '"+name+" 'and upwd = '"+pwd+"'

结合起来即为:

select count(*) from login where uname = 'xxx ' or 1=1 --' and upwd = '"+pwd+"'

账号部分:因为or 1=1永远为真
密码部分:因为--而被当成注释

d. CallableStatement(调用储存过程、储存函数)

***connection.prepareCall(储存过程 / 储存函数) ***

d.1 调用储存过程、储存函数的区别
存储过程:(无返回值,用out参数代替) 存储函数:(有返回值return)
{ call 存储过程名 (参数列表) } { = call存储函数名 (参数列表) }
d.2 JDBC调用 存储过程 的步骤
  1. 创建CallableStatement对象

在这里插入图片描述

  1. 调用CallableStatement对象
    在这里插入图片描述

  2. 用set方法处理输入参数值(从1开始)
    在这里插入图片描述

  3. 设置输出参数的类型 (无返回值这步省略)
    在这里插入图片描述

  4. cstmt.execute();执行
    在这里插入图片描述

  5. 获取返回值(无返回值这步省略)
    在这里插入图片描述

存储过程示例:

sql语句👇

-- 1 + 1  -> 2
create or replace procedure addTwoNum (num1 in number,num2 in number,result out number)
as
begin
result := num1 + num2;
end;
/

JDBC_CallableStatement.java👇

import java.lang.reflect.Type;
import java.sql.*;
/**
 * @Author: qsX
 * @Time: 2020-04-27 16:22
 * @Description:JDBC访问Oracle具体步骤(CallableStatement)
 */
public class JDBC_CallableStatement {
   
    private static final String URL = "jdbc:oracle:thin:@localhost:1521:ORCL";
    private static final String USERNAME = "scott";
    private static final String PWD = "tiger";

    /**
     * @Description 调用存储过程
     * @Param []
     * @Return void
     */
    public static void invokeProcedure() {
   
        Connection connection = null;
        Statement statement = null;
        CallableStatement cstmt = null;

        try {
   
// a. 导入驱动,加载具体的驱动类
            Class.forName("oracle.jdbc.OracleDriver");//加载具体的驱动类
// b. 与数据库建立连接
            connection = DriverManager.getConnection(URL, USERNAME, PWD);

// c. 发送sql,执行(增删改)
            //存储过程:{ call存储过程名 (参数列表) }
            cstmt = connection.prepareCall("{ call addTwoNum (?,?,?) }");
            cstmt.setInt(1,10);
            cstmt.setInt(2,10);
            //设置输出参数的类型
            cstmt.registerOutParameter(3, Types.INTEGER);
            cstmt.execute();//num1+num2,execute()之前设置输入值、输出参数类型。之后接收输出参数

            //获取返回值
            int result = cstmt.getInt(3);

// d. 处理结果集(查询)(可选操作,没有返回就忽略)
                System.out.println("result=" + result);

        } catch (ClassNotFoundException e) {
   
            e.printStackTrace();
        } catch (SQLException e) {
   
            e.printStackTrace();
        } catch (Exception e) {
   
            e.printStackTrace();
        } finally {
   
            try {
   
                //执行完后关闭
                if (cstmt != null) {
   
                    cstmt.close();
                }
                if (connection != null) {
   
                    connection.close();
                }
            } catch (SQLException e) {
   
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
   
        invokeProcedure();
    }
}

结果👇
在这里插入图片描述

d.3 JDBC调用 存储函数 的步骤
  • 在调用存储过程的基础上,将格式改变
    在这里插入图片描述
  • 参数索引的顺序也要改变
    在这里插入图片描述
存储函数示例:
-- 1 + 1  -> 2
create or replace function addTwoNumfunction (num1 in number,num2 in number)
return number
as
result number;
begin
result := num1 + num2;
return result; 
end;
/

invokeFunction()👇

    /**
     * @Description 调用存储函数
     * @Param []
     * @Return void
     */
    public static void invokeFunction() {
   
        Connection connection = null;
        Statement statement = null;
        CallableStatement cstmt = null;

        try {
   
// a. 导入驱动,加载具体的驱动类
            Class.forName("oracle.jdbc.OracleDriver");//加载具体的驱动类
// b. 与数据库建立连接
            connection = DriverManager.getConnection(URL, USERNAME, PWD);

// c. 发送sql,执行(增删改)
            //存储函数:{ ? = call存储函数名 (参数列表) }
            cstmt = connection.prepareCall("{ ? = call addTwoNumfunction (?,?) }");
            cstmt.setInt(2,10);
            cstmt.setInt(3,10);
            //设置输出参数的类型
            cstmt.registerOutParameter(1, Types.INTEGER);
            cstmt.execute();//num1+num2,execute()之前设置输入值、输出参数类型。之后接收输出参数

            //获取返回值
            int result = cstmt.getInt(1);

// d. 处理结果集(查询)(可选操作,没有返回就忽略)
            System.out.println("result=" + result);

        } catch (ClassNotFoundException e) {
   
            e.printStackTrace();
        } catch (SQLException e) {
   
            e.printStackTrace();
        } catch (Exception e) {
   
            e.printStackTrace();
        } finally {
   
            try {
   
                //执行完后关闭
                if (cstmt != null) {
   
                    cstmt.close();
                }
                if (connection != null) {
   
                    connection.close();
                }
            } catch (SQLException e) {
   
                e.printStackTrace();
            }
        }
    }

3. JDBC访问数据库的具体步骤

a. 导入驱动,加载具体的驱动类

数据库驱动:

数据库 驱动jar 具体驱动类 连接字符串
Oracle ojdbc-x.jar oracle.jdbc.OracleDriver jdbc:oracle:thin:@localhost:1521:ORCL
MySQL mysql-connector-java-x.jar com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/数据库实例名
Sqlsever sqljdbc-x.jar com.microsoft.sqlserver.jdbc.SQLSeverDriver jdbc:microsoft:sqlsever:1443;databasename=数据库实例名
Oracle驱动jar安装到Maven库
  1. Oracle官方宣布的Oracle数据库11g的驱动jar包是ojdbc6.jar
    ojdbc6.jar下载地址:https://www.oracle.com/database/technologies/jdbcdriver-ucp-downloads.html
  2. 进入ojdbc6.jar目录看见MANIFEST.MF文件,打开后查看具体版本号,下步使用
    在这里插入图片描述
  3. 打开cmd窗口,执行maven命令:
mvn install:install-file -Dfile==F:/Java/jar/ojdbc6.jar -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0.4.0 -Dpackaging=jar -DgeneratePom=true 

在这里插入图片描述

  1. pom.xml依赖引入
<dependency>
      <groupId>com.oracle</groupId>
      <artifactId>ojdbc6</artifactId>
      <version>11.2.0.4.0</version>
</dependency>
Mysql驱动jar安装到Maven库
  • pom.xml依赖引入
  <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.45</version>
  </dependency>

b. 与数据库建立连接

  • 通过DriverManager.getConnection(URL, USERNAME, PWD)👇
URL 连接字符串中有:数据库名、IP、端口
USERNAME 用户名
PWD 密码
  • 写完DriverManager..getConnection(URL, USERNAME, PWD);后ALT+ENTER👇
    在这里插入图片描述

c. 发送sql语句,执行

c.1 Statement
  1. 创建statement
    connection.createStatement();👉ALT+ENTER👇
    在这里插入图片描述
  2. 发送sql语句👇
    在这里插入图片描述
  • 查询:statement.executeQuery(sql语句)
  • 增删改:statement.executeUpdate(sql语句)
  1. 返回成功否👇
    在这里插入图片描述
c.2 PreparedStatement
  1. 先导入sql语句,connection.prepareStatement(sql);(可预编译)
    在这里插入图片描述
  2. 对之前预编译的sql语句完善
    在这里插入图片描述
  3. 发送命令,返回结果
    在这里插入图片描述

d. 处理结果集(查询)(可选操作,没有返回就忽略)

这边PreparedStatement与Statement一样

  1. 创建返回结果集resultset
    在这里插入图片描述

  2. 通过循环得到返回的查询结果,rs.next()有值为true
    获取内容也可以直接写1,2,3,但是不推荐使用。
    在这里插入图片描述

  3. 注意:层层抛出异常:
    除了class.forName()抛出ClassNotFoundException
    其他的方法都抛出SQLException
    最后保险起见,再抛出Exception
    在这里插入图片描述

  4. 关流,后开的先关,先开的后关
    注意:如果没开可能会报空指针异常,所以要先排空
    在这里插入图片描述

4.1 示例(JDBC访问Oracle具体步骤)

用Statement方式实现

import java.sql.*;

/**
 * @Author: qsX
 * @Time: 2020-04-25 14:22
 * @Description:JDBC访问Oracle具体步骤
 */
public class JDBCDemo1 {
   
    private static final String URL = "jdbc:oracle:thin:@localhost:1521:ORCL";
    private static final String USERNAME = "scott";
    private static final String PWD = "tiger";

    /**
     * @Description 增删改
     * @Param []
     * @Return void
     */
    public static void update(
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值