0%

对HTTP协议操作进行封装,使得程序员不必直接对协议进行操作,让Web开发更加便捷

目录结构

  • bin 可执行文件目录
  • conf 配置文件目录
  • lib 存放lib的目录
  • logs 日志文件目录
  • webapps 项目部署目录
  • work 工作目录
  • temp 临时目录

Maven中Tomcat的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8080</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>

  • 继承于Prepared类
  • 作用:预编译SQL语句并执行,预防SQL注入问题
  • SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达到代码对服务器进行攻击的方法

原理:

  1. 在获取PreparedStatement对象时,将sql语句发送给mysql服务器进行检查,编译
  2. 执行时就不用进行这些步骤,速度更快
  3. 如果sql模板相同,只需要进行一次检查,编译
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package com.sympa.lesson01;

import javax.swing.plaf.nimbus.State;
import java.sql.*;

public class JdbcFirstDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.加载驱动
//Class.forName("com.mysql.cj.jdbc.Driver"); //固定写法,加载驱动
//2.用户信息和url
//在url中添加useServerPrepStmts=true开启预编译功能
String url = "jdbc:mysql://127.0.0.1:3306/jdbcstudy?serverTimezone=UTC&useSSL=false&useServerPrepStmts=true";
String username = "root";
String password = "";
//3.连接成功,数据库对象 Connection 代表数据库
Connection connection = DriverManager.getConnection(url, username, password);

String sql = "select * from users";
String sql1 = "update users set password = ? where id = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
PreparedStatement pstmt1 = connection.prepareStatement(sql1);
pstmt1.setInt(1, 23333);
pstmt1.setInt(2, 1);

ResultSet resultSet = null; //返回的结果集
try {
//开启事务
connection.setAutoCommit(false);
int resultSet1 = pstmt1.executeUpdate();
resultSet = pstmt.executeQuery();
while(resultSet.next()){
System.out.println("id=" + resultSet.getObject("id"));
System.out.println("name=" + resultSet.getObject("name"));
System.out.println("password=" + resultSet.getObject("password"));
System.out.println("email=" + resultSet.getObject("email"));
System.out.println("birthday=" + resultSet.getObject("birthday"));
}
//提交事务
connection.commit();
} catch (Exception e) {
//回滚事务
connection.rollback();
e.printStackTrace();
}
//5.释放连接
resultSet.close();
pstmt.close();
pstmt1.close();
connection.close();
}
}

Connection功能

  1. 获取执行SQL的对象

    • 普通执行SQL对象:Statement createStatement()
    • 预编译SQL的执行SQL对象,防止SQL注入:PreparedStatement prepareStatement(sql)
    • 执行存储过程的对象:CallableStatement prepareCall(sql)
  2. 事务管理

    • 开启事务:setAutoCommit(boolean autoCommit),true为自动提交,false为手动提交
    • 提交事务:commit()
    • 回滚事务:rollback()
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    package com.sympa.lesson01;

    import javax.swing.plaf.nimbus.State;
    import java.sql.*;

    //我的第一个JDBC程序
    public class JdbcFirstDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
    //1.加载驱动
    //Class.forName("com.mysql.cj.jdbc.Driver"); //固定写法,加载驱动
    //2.用户信息和url
    String url = "jdbc:mysql://127.0.0.1:3306/jdbcstudy?serverTimezone=UTC&userUnicode=true&characterEncoding=utf8&useSSL=false";
    String username = "root";
    String password = "";
    //3.连接成功,数据库对象 Connection 代表数据库
    Connection connection = DriverManager.getConnection(url, username, password);
    //4.执行SQL的对象
    Statement statement = connection.createStatement();

    String sql = "select * from users";
    String sql1 = "update users set password = 114514 where id = 1";

    ResultSet resultSet = null; //返回的结果集
    try {
    //开启事务
    connection.setAutoCommit(false);
    int resultSet1 = statement.executeUpdate(sql1);
    resultSet = statement.executeQuery(sql);
    while(resultSet.next()){
    System.out.println("id=" + resultSet.getObject("id"));
    System.out.println("name=" + resultSet.getObject("name"));
    System.out.println("password=" + resultSet.getObject("password"));
    System.out.println("email=" + resultSet.getObject("email"));
    System.out.println("birthday=" + resultSet.getObject("birthday"));
    }
    //提交事务
    connection.commit();
    } catch (Exception e) {
    //回滚事务
    connection.rollback();
    e.printStackTrace();
    }
    //5.释放连接
    resultSet.close();
    statement.close();
    connection.close();
    }
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.sympa.lesson01;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectionTest {

public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException, InvocationTargetException, InstantiationException, IllegalAccessException {

Class<Person> clazz = Person.class;
Person person = clazz.getDeclaredConstructor().newInstance();
//操作运行时类的指定属性
Field age = clazz.getDeclaredField("age");
//设置当前对象指定属性值
age.set(person, 10); //(操作对象, 设置值)
//获取当前对象指定属性值
int ans = (int)age.get(person);
System.out.println(ans);

//操作运行时类的指定方法
//获取指定方法
Method show = clazz.getDeclaredMethod("show", int.class); //(方法名, 形参列表)
//保证当前方法可访问
show.setAccessible(true);
//执行方法
show.invoke(person, 2); //(方法名, 实参列表)
//invoke返回值即为方法返回值
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.sympa.lesson01;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectionTest {

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {

Class<Person> clazz = Person.class;

//newInstance:创建对应运行时类对象
Person person = clazz.getDeclaredConstructor().newInstance();
System.out.println(person);

//获取运行时类的属性结构
Field[] fields = clazz.getDeclaredFields();
for(Field f : fields){
System.out.println(f);
}

//获取运行时类的方法结构
Method[] methods = clazz.getDeclaredMethods();
for(Method m : methods){
System.out.println(m);
}

Method show = clazz.getMethod("show");

//…………………………
}
}

关于java.Lang.Class类的理解

类的加载过程
  • 程序经过javac,exe命令后,会生成一个或多个字节码文件(.class结尾)。
  • 接着使用java.exe命令对某个字节码文件进行解释运行,相当于将某个字节码文件加载到内存中,此过程就称为类的加载
  • 加载到内存中的类,我们就称为运行时类,此运行时类,就称为Class类的一个实例
  • 换句话说,Class的实例对应着一个运行时类
  • 加载到内存中的运行时类,会缓存一定时间,可以通过不同方式来获取此运行时类

获取Class实例的四种方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.sympa.lesson01;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectionTest {

public static void main(String[] args) throws ClassNotFoundException {

//方式1:调用运行时类的属性
Class clazz = Person.class;

//方式2:通过运行时类的对象,调用getClass()
Person person = new Person();
Class clazz1 = person.getClass();

//方式3:调用Class的静态方法:forName(String, classPath)
Class clazz2 = Class.forName("com.sympa.lesson01.Person");

System.out.println(clazz == clazz1); //true
System.out.println(clazz == clazz2); //true

//方式4:使用类的加载器:ClassLoader
ClassLoader classLoader = ReflectionTest.class.getClassLoader();
Class clazz3 = classLoader.loadClass("com.sympa.lesson01.Person");

}
}

哪些类型可以有Class对象

  • class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类
  • interface:接口
  • []:数组(元素类型和维度一样,就是同一个Class)
  • enum:枚举类
  • annotation:注解
  • primitive type:基本数据类型
  • void

Java反射机制提供的功能

  • 在运行时判断任意一个对象所属的类
  • 在运行时构造任意一个类的对象
  • 在运行时判断任意一个类所具有的成员变量和方法
  • 在运行时获取泛型信息
  • 在运行时调用任意一个对象的成员变量和方法
  • 在运行时处理注解
  • 生成动态代理

反射相关的主要API

  • java.lang.Class:代表一个类
  • java.lang.reflect.Method:代表类的方法
  • java.lang.reflect.Field:代表类的成员变量
  • java.lang.reflect.Constructor:代表类的构造器
  • ……
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.sympa.lesson01;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectionTest {

public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {

Class clazz = Person.class;
//1.通过反射,创建Person对象
Constructor cons = clazz.getConstructor(String.class, int.class);
Object obj = cons.newInstance("Tom", 12);
Person p = (Person) obj;
System.out.println(p.toString());

//2.通过反射调用对象属性
Field age = clazz.getField("age");
age.set(p, 10);
System.out.println(p.toString());

//3.通过反射调用对象方法
Method show = clazz.getDeclaredMethod("show");
show.invoke(p);
}
}

class Person {
private String name;
public int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public void show() {
System.out.println(name + age);
}
}

反射与封装性不矛盾

  • URL:统一资源定位符,标识Internet上某一资源地址

  • 是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源

  • URL基本结构由5部分组成:

    <传输协议>://<主机名>:<端口号>/<文件名>#片段名?参数列表

  • 片段名:即锚点,例如看小说,直接定位到章节

  • 参数列表格式:参数名=参数值&参数名=参数值……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.sympa.lesson01;

import java.io.IOException;
import java.net.URL;

public class URLTest {

public static void main(String[] args) {

try{
URL url = new URL("file:///F:/jdbc/02.jpg");
System.out.println(url.getProtocol()); //获取URL的协议名
System.out.println(url.getHost()); //获取URL的主机名
System.out.println(url.getPort()); //获取URL的端口号
System.out.println(url.getPath()); //获取URL的文件路径
System.out.println(url.getFile()); //获取URL的文件名
System.out.println(url.getQuery()); //获取URL的查询名

} catch (IOException e){
e.printStackTrace();
}
}
}

  • 类DatagramSocket 和 DatagramPacket 实现了基于UDP协议网络程序
  • UDP数据报通过数据报套接字DatagramSocket发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达
  • DatagramPacket对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号
  • UDP协议中每个数据报都给出了完整的地址信息,因此无需建立发送方和接收方的连接
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.sympa.lesson01;

import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;

public class UDPTest {

@Test
public void sender(){
try {
DatagramSocket socket = new DatagramSocket();
String str = "UDP消息发送";
byte[] data = str.getBytes(StandardCharsets.UTF_8);
DatagramPacket packet = new DatagramPacket(data, 0, data.length, InetAddress.getLocalHost(), 8888);

socket.send(packet);
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}

@Test
public void receiver(){
DatagramSocket socket = null;
DatagramPacket packet = null;
try {
socket = new DatagramSocket(8888);

byte[] data = new byte[100];
packet = new DatagramPacket(data, 0, data.length);
socket.receive(packet);
System.out.println(new String(packet.getData(), 0, packet.getLength()));
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package com.sympa.lesson01;

import org.junit.jupiter.api.Test;

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class InetAddressTest {

@Test
public void client(){
Socket socket = null;
OutputStream os = null;
FileInputStream fis = null;
try{
//1. 创建Socket对象,指明服务器端IP和端口号
InetAddress inet = InetAddress.getByName("127.0.0.1");
socket = new Socket(inet, 8888);
//2.获取输出流,用于输出数据
os = socket.getOutputStream();
fis = new FileInputStream(new File("F:\\jdbc\\src\\com\\sympa\\lesson01\\01.jpg"));
byte[] car = new byte[1024];
int len = 0;
//3.写出数据
while((len = fis.read(car)) != -1){
os.write(car, 0, len);
}
socket.shutdownOutput();

InputStream is = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] car1 = new byte[20];
while((len = is.read(car1)) != -1){
baos.write(car1, 0, len);
}
System.out.println(baos.toString());
} catch(IOException e) {
e.printStackTrace();
} finally {
try{
if(socket != null) socket.close();
if(os != null) os.close();
} catch (IOException e){
e.printStackTrace();
}
}
}

@Test
public void server() {
ServerSocket ss = null;
Socket socket = null;
InputStream is = null;
FileOutputStream fos = null;
try{
//1.创建服务器端socket对象,指明自己端口号
ss = new ServerSocket(8888);
//2.表明可以接受来自于客户端的socket
socket = ss.accept();
//3.获取输入流
is = socket.getInputStream();
fos = new FileOutputStream("04.jpg");
byte[] buffer = new byte[1024];
int len;
//4.读取输入流数据
while((len = is.read(buffer)) != -1){
fos.write(buffer, 0, len);
}
socket.shutdownInput();
System.out.println("收到了来自于" + socket.getInetAddress().getHostAddress() + "的消息");

OutputStream os = socket.getOutputStream();
os.write("收到".getBytes(StandardCharsets.UTF_8));
} catch (IOException e){
e.printStackTrace();
} finally {
try{
if(fos != null) fos.close();
if(is != null) is.close();
if(socket != null) socket.close();
if(ss != null) ss.close();
} catch (IOException e){
e.printStackTrace();
}
}
}

}