照葫芦画葫芦,傻逼学习是这样的
Web开发
BS架构特点是,客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端。浏览器只需要请求服务器,获取Web页面,并把Web页面展示给用户即可。
浏览器向服务器请求一个url,服务器把生成的html网页发送给浏览器,浏览器渲染
Header: Value HTTP头
编写HTTP Server
Java标准库提供了ServerSocket来实现对指定IP和指定端口的监听。
典型服务器端
1 | public class Server { |
典型客户端
1 | public class Client { |
Java标准库使用InputStream和OutputStream来封装Socket的数据流,这样我们使用Socket的流,和普通IO流类似
再补多线程
一个任务称为一个进程
一个进程可以包含一个或多个线程,但至少会有一个线程。
操作系统调度的最小任务单位其实不是进程,而是线程。
main方法是一个进程,main调用的实力里面的方法是线程
1 | // 多线程 |
可以继承,接口,lambda
1 | // 多线程 |
main调用t线程,t线程开始进行,main也没有停止
直接调用Thread实例的run()方法是无效的
必须先start
线程的优先级
1 | Thread.setPriority(int n) // 1~10, 默认值5 |
线程的状态
1 | Runnable`、`Blocked`、`Waiting`和`Timed Waiting |
一个线程对象只能调用一次start()方法启动新线程,并在新线程中执行run()方法。一旦run()方法执行完毕,线程就结束了
可以通过t.join()等待t线程结束后再继续运行,在start后面加join
中断线程
interrupt()方法
如果对main线程调用interrupt(),join()方法会立刻抛出InterruptedException
running标志
把HelloThread.running置为false,就可以让线程结束
volatile关键字;
守护线程
在调用start()方法前,调用setDaemon(true)
线程同步
加锁和解锁
1 | synchronized(lock){ |
1 | synchronized(Counter.lock) { // 获取锁 |
返回500一般是sql语法出错
1 | class Data{ |
所以把锁放到类里面
1 | public synchronized void add(int n){ |
对于static方法,是没有this实例的,因为static方法是针对类而不是实例。
锁住的是该类的Class实例
可重入锁 在获取到锁以后继续获取同一个锁
死锁:两个线程拿到不同的锁不放
使用wait和notify
使用线程池
Java标准库提供了ExecutorService接口表示线程池,它的典型用法如下
使用DOM
最顶层的document代表XML文档,它是真正的“根”,而<book>虽然是根元素,但它是document的一个子节点。
使用DOM API解析一个XML文档的代码如下:
1 | InputStream input = Main.class.getResourceAsStream("/book.xml"); |
如果解析无误,我们将获得一个Document对象,这个对象代表了整个XML文档的树形结构,需要遍历以便读取指定元素的值
使用SAX
1 | InputStream input = Main.class.getResourceAsStream("/book.xml"); |
Myhandler要继承自DefaultHandler:
使用Jackson
XML可以对应到一个定义好的JavaBean中
我们要使用Jackson,先添加一个Maven的依赖:
- com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.10.1
1 | InputStream input = Main.class.getResourceAsStream("/book.xml"); |
使用JSON
去除了所有JavaScript执行代码,只保留JavaScript的对象格式
引入以下Maven依赖:
- com.fasterxml.jackson.core:jackson-databind:2.12.0
1 | InputStream input = Main.class.getResourceAsStream("/book.json"); |
把JSON解析为JavaBean的过程称为反序列化。如果把JavaBean变为JSON,那就是序列化
要实现JavaBean到JSON的序列化,只需要一行代码:
1 | String json = mapper.writeValueAsString(book); |
把JSON的某些值解析为Java对象
引入标准的JSR 310关于JavaTime的数据格式定义至Maven:
- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.0
1 | ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule()); |
TCP编程
一个应用程序通过一个Socket来建立一个远程连接,而Socket内部通过TCP/IP协议把数据传输到网络
一个Socket就是由IP地址和端口号(范围是0~65535)组成
Java标准库提供了ServerSocket来实现对指定IP和指定端口的监听。
UDP编程
UDP没有创建连接,数据包也是一次收发一个,所以没有流的概念。
服务器 datagramSocket
1 | DatagramSocket ds = new DatagramSocket(6666); // 监听指定端口 |
客户端
1 | DatagramSocket ds = new DatagramSocket(); |
发送Email
SMTP协议
- QQ邮箱:SMTP服务器是
smtp.qq.com,端口是465/587; - 163邮箱:SMTP服务器是
smtp.163.com,端口是465; - Gmail邮箱:SMTP服务器是
smtp.gmail.com,端口是465/587。
1 | // 服务器地址: |
1 | MimeMessage message = new MimeMessage(session); |
Http协议
接收Email
HTTP编程
服务器依靠User-Agent判断客户端类型是IE还是Chrome,是Firefox还是一个Python爬虫;
get请求
1 | import java.net.URI; |
如果我们要获取图片这样的二进制内容,只需要把HttpResponse.BodyHandlers.ofString()换成HttpResponse.BodyHandlers.ofByteArray(),就可以获得一个HttpResponse<byte[]>对象。如果响应的内容很大,不希望一次性全部加载到内存,可以使用HttpResponse.BodyHandlers.ofInputStream()获取一个InputStream流。
post请求
1 | String url = "http://www.example.com/login"; |
RMI远程调用
一个JVM中的代码可以通过网络实现远程调用另一个JVM的某个方法
JDBC编程
Java程序访问数据库的标准接口。
用Reader读取HTTP请求,用Writer发送HTTP响应
Servlet入门
1 | // WebServlet注解表示这是一个Servlet,并映射到地址/: |
覆写doGet()或doPost()方法
编写pom.xml文件如下:
1 | <project xmlns="http://maven.apache.org/POM/4.0.0" |
如有错误,多多指教