Taogen's Blog

Stay hungry stay foolish.

Solve coding problems

Programming language coding problems

Solve problems on LeetCode

Do small toy projects

To-do list

Calculator

Snake game

Make projects that solve your own problems or requirements

Web page crawlers

Web video downloader

Automation scripts or tools

Contribute to open-source projects

You can search “How to find open source projects to contribute”

Create your own open-source project

Doing open source projects forces you to write better and clean code.

Getting Started

Introduction to the programming language

Programming environment

Print “Hello world”

An example of the combination of variables, functions, expressions, statements, standard Input, and output

Comment. Single line and multiline comments.

Variables and Data Types

Variables

Variable declaration, initialization, assignment.

Variable scope. Local variables and global variables.

Data Types

Data type table by categories

Data type literal (type initialization) examples

Get the type of the variable

Type check

Check null or undefined

Check string type

Check number type

Check object type

Check array type

Check function type

Type conversion

Conversion between bool, integer, float, and string

number to string

string to number

string to float

Type formatting

String formatting. placeholders formatting.

Integer formatting. Add leading zero. Specify length.

Float formatting. fixed-point decimal formatting.

Date formatting. Format date objects by pattern.

String and Array

String

String basic

String declaration and initialization. multiline strings.

Length of string

Lookup

chatAt. the n character of the string

indexOf, lastIndexOf

String check

equals

isEmpty

contains

startsWith, endsWith

matches regex

String conversion

toCharArray

toLowerCase, toUpperCase

String Handling

String concatenation

Substring

replace

trim

split

join

String formatting

Array

Array basic

Array declaration and initialization

length of array

Lookup

Access element by index

indexOf

contains

Operations

insert, append

update

remove

Handling

Slice or subarray

Array concatenation

Conversion

Array to string

Expressions

Arithmetic operators

addition +, subtraction -, multiplication *, division /, remainder/modulo %, exponentiation ^.

Logical operators

and &&, or ||, not !

Comparison operators

equality ==, inequality !=, greater than >, less than <, >=, <=

Bitwise operators

bitwise AND &, bitwise OR |, bitwise NOT ~, bitwise XOR ^, left shift <<, right shift >>

Others operators

Assignment, member access, conditional operator

Operator precedence

Statements

Conditional

if

switch

For loop

while

for

do…while

Exception handling

try…catch…finally

throw

Functions

Function definition

Function call

Argument passing and return value

Modules

Classes and Objects

Object-Oriented Programming

Classes

Class definition

Class members. Constructors. Static and instance members of classes.

Objects

Object construction

Object Deep copy

Inheritance

Standard Library

I/O Streams and Files

Input/Output streams

Input stream types. Bytes input streams, character input streams, buffered input streams.

Output stream types. Bytes output streams, character output streams, buffered output streams.

Read from and write into files.

Read from and write into memory.

Non-blocking and asynchronous I/O

Moving data into and out of buffers

Files

File and directory operations. creation, delete, update.

File path.

File information. Mine type of files.

Temporary files and directories.

Container

Container types

List, Set, Map, Queue, Stack

Container Operations

Basic operations

Traversal, print, add elements, remove elements

Conversion

Element type conversion, Container conversion.

Common operations

Merge

Join

Deduplication

Sorting

Reversion

Computation

Reduction

Aggregation and group

Concurrent Containers

Thread and concurrency

Processes and threads

Synchronization.

Liveness. Deadlock and livelock (starvation).

Guarded blocks. wait and notifiy.

Immutable objects. Its state cannot change after it is constructed.

High level concurrency objects. Reentrant lock. Executors and thread pools. Concurrent collections. Atomic variables.

Network programming

Sockets

Web Sockets

Server-sent events

HTTP

HTTP clients.

Download files by HTTP URLs.

Security

Class loaders

User authentication

Digital signatures

Encryption

Advanced Topics

Lambda expressions and Functional Programming

Streams

Stream Creation

The filter, map Methods

Collecting Results

Grouping and Partitioning

Reduction Operations

Parallel Streams

Annotation

Generics

Reflection

Regular expressions

Packaging and deployment

References

[1] What are the basic fundamental concepts of programming?

[2] C++ Primer, Fifth Edition - Table of Contents

[3] Java SE 8 API

[4] The Java Tutorial: A Short Course on the Basics - Table of Contents

[5] Core Java, Volume I: Fundamentals, 12th Edition - Table of Contents

[6] Core Java, Vol. II-Advanced Features, 12th Edition - Table of Contents

Factors in choosing a programming language

  • Purpose
  • Speed to Market / Productivity
  • Popularity: Technology ecology
  • Usability: Readable code, less effort
  • Learning Curve / Simplicity
  • Performance / Speed
  • Security

Programming languages for developing web applications

When you’re talking about web applications at large scale, you have to consider things like security, performance, concurrency, developer productivity, scalability as a language, interoperability

Server-side programming languages for web application development

  • Small scale project: PHP, Python, Ruby
  • Large scale project: Java, Go, C# (.NET)
  • Others: Node.js

Comparison table of web application server-side programming languages

Language Purpose Speed to Market Popularity Usability Performance Security Learning Curve
PHP Produce dynamic web pages 1 2 3 2 3 2
Python High productivity and readable code 1 1 2 3 2 1
Ruby simply and with less effort 1 3 1 1 1 3

PHP disadvantages

  • Website may be difficult for modify if you don’t have a good architecture at the beginning.

Ruby disadvantages

  • There is so many magic here makes you feeling very well at the beginning. But when you need to go deeper into the framework. There would be a lot of pain.

Programming languages for developing mobile applications

Android

The majority of Android apps are written in Java and Kotlin. In some cases, programming languages like C, C++, and Basic are also used.

Java

Kotlin

C/C++ (Android Native Development Kit (NDK))

  • C++ can be used in Android app development in rare cases, especially when you plan to build native-activity Android applications. It is because C++ is less flexible and very difficult to set up, and as a result, it can lead to more bugs. Usually, Java is preferred more over C++.
  • Google offers the native development kit (NDK) that uses native languages like C and C++ for Android development. But you can’t build an entire Android app with C or C++. You need to learn Java.

iOS

Swift

Objective C

Cross-Platform Mobile

C# (Xamarin)

Dart (Flutter)

Lua (Corona, Solar2D)

JavaScript (React Native)

Python (convert Python apps into Android Packages)

Programming languages for developing desktop applications

Windows

C, C++

C#(.Net)

Linux

C/C++

Mac OS X

Swift

Objective C

Cross-Platform Desktop

Java

Python

JavaScript (Electron)

Local Environment

Check if your network status is OK and if you can access other websites.

Try a different browser or clear browser cache.

Check if the HOSTS file maps the domain name to 127.0.0.1 or an incorrect IP address. You can see what IP address the domain name is mapped to with the following command line.

ping {your_domain}

Check if you are using a HTTP proxy or if the proxy can access the website.

DNS Settings

Check that the A record of the DNS configuration points the domain name to the correct IP address.

Cloud Host

Check if the cloud host is on and accessible. You can use the following command line to check if cloud host is on.

ping {IP_address}

Check if the HTTP (80) or HTTPS (443) port is allowed in the firewall.

telnet {IP_address} 80
telnet {IP_address} 443

Check that the reverse proxy server listening on port 80 or 443 is running. You can find out what process is using 80 or 443 with the following command line.

sudo lsof -i -P -n | grep LISTEN

Check if the configuration of the reverse proxy server is correct.

Check if the actual web project is up and running. You can view all processes with the following command line.

ps -ef

Check that the cloud host operating system has sufficient resources such as CPU, memory, disk, and bandwidth. You can view the resource usage of the cloud host in the cloud platform console or view usage by command lines.

功能介绍

阿里云视频点播(VoD)提供了很多视频相关的功能。主要流程是上传视频,处理视频和播放视频。具体介绍可以参考视频点播产品简介。下图为视频点播的架构图。

视频点播架构图

准备工作

本节目标:开通服务,以及获取可以调用视频点播 SDK 和 API 的 accessKeyId 和 accessKeySecret。

开通视频点播服务

访问视频点播控制台页面,点击开通服务即可。第一次进入会提示开通服务,之后会直接进入点播控制台。

启用存储视频的Bucket

视频点播服务的视频存储可以使用点播系统Bucket,也可以使用OSS自有Bucket。

使用点播系统Bucket需要手动启用,操作如下:

视频点播控制台-> 配置管理 -> 存储管理 -> 顶部栏,选择地区:华东2(上海)-> 待分配 点播系统bucket:启用

点播系统Bucket上的视频使用视频点播相关功能会更方便。但如果你之前使用了阿里云的OSS,想要对你OSS上的视频使用视频点播相关功能也是可以的,就是会麻烦一点,需要多调用一个注册媒资信息接口。

这两种 bucket 有很多不同之处。详情可以查看视频点播-开发指南-存储管理视频点播-配置管理-存储管理

创建用户和授权

阿里云控制台 -> 右上角账号名称 -> 访问控制 -> 用户 -> 点击创建用户 -> 输入登录名称和显示名称,勾选 OpenAPI 调用访问 -> 点击确定 -> 保存用户的 accessKeyId 和 accessKeySecret

创建用户成功后,进入用户详情页面,为用户授予权限。

权限管理 -> 新增授权 -> 添加 “AliyunVODFullAccess 管理视频点播服务(VOD)的权限”

开发环境

本节目标:引入视频点播相关的 Java SDK。

Maven依赖

  • aliyun-java-sdk-core为核心库
  • aliyun-java-sdk-vod为VOD库
  • aliyun-java-sdk-kms为密钥管理服务(KMS)的所需依赖,若不涉及则无需添加。
  • com.aliyun.vod:upload 视频点播上传SDK没有开源,需要手动下载jar包引入到项目中。详情参考 SDK简介与下载-上传SDK
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.6.0</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-vod</artifactId>
<version>2.16.10</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-kms</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>com.aliyun.vod</groupId>
<artifactId>upload</artifactId>
<version>1.4.15</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/aliyun-java-vod-upload-1.4.15.jar</systemPath>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20230227</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.25</version>
</dependency>

调用接口

本节目标:了解接口调用流程和基本使用。

SDK的使用流程如下:

上传视频的代码示例

private static String uploadVideoToVOD(String fileName, InputStream inputStream) {
UploadStreamRequest request = new UploadStreamRequest(
accessKeyId, accessKeySecret, fileName, fileName, inputStream);
request.setAccessKeyId(accessKeyId);
request.setAccessKeySecret(accessKeySecret);
UploadVideoImpl uploader = new UploadVideoImpl();
UploadStreamResponse response = uploader.uploadStream(request);
System.out.print("RequestId=" + response.getRequestId() + "\n"); //请求视频点播服务的请求ID
String videoId = response.getVideoId();
if (response.isSuccess()) {
System.out.print("VideoId=" + response.getVideoId() + "\n");
} else { //如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因
System.out.print("VideoId=" + response.getVideoId() + "\n");
System.out.print("ErrorCode=" + response.getCode() + "\n");
System.out.print("ErrorMessage=" + response.getMessage() + "\n");
}
return videoId;
}

/**
* 获取上传结果
*
* 用于检查是否上传成功,视频上传成功后才能进行视频处理
*
* @param videoId
* @return
* @throws ClientException
*/
private static GetUploadDetailsResponse.UploadDetail getUploadDetails(String videoId) throws ClientException {
GetUploadDetailsRequest request = new GetUploadDetailsRequest();
request.setMediaIds(videoId);
GetUploadDetailsResponse acsResponse = initVodClient(ACCESS_KEY_ID, ACCESS_KEY_SECRET).getAcsResponse(request);
return acsResponse.getUploadDetails().get(0);
}

创建 DefaultAcsClient,请求视频AI处理的代码示例

private static String submitAiJob(String videoId) throws ClientException {
SubmitAIJobRequest request = new SubmitAIJobRequest();
request.setMediaId(videoId);
request.setTypes("AIVideoTag");
// Face,ASR,OCR,Category,Annotation
request.setConfig("{\"AIVideoTag\": {\"AnalyseTypes\": \"ASR,OCR,Annotation\"} }");
SubmitAIJobResponse acsResponse = initVodClient(ACCESS_KEY_ID, ACCESS_KEY_SECRET).getAcsResponse(request);
String jobId = acsResponse.getAIJobList().get(0).getJobId();
System.out.println("jobId: " + jobId);
return jobId;
}

private static ListAIJobResponse.AIJob listAiJob(String jobId) throws ClientException {
ListAIJobRequest listAIJobRequest = new ListAIJobRequest();
listAIJobRequest.setJobIds(jobId);
ListAIJobResponse acsResponse = initVodClient(ACCESS_KEY_ID, ACCESS_KEY_SECRET).getAcsResponse(listAIJobRequest);
ListAIJobResponse.AIJob aiJob = acsResponse.getAIJobList().get(0);
return aiJob;
}

public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) {
String regionId = "cn-shanghai"; // 点播服务接入地域
DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
DefaultAcsClient client = new DefaultAcsClient(profile);
return client;
}

视频点播的服务端 Java SDK 的使用

  • 创建一个对应视频处理的 Request 对象。SDK 的 request 对象和 API 上写的的基本一致,API 名称加个 Request 后缀即可。API 上有详情的参数说明,可结合使用。
  • 创建一个 VodClient 对象。
  • 获取对应的视频处理 Response 对象。

其他

查看费用

阿里云控制台 -> 顶部栏 “费用” -> 账单详情 -> 明细账单。

账单明细会有延迟,不能看到实时的消费明细。

明细账单数据相对于实际费用消耗延迟24小时更新,其中实例ID相关的信息( 实例配置,实例规格,实例昵称,资源组,公网IP,私网IP,可用区)延迟48小时更新。

关闭服务

视频点播服务没有统一的关闭入口。但可以在视频点播控制台中删除所有付费项。比如:删除掉所有域名,清空所有存储,取消转码和调用。

HTML & CSS

HTML: HyperText Markup Language

CSS: Cascading Style Sheets

Tags and Attributes of HTML Elements

Block Elements

<div>: document divisions

<h1>-<h6>: headings

<p>: paragraphs

<ul>: unordered lists

<ol>: ordered lists

<li>: list item

<pre>: preformatted text

<hr>: horizontal rules

Inline Elements

<img>: image

  • src: source
  • alt: alternative

<a>: anchor

  • href: hypertext reference

<br>: line break

References

Center a Div

The HTML example

<div class="container" style="height: 200px; width: 100%;">
<div class="child" style="width: 500px; height: 100px;">
I am the child
</div>
</div>

Horizontally Center a Div

Using margin

.container {
}
.child {
margin: 0 auto;
}

Using flex

.container {
display: flex;
justify-content: center;
}
.child {
}

Using position

.container {
position: absolute;
}
.child {
position: absolute;
left: 50%;
transform: translate(-50%);
}

Vertically Center a Div

Using flex

.container {
display: flex;
align-items: center;
}
.child {
}

Using position

.container {
position: absolute;
}
.child {
position: absolute;
top: 50%;
transform: translate(0, -50%);
}

Horizontally and Vertically Center a Div

Using flex

.container {
display: flex;
align-items: center;
justify-content: center;
}
.child {
}

Using grid

.container {
display: grid;
place-items: center;
}
.child {
}

Using position

.container {
position: absolute;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

Using margin and grid

.container {
display: grid;
}
.child {
margin: auto;
}

Using margin and flex

.container {
display: flex;
}
.child {
margin: auto;
}

Center Text

The HTML example

<div class="container" style="width: 500px; height: 100px;">
I am the text
</div>

Horizontally Center Text

Using text-align

.container {
text-align: center;
}

Using flex

.container {
display:flex;
justify-content: center;
}

Vertically Center Text

Using height and line-height

center a single line text

.container {
height: 50px;
line-height: 50px;
}

Using table-cell and vertical-align

.container {
display:table-cell;
vertical-align:middle;
}

Using pading-top and padding-bottom

.container {
padding-top: 100px;
padding-bottom: 100px;
}

Using flex

.container {
display:flex;
align-items:center;
}

Horizontally and Vertically Center Text

Using text-align + line-height

Using text-align + table-cell and vertical-align

Using text-align + padding top and bottom

Using flex

.container {
display:flex;
align-items:center;
justify-content: center;
}

Buy your blog website domain

You can buy a domain from the following domain registers:

Installing Hexo

Before installing Hexo, you need installing the following software

  • Node.js (Should be at least Node.js 10.13, recommends 12.0 or higher)
  • Git

Installing Hexo

npm install -g hexo-cli
hexo -v

Uninstalling Hexo

npm uninstall -g hexo-cli

Create your Hexo project

cd hexo-site
hexo init .
npm install
npm install hexo

Configuring Hexo

Configuring basic website information in _config.yml

Setting Description
title The title of your website
subtitle The subtitle of your website. (slogan)
description The description of your website
author Your name

Run Hexo

cd hexo-site
hexo s --debug

Visit http://localhost:4000

NexT Theme

Installation NexT

If you’re using Hexo 5.0 or later, the simplest way to install is through npm.

cd hexo-site
npm install hexo-theme-next

Upgrading NexT

cd hexo-site
npm install hexo-theme-next@latest

Enable NexT

Enable NexT in _config.yml

theme: next

Checking NexT

hexo clean
hexo s --debug

Visit http://localhost:4000

Settings

Copy default NexT configuration file to root path

cp node_modules/hexo-theme-next/_config.yml _config.next.yml

Enable cache in _config.next.yml

cache:
enable: true

Enable minify in _config.next.yml

minify: true

Set Gemini Scheme in _config.next.yml

#scheme: Muse
#scheme: Mist
#scheme: Pisces
scheme: Gemini

Enable icons and badges in _config.next.yml

menu_settings:
icons: true
badges: true

Disable motion to load web pages faster in _config.next.yml

motion:
enable: false

Update codeblock settings in _config.next.yml. Choose your favorite code block theme on NexT Highlight Theme Preview. Recommend highlight themes: stackoverflow-light, intellij-light.

codeblock:
theme:
light: intellij-light
dark: intellij-light
copy_button:
enable: true

Disable line number in _config.yml (Optional)

highlight:
line_number: false

prismjs:
line_number: false

Enable scroll percent in _config.next.yml

back2top:
scrollpercent: true

Update favicon in _config.next.yml

favicon:
small: /favicon_16x16.ico
medium: /favicon_32x32.ico
apple_touch_icon: /favicon.jpg
safari_pinned_tab: /favicon.jpg

Adding Page

Enable menu home, about, tags, categories, achives in _config.next.yml

menu:
home: / || fa fa-home
about: /about/ || fa fa-user
tags: /tags/ || fa fa-tags
categories: /categories/ || fa fa-th
archives: /archives/ || fa fa-archive

Home and Archives pages exist by default.

We need to add tags, categories, and about pages

hexo new page tags && hexo new page categories && hexo new page about

Setting page type

  • source/tags/index.md: type: tags
  • source/categories/index.md: type: categories
  • source/about/index.md: type: about

For example:

title: Tags
date: xxx
type: tags

Re-run your hexo project to see the new theme settings.

hexo s --debug

Add Search Service

Add the Local Search

Installation

npm install hexo-generator-searchdb

Configuring Hexo config file _config.yml. Add the following configurations to the _config.yml file

search:
path: search.xml
field: post
content: true
format: html

Configuring NexT config file _config.next.yml

local_search:
enable: true

Deploying your Hexo website

Push your Hexo project to GitHub

Create a new git repository on GitHub

Push your hexo project to GitHub

git init .
git add -A
git commit -m "Initialize Hexo project"
git remote add origin git@github.com:tagnja/{your-repository-name}.git
git branch -M main
git push -u origin main

Deploying Hexo website to Vercel

Add new project on Vercel

Import Git Repository

Deploy the project

Domain settings for your project on Vercel

Add your domain in Vercel -> hexo project -> Settings -> Domains

Add vercel dns to your domain register

ns1.vercel-dns.com
ns2.vercel-dns.com

Visit your domain in web browser

References

Create a spring boot project

You can go to Spring Initializr to create a spring boot project

Setting your basic configurations. The following is my settings

  • Project: Maven
  • Language: Java
  • Spring Boot: 2.7.9
  • Project Metadata:
    • Group: com.taogen
    • Aritifact: chatgpt-demo
    • Packaging: Jar
    • Java: 8

You can set your own configurations according to your local environment.

After setting the project configurations, we need to add the following dependencies:

  • Spring Web
  • Lombok

Then we click the GENERATE button to download our project file.

After downloading the generated project file, we need to decompress the file and open the directory in our IDE. I prefer to use IntelliJ IDEA as my IDE.

Call the ChatGPT API in spring boot

Configuring your Open AI key in application.properties

openai.apiKey=${YOUR_OPEN_AI_KEY}

Create the RestTemplateConfig.java to build the RestTemplate bean for API calls

@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
}

Create a POJO ChatGpt3dot5Request.java for building ChatGPT API requests

@Data
public class ChatGpt3dot5Request {
public static final String ENDPOINT = "https://api.openai.com/v1/chat/completions";

public static final String STREAM_MESSAGE_PREFIX = "data: ";

private String model = "gpt-3.5-turbo";

private Boolean stream;
List<Message> messages = new ArrayList<>();

@Data
@AllArgsConstructor
static class Message {
private String role;
private String content;
}
}

Create the controller ChatBotController.java

@RequestMapping("/chatbot")
@RestController
public class ChatBotController {

@Autowired
public RestTemplate restTemplate;

@Value("${openai.apiKey}")
private String OPEN_API_KEY;

@PostMapping("/conversation")
public void conversation(@RequestBody String prompt, HttpServletResponse httpServletResponse) throws IOException {
httpServletResponse.setContentType("text/plain; charset=UTF-8");
UriComponentsBuilder builder = UriComponentsBuilder
.fromUriString(ChatGpt3dot5Request.ENDPOINT)
.queryParams(null);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
httpHeaders.setBearerAuth(OPEN_API_KEY);
String json = getRequestBody(prompt);
HttpEntity<Object> requestEntity =
new HttpEntity<>(json, httpHeaders);
ResponseEntity<Resource> responseEntity = restTemplate.exchange(builder.build().toUriString(), HttpMethod.POST, requestEntity, org.springframework.core.io.Resource.class);
PrintWriter writer = httpServletResponse.getWriter();
BufferedReader bufferedReader;
try {
bufferedReader = new BufferedReader(new InputStreamReader(responseEntity.getBody().getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null && !(ChatGpt3dot5Request.STREAM_MESSAGE_PREFIX + "[DONE]").equals(line)) {
String message = getMessageFromLine(line, ChatGpt3dot5Request.STREAM_MESSAGE_PREFIX);
writer.write(message);
writer.flush();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}

private static String getMessageFromLine(String line, String prefix) throws JsonProcessingException {
if (!StringUtils.hasLength(line.trim())) {
return "";
}
String messageJsonStr = line.substring(line.indexOf(prefix) + prefix.length());
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode objectNode = (ObjectNode) objectMapper.readTree(messageJsonStr);
JsonNode messageNode = objectNode.get("choices").get(0).get("delta").get("content");
if (messageNode != null) {
return messageNode.asText();
} else {
return "";
}
}

private String getRequestBody(String prompt) throws JsonProcessingException {
ChatGpt3dot5Request chatGpt3dot5Request = new ChatGpt3dot5Request();
chatGpt3dot5Request.setStream(true);
chatGpt3dot5Request.setMessages(Arrays.asList(
new ChatGpt3dot5Request.Message("user", prompt)));
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(chatGpt3dot5Request);
return json;
}
}

The ChatBotController sends an HTTP request to ChatGPT API and reads its response stream line by line. Each line of the response has a similar structure. We extract the chat content by removing the prefix data: , parsing the string to a JSON object, and retrieving the content value. This content is then written into the response of our chatbot API. The following is an example of the content of the ChatGPT API response.

Click to expand!
data: {"id":"chatcmpl-6zET7QIiAHSVeqoBwPNncxtIL3L6O","object":"chat.completion.chunk","created":1680051645,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"role":"assistant"},"index":0,"finish_reason":null}]}

data: {"id":"chatcmpl-6zET7QIiAHSVeqoBwPNncxtIL3L6O","object":"chat.completion.chunk","created":1680051645,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":"Hi"},"index":0,"finish_reason":null}]}

data: {"id":"chatcmpl-6zET7QIiAHSVeqoBwPNncxtIL3L6O","object":"chat.completion.chunk","created":1680051645,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":" there"},"index":0,"finish_reason":null}]}

data: {"id":"chatcmpl-6zET7QIiAHSVeqoBwPNncxtIL3L6O","object":"chat.completion.chunk","created":1680051645,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":"!"},"index":0,"finish_reason":null}]}

data: {"id":"chatcmpl-6zET7QIiAHSVeqoBwPNncxtIL3L6O","object":"chat.completion.chunk","created":1680051645,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":" How"},"index":0,"finish_reason":null}]}

data: {"id":"chatcmpl-6zET7QIiAHSVeqoBwPNncxtIL3L6O","object":"chat.completion.chunk","created":1680051645,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":" can"},"index":0,"finish_reason":null}]}

data: {"id":"chatcmpl-6zET7QIiAHSVeqoBwPNncxtIL3L6O","object":"chat.completion.chunk","created":1680051645,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":" I"},"index":0,"finish_reason":null}]}

data: {"id":"chatcmpl-6zET7QIiAHSVeqoBwPNncxtIL3L6O","object":"chat.completion.chunk","created":1680051645,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":" assist"},"index":0,"finish_reason":null}]}

data: {"id":"chatcmpl-6zET7QIiAHSVeqoBwPNncxtIL3L6O","object":"chat.completion.chunk","created":1680051645,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":" you"},"index":0,"finish_reason":null}]}

data: {"id":"chatcmpl-6zET7QIiAHSVeqoBwPNncxtIL3L6O","object":"chat.completion.chunk","created":1680051645,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":" today"},"index":0,"finish_reason":null}]}

data: {"id":"chatcmpl-6zET7QIiAHSVeqoBwPNncxtIL3L6O","object":"chat.completion.chunk","created":1680051645,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{"content":"?"},"index":0,"finish_reason":null}]}

data: {"id":"chatcmpl-6zET7QIiAHSVeqoBwPNncxtIL3L6O","object":"chat.completion.chunk","created":1680051645,"model":"gpt-3.5-turbo-0301","choices":[{"delta":{},"index":0,"finish_reason":"stop"}]}

data: [DONE]

Call your spring boot application API

Send a “hello” prompt to ChatGPT API by your API

curl -d 'hello' -H 'Content-Type: application/json' -X POST http://localhost:8080/chatbot/conversation
Hi there! How can I assist you today?

Note: If ChatGPT is not available in your region, you will not be able to call the ChatGPT API and the request will time out. Your application may throw the following exception:

2023-03-16 14:40:22.680 ERROR 14704 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://api.openai.com/v1/engines/davinci-codex/completions": Connection timed out: connect; nested exception is java.net.ConnectException: Connection timed out: connect] with root cause
java.net.ConnectException: Connection timed out: connect

Java

1. Use logging. Never use system.out.print().

For long-running programs, you’ll need to look at the log files to check that the program is functioning correctly.

2. For the scheduled task thread or any thread other than the main thread, catch the entire code block exception.

Generally, the main thread has global exception handling, but other threads do not.

3. No empty catch blocks.

An empty catch block won’t give you any information about what exception occurred. Probably the exception doesn’t matter, but it’s still an exceptional case.

4. Separate business and functional code.

Businesses are changing and functions are shared and reusable.

5. Divide your code by domain rather than by functionality or class type.

Usually, changes in your application are related to a specific domain, you should focus on business domains when building your structures, not functionality or class type.

6. Don’t create unnecessary variables, objects in a loop block.

Be careful when creating objects in a loop block. Create objects before a loop block if possible. Don’t create a lot of unnecessary objects in a loop block. For example, java.text.SimpleDateFormat, org.apache.poi.xssf.usermodel.XSSFCellStyle objects.

7. Don’t use Java internal code. All classes in com.sun.*, sun.*, or jdk.*are notionally internal, and should not be used directly in your code. All the classes you can use are in the Java API documentation, such as java.*, javax.*, and org.*.

Data Access

1. Never execute SQL statements in a for loop.

It takes a lot of time. You should find a way to do it in bulk.

Java Web and Spring Boot

1. Scheduling tasks should run when a specific profile is activated.

If the project is deployed on multiple servers, each server will execute scheduled tasks. Even if it activates different profiles on different servers.

2. API URLs use domain names rather than IP addresses.

If you use IP-based API URLs in many projects, you need to change many projects whenever the IP address changes.

3. Use Environment Variables in spring boot configuration files.

Don’t expose your confidential information in source code.

0%