JDBC&Tomcat&Http&Servlet

JDBC

JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库。原来我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句
JDBC是接口,而JDBC驱动才是接口的实现,没有驱动无法完成数据库连接!每个数据库厂商都有自己的驱动,用来连接自己公司的数据库

核心类(接口)

DriverManager(驱动管理器)Connection(连接)Statement(传输器),和ResultSet(返回结果集)

实现JDBC程序步骤

  1. 注册数据库驱动
Class.forName(“com.mysql.jdbc.Driver”); 
  1. 获取数据库连接
Connection con = DriverManager.getConnection(url,username,password);

示例:

Connection conn = DriverManager.getConnection(
    "jdbc:mysql://localhost:3306/jt_db?characterEncoding=utf-8",
    "root", "root" );
  1. 获取传输器
Statement stmt = con.createStatement();
  1. 发送SQL到服务器执行并返回执行结果
String sql =select * from user;
ResultSet rs = stmt.executeQuery(sql);

executeQuery(String sql) – 用于向数据库发送查询类型的sql语句,返回一个ResultSet对象中
executeUpdate(String sql) – 用于向数据库发送更新(增加、删除、修改)类型的sql语句,返回一个int值,表示影响的记录行数

  1. 处理结果
rs.next();//光标移动到第一行
rs.getInt(1);//获取第一行第一列的数据

getInt(int columnIndex)
getInt(String columnLable)
getString(int columnIndex)
getString(String columnLable)
getDouble(int columnIndex)
getDouble(String columnLable)
getObject(int columnIndex)
getObject(String columnLable)

  1. 释放资源(先开后关)
rs.close();
stmt.close();
con.close();
  1. 示例
public static void main(String[] args) throws Exception {
    //1.注册数据库驱动
    Class.forName("com.mysql.jdbc.Driver");
    //2.获取数据库连接
    Connection conn = DriverManager.getConnection(
        "jdbc:mysql://localhost:3306/jt_db?characterEncoding=utf-8",
        "root", "root");
    //3.获取传输器
    Statement stat = conn.createStatement();
    //4.发送SQL到服务器执行并返回执行结果
    String sql = "select * from account";
    ResultSet rs = stat.executeQuery( sql );
    //5.处理结果
    while( rs.next() ) {
        int id = rs.getInt("id");
        String name = rs.getString("name");
        double money = rs.getDouble("money");
        System.out.println(id+" : "+name+" : "+money);
    }
    //6.释放资源
    rs.close();
    stat.close();
    conn.close();
    System.out.println("TestJdbc.main()....");
}

SQL注入攻击

用户在提交参数时,在参数中掺杂了一些SQL关键字(比如or)或者特殊符号(#、-- 、’ 等),就可能会导致SQL语句语义的变化,从而执行一些意外的操作(用户名或密码不正确也能登录成功)

public static void main(String[] args) {
	/* 1、提示用户登录,提示用户输入用户名并接收用户名
	 *  2、提示用户输入密码并接收密码
	 *  3、根据用户名和密码查询用户信息
	 */
	// 1、提示用户登录,提示用户输入用户名并接收用户名
	Scanner sc = new Scanner(System.in);
	System.out.println( "请登录:" );
	System.out.println( "请输入用户名:" );
	String user = sc.nextLine();
	
	// 2、提示用户输入密码并接收密码
	System.out.println( "请输入密码:" );
	String pwd = sc.nextLine();
	
	// 3、根据用户名和密码查询用户信息
	login( user, pwd );
}
/**
 * 根据用户名和密码查询用户信息
 * @param user 用户名
 * @param pwd 密码
 */
private static void login(String user, String pwd) {
	Connection conn = null;
	Statement stat = null;
	ResultSet rs = null;
	try {
		//1.注册驱动并获取连接
		conn = JdbcUtil.getConn();
		//2.获取传输器,执行sql并返回执行结果
		stat = conn.createStatement();
		String sql = "select * from user where username='"+user+"' and password='"+pwd+"'";
		rs = stat.executeQuery(sql);
		System.out.println( sql );
		//3.处理结果
		if( rs.next() ) { //有数据 -- 用户名密码都正确
			System.out.println("恭喜您登录成功!");
		}else { //没数据 -- 用户名或密码不正确
			System.out.println("登录失败, 用户名或密码不正确!");
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		//4.释放资源
		JdbcUtil.close(conn, stat, rs);
	}
}

防止SQL注入攻击

(1)使用正则表达式对用户提交的参数进行校验。如果参数中有(# – ’ or等)这些符号就直接结束程序,通知用户输入的参数不合法

(2)使用PreparedStatement对象来替代Statement对象

/**
 * 根据用户名和密码查询用户信息
 * @param user 用户名
 * @param pwd 密码
 */
private static void login(String user, String pwd) {
	Connection conn = null;
	PreparedStatement ps = null;
	ResultSet rs = null;
	try {
		//1.注册驱动并获取连接
		conn = JdbcUtil.getConn();
		//2.获取传输器,执行sql并返回执行结果
		String sql = "select * from user where username=? and password=?";
		ps = conn.prepareStatement( sql );
		//设置SQL语句中的参数
		ps.setString( 1 , user );
		ps.setString( 2 , pwd );
		//执行SQL语句
		rs = ps.executeQuery();//这里不要再传输SQL语句
		
		//3.处理结果
		if( rs.next() ) { //有数据 -- 用户名密码都正确
			System.out.println("恭喜您登录成功!");
		}else { //没数据 -- 用户名或密码不正确
			System.out.println("登录失败, 用户名或密码不正确!");
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		//4.释放资源
		JdbcUtil.close(conn, ps, rs);
	}
}

原理:使用PreparedStatement对象是先将SQL语句的骨架发送给服务器编译并确定下来,编译之后,SQL语句的骨架和语义就不会再被改变了,再将SQL语句中的参数发送给服务器,即使参数中再包含SQL关键字或者特殊符号,也不会导致SQL语句的骨架或语义被改变,只会被当作普通的文本来处理

tomcat

下载tomcat服务器

tomcat下载地址

tomcat服务器运行需要jdk的支持(tomcat是由java语言开发的),版本对应为
配置JAVA_HOME环境变量,该变量指向jdk的根目录

tomcat5 需要jdk4以上支持
tomcat6 需要jdk5以上支持
tomcat7 需要jdk6以上支持
tomcat8 需要jdk7以上支持

启动关闭tomcat服务器

  • 通过 [tomcat根目录]/bin/startup.bat 可以启动tomcat服务器;
  • 通过 [tomcat根目录]/bin/shutdown.bat 可以关闭tomcat服务器;
  • tomcat服务器在启动时,默认监听的端口是8080
    访问地址:http://localhost:8080

修改tomcat默认端口

  1. [tomcat安装目录]/conf/server.xml
  2. 文件中的 <Connector> 标签上的 port 属性的值改为 80
<Connector port="80" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />
  1. 保存文件,重新启动服务器

HTTP协议

HTTP协议是用于规定浏览器和服务器之间的通信方式/规则
主要规定了浏览器给服务器发送的请求信息的格式
以及规定了服务器给浏览器发送响应信息的格式

原则:
(1)一次请求,只对应一次响应
(2)请求只能由浏览器发起,服务器只能被动的等待请求,根据请求作出回应

HTTP请求

在这里插入图片描述
请求行

  • GET:表示请求方式,在HTTP协议中一共定义了7种提交方式,但是我们只用GET和POST
  • /news/hello.html:请求资源路径,表示浏览器请求的是哪一个Web应用以及哪一个web资源文件
  • HTTP/1.1:请求所遵循的协议和版本
    若干请求头
  • 请求头都是Key-Value结构
    Host:localhost – 通知服务器,浏览器要请求的是哪一台虚拟主机
    Accept:text/html, appliaction/xhtml+xml,… – 通知服务器,浏览器能接收的响应数据类型
    请求实体内容
    如果请求方式为 GET 提交,请求实体是没有内容的!
    如果请求方式为 POST 提交,并且请求中携带了数据,请求实体中才会有内容

HTTP响应

在这里插入图片描述

状态行

  • HTTP/1.1:表示响应所遵循的协议和版本
  • 200:状态码,三位的数字,表示服务器对请求处理的结果
  • 描述短语(可以忽略),也表示服务器对请求处理的结果,和状态码表示的结果一致
    若干响应头
  • key-value格式
    Content-Type: 表示服务器响应的数据类型,text/html, image/*…
    Content-Length: 表示服务器响应数据的长度, 例如: 384 /字节
    响应实体内容
    响应实体就是浏览器所请求文件的内容。例如:浏览器向服务器请求一个hello.html文件,服务器会找到hello.html文件,将文件的内容作为响应实体发送给浏览器

GET提交和POST提交有什么区别

GET提交:

  • 将数据通过问号拼接在地址栏URL地址的后面,相对非常不安全。
  • 将数据拼接在地址栏URL地址的后面,数据量是有限制的,通常不能超过1KB或者4KB。

POST提交:(form)

  • POST提交是通过请求实体将数据提交给服务器,不会显示在地址栏上,因此相对更加安全。
  • POST提交通过请求实体提交数据,数据量理论上是没有限制的。

3、总结:

  • 如果只是单纯做一个跳转,请求中没有数据,尽量使用GET提交。
  • 如果在请求中有数据,但数据量不大,并且数据没有隐私性,也尽量使用GET提交。
  • 如果在请求中有数据,数据量比较大或者数据较为隐私,此时推荐使用POST提交。

Servlet

  • Servlet是由SUN公司提供的一门动态Web资源开发技术
    Servlet本质上是一段Java程序,和之前的Java程序不同的是,Servlet程序无法独立运行,需要将Servlet程序放在服务器中(比如tomcat服务器),由服务器调用才可以执行
    在这里插入图片描述

Servlet在web.xml中的配置

<servlet>
    <servlet-name>HelloServlet</servlet-name>
    <servlet-class>com.tedu.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>HelloServlet</servlet-name>
    <url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>

Servlet调用过程

在这里插入图片描述

request对象

request是代表HTTP请求信息的对象 ,request对象中封装了浏览器发送给服务器的请求信息(请求行、请求头、请求实体等)

请求参数

所谓的请求参数,就是浏览器发送给服务器的数据(不区分请求方式),例如:通过表单向服务器提交的用户名、密码等,或者在超链接后面通过问号提交的数据,都是请求参数

设置和获取请求参数

(1)request.getParameter(String paramName)
– 根据请求参数的名字获取对应的参数值,返回值是一个字符串;
– 如果一个参数有多个值,该方法只会返回第一个值。
– 如果获取的是一个不存在的参数,返回值为null
(2)request.getParameterValues(String paramName)
– 根据请求参数的名字获取该名字对应的所有参数值组成的数组,返回值是一个字符串数组,其中包含了这个参数名对应的所有参数值
– 如果获取的是一个不存在的参数,返回值为null

//1.获取请求参数中的用户名(user)
String user = request.getParameter("user");
System.out.println( "user="+user );

//2.获取请求参数中的爱好(like)
String[] like = request.getParameterValues( "like" );
System.out.println( "like="+Arrays.toString( like ) );

作为域对象使用

request在实现转发时,通过request.setAttribute方法和request.getAttribute方法带数据到目的地时,就是通过request对象中的map集合带数据,这个request对象上的map集合以及request对象所在的范围即称之为是一个域对象

request域对象所具备的三大特征:

**生命周期:**在服务器调用Servlet程序的service方法之前,会创建代表请求的request对象,在请求处理完,响应结束时,会销毁request对象。

**作用范围:**在一次请求范围内,都可以获取到同一个request对象。

**主要功能:**和请求转发配合使用,从Servlet带数据到JSP(带数据到目的地)

request.setAttribute(String attrName, Object attrValue);
-- 往request域中存入一个域属性,属性名(key)只能是字符串,属性值(value)可以是任意类型。
request.getAttribute(String attrName);
-- 根据属性名(key)获取对应的属性值(value)。返回的是一个Object类型的对象。

response对象

response是代表HTTP响应信息的对象

/*  通知服务器在响应数据时,使用utf-8编码
 * 也能通知浏览器使用utf-8接收服务器发送的数据 */
response.setContentType( "text/html;charset=utf-8" );
PrintWriter out = response.getWriter();
out.write( "你好" );

请求转发(forward)和重定向(redirect)

实现请求转发

在这里插入图片描述

(1)转发是一次请求,一次响应
(2)请求转发前后,浏览器的地址栏地址不会发生变化。(浏览器–访问–> A --转发–> B,地址栏地址始终指向A的地址)
(3)请求转发前后的request对象是同一个(转发前在A中的request和转发到B后,B中的request对象和A中的request对象是同一个。基于这一点,可以通过request从A带数据到B)
(4)请求转发前后的两个资源必须属于同一个Web应用,否则将无法进行转发。(A–转发–>B,A和B必须属于同一个Web应用!)

request.getRequestDispatcher(“index.jsp”).forward(request, response);

request.getRequestDispatcher("index.jsp").forward(request, response);

实现请求转发

在这里插入图片描述

response.sendRedirect(所重定向到资源的URL地址);
//测试: 从当前Servlet重定向到百度首页
response.sendRedirect( "http://www.baidu.com" );

(1)重定向是两次请求、两次响应
(2)重定向前后,浏览器的地址栏地址会发生变化。(因为两次请求都是通过浏览器发起,浏览器知道这个跳转的过程,因此地址栏地址会变化)
(3)重定向前后的request对象不是同一个(因为重定向是两次请求,服务器会根据两次请求创建两个不同的request对象,request对象不是同一个,也就不能在重定向时通过request带数据到目的地。)
(4)重定向前后的两个资源可以是来自不同的web应用,甚至可以是来自不同的服务器。(进行跳转的两个资源之间没有限制)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值