HTML元素的id是否唯一
HTML 元素原则上应该保持唯一,但没有硬性要求。
存在多个相同的 id 元素时,CSS 对所有元素都生效。
<style> |
然而,JavaScript 和 jQuery 都只获取多个相同的 id 元素的第一个元素。
document.getElementById("myId").innerHTML //div1 |
$("#myId").html() //div1 |
HTML 元素原则上应该保持唯一,但没有硬性要求。
存在多个相同的 id 元素时,CSS 对所有元素都生效。
<style> |
然而,JavaScript 和 jQuery 都只获取多个相同的 id 元素的第一个元素。
document.getElementById("myId").innerHTML //div1 |
$("#myId").html() //div1 |
Using List<Integer> ids
to receive a form parameter of HTTP request. The size of the parameter ids is over 255.
org.springframework.beans.InvalidPropertyException: Invalid property 'ids[256]' of bean class [com.fantasi.manage.console.web.modules.recovery.dto.RecoveryGroupDto]: Invalid list index in property path 'ids[256]'; nested exception is java.lang.IndexOutOfBoundsException: Index: 256, Size: 256. |
To override init Binder method and configure the limit size which needs so that you can pass those many objects to your controller classes.
@Controller |
@InitBinder plays the role to identify the methods which initialize the WebDataBinder.
WebDataBinder is a DataBinder that binds request parameter to JavaBean objects.
By default spring only maps only 255 objects to the java bean. Spring developers has done this to prevent OutOfMemory problem.
[1] Spring initBinder for Handling Large List of Java Objects
String text = "hello 世界"; |
String text = "hello 世界"; |
MD5 (Message Digest 5)
String text = "123456"; |
Note: the MessageDigest is not thread-safe. Consequently, we should use a new instance for every thread.
SHA (Secure Hash Algorithm)
SHA-256 by MessageDigest
String text = "123456"; |
SHA3-256 by MessageDigest (since Java 9)
String text = "123456"; |
Concluding all points, it will be better to use MDA5 if you want to secure your files otherwise you can use SHA256.
DES (data encryption standard, 1976)
DES is Not Secure.
3DES is Not Secure.
AES (advanced encryption system, 2001)
The AES algorithm has six modes of operation:
Don’t use AES Electronic codebook (ECB) Mode. The AES ECB mode, or AES/ECB/PKCS5Padding
(in Java) is not semantically secure.
AES encryption best practice: Don’t reuse IV with the same key.
IV
The IV (initial value or initial vector), it is random bytes, typically 12 bytes or 16 bytes. In Java, we can use SecureRandom
to generate the random IV.
public static IvParameterSpec generateIv() { |
secret key
The AES secret key, either AES-128
or AES-256
. In Java, we can use KeyGenerator
to generate the AES secret key.
public static SecretKey getAESKey() throws NoSuchAlgorithmException { |
The AES secret key that derived from a given password. In Java, we can use the SecretKeyFactory
and PBKDF2WithHmacSHA256
to generate an AES key from a given password.
public static SecretKey getAESKeyFromPassword(char[] password, byte[] salt) |
salt
We use salt
to protect rainbow attacks, and it is also a random byte, we can use the SecureRandom to generate it.
import javax.crypto.KeyGenerator; |
CBC Mode
Input
GCM Mode
RSA (Rivest-Shamir-Adleman)
public static void getKeyPair() throws NoSuchAlgorithmException { |
ECC (Elliptic Curve Cryptography)
QueryWrapper
// usage 1 |
LambdaQueryWrapper
// usage 1 |
Convert QueryWrapper
to LambdaQueryWrapper
LambdaQueryWrapper<SysUser> lambdaQueryWrapper = new QueryWrapper<SysUser>() |
An example
List<SysUser> sysUserList = userService.list( |
from
new QueryWrapper<Entity>() |
select
wrapper.select("column 1", "column 2") |
where
wrapper.eq("type", 1) |
and…or
// where type = 1 or type = 2 |
// find_in_set(?, category_id) or find_in_set(?, category_id) |
// where status = 0 and (type = 1 or (type > 10 and type < 20)) |
order by
wrapper.orderByDesc("id") |
limit
wrapper.last("limit 10") |
find_in_set
wrapper.apply("find_in_set({0}, type)", type); |
Date functions
date equal
wrapper.apply("date(gmt_create)=date({0})", new Date()) |
Recent 7 days
wrapper.apply("create_time > DATE_SUB(NOW(), INTERVAL 7 DAY)")); |
http://xxx.xxx/?current=1&size=10&orders[0].column=pubtime&orders[0].asc=true
com.baomidou.mybatisplus.extension.plugins.pagination.Page
Fields for Request parameters
long size
long current
List<OrderItem> orders
String column
boolean asc
Fields for response
List<T> records
long total
MyBatis Plus page query method
IPage<T> selectPage(IPage<T> page, Wrapper<T> queryWrapper) |
Custom page query in Mapper XML
IPage<MyResult> myPageQuery(@Param("page") Page page, @Param("param") MyParam param); |
com.baomidou.mybatisplus.extension.plugins.pagination.Page
object as a parameter.IPage
class as the return type.limit start, size
in mapper XML. The SQL is query all rows. But MyBatis Plus automatically add limit at the end of SQL. If you want to query all, update to List<MyResult> queryAll(@Param("param") MyParam param);
List<Object> names = baseMapper.selectObjs( |
Aggregation Query methods
List<Map<String, Object>> mapList = userMapper.selectMaps( |
List<Object> mapList = userMapper.selectObjs( |
userMapper.selectCount(queryWrapper); |
select
queryWrapper.select("count(*) as typeCount"); |
group by
queryWrapper.groupBy("type")); |
having
queryWrapper.having("COUNT(*) > 10")) |
Non-query fields
Use @TableField(exist = false)
public class User { |
Use @TableName(excludeProperty={})
@TableName(value = "my_table_name", excludeProperty = {"dept"}) |
Columns using like "%xxx%"
Using @TableField(condition = SqlCondition.LIKE)
@TableField(condition = SqlCondition.LIKE) |
Only perform field query if the value is not null or empty
Using @TableField(whereStrategy = FieldStrategy.NOT_EMPTY)
IGNORED
: 不判断NOT_NULL
: 非NULL判断NOT_EMPTY
: 非空判断@TableField(whereStrategy = FieldStrategy.NOT_EMPTY) |
Using MySQL keyword as a column name
@TableField(value = "`type`") |
Using another entity name
@Alias("UserV2") |
Update
userService.update(new UpdateWrapper<User>() |
update it to null when it value is null
@TableField(fill = FieldFill.UPDATE) |
Logical delete
// Note that the field for logical deletion cannot be modified by update() method |
mybatis-plus: |
More configurations reference MyBatis Plus使用配置
Running the Spring Boot project occurs an error.
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.datasource.druid.initialSize' in value "${spring.datasource.druid.initialSize}" |
1. Check that the property you need exists in a configuration file. Find out in which configuration file your injected property is.
2. Check whether the property spring.profiles.active
value is correct in application.yml
. Make sure the active profile is in your project.
3. Check whether your injected property exists in application.yml
(or application.properties
) and the active profile application-xxx.yml
(or application-xxx.properties
).
The value of the property spring.profiles.active
in my application.yml
is spring.profiles.active=pro
, but I don’t have the application-pro.yml
file. The property’s value spring.profiles.active=pro
should update to prod
.
When I do an insert operation to save the item data to MySQL, occurs an error.
Error updating database. Cause: java.sql.SQLException: Data truncated for column 'xxx' at row 1 |
Check whether the column type is right.
Check whether the length of the field value over the length of the column.
The length of the field value over the length of the column.
My passed field value is a set
type value, but the column type is enum
. The column type should update to set
.
When I use the FreeMarker to generate text files, occurs an error: Failed to “?eval” string.
<#assign dataFromConfigJson = columnMapping.formComponentDataFromConfig?eval> |
FreeMarker template error: |
Corrects the JSON string of the field of data that passed to the FreeMarker Template object.
The JSON string is invalid.
解决方案:笔记本和外接显示器的缩放比例保持一致。
Display settings -> Scale and layout
解决方案:将外接屏幕设为主显示器,并设置“仅显示外接显示器”。
Display settings -> Rearrange your display -> Click 2 for setting extended monitor
Display settings -> Multiple displays -> select “Show only on 2”, and checked “Make this main display”
Solution: 声音设置中选择笔记本的扬声器作为声音输出设备。
Reason: HDMI接口是包含音频+视频两种信号的接口。当电脑的HDMI接口被使用时,系统就会默认从HDMI设备输出声音信号。
在我看来,编程它既是脑力活,也是体力活。脑力活在于如何解决未知的问题,体力活则在于一行一行地敲代码完成已知的问题。
编程中最累人的便是面对未知问题。如:未知的技术栈,未知的系统设计,未知的设计模式和类的继承结构,未知的算法实现,未知的异常等等。遇到未知问题时,我们会注意力保持高度集中,不断的失败,不断的尝试,我们绞尽脑汁想要解决这个问题,同时我们感到沮丧和急躁。然而,长时间的保持紧绷的神经和僵硬的坐姿会严重影响我们的健康状态。作为一名程序员,为了保持良好的身心健康,我们要学会如何与未知相处。
我们不可能去知道所有的技术和知识。但是我们可以把自己经历过的问题,总结一下,下次遇到相似的问题,可以轻松地应对。我们也可以尽量地学习和了解一些你所处领域相关的你没有掌握的技术。
每个人掌握着有限的知识,每个人都会遇到难题。遇到难题不能完全代表一个人的能力水平,难题给了我们一次成长的机会。我们尽力去解决问题,最终无论我们能不能解决这个难题,我们都会有所收获。
解决未知问题的过程就是把未知慢慢变成已知的过程。我们在解决未知问题的过程中,经过了一段时间的思考之后,我们会发现自己有了点思路或者有了点感觉,慢慢地问题就逐渐变得越来越明朗了。
保持心平气和地去解决未知问题,这是急不来的,我们需要给大脑一些时间去理解和记忆。
Content
@PostMapping(value = "/uploadFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
public class FileUploadByCommonsFileUploadServlet extends HttpServlet { |
Write input streams to the OutPutStream of the HttpServletResponse
@GetMapping(value = "/download" ) |
Write file Resource to ReponseBody
@GetMapping(value = "/download" ) |
original file name: “中 文.txt”
filename = resource.getFilename()
// 中%20文.txt
browser download filename: -%20‡.txt
1
filename = URLEncoder.encode(resource.getFilename().replace("%20", " "), "UTF-8")
// %E4%B8%AD+%E6%96%87.txt
browser download filename: 中+文.txt
2
filename = URLEncoder.encode(resource.getFilename().replace("%20", " "), "UTF-8").replace("+", "%20")
// %E4%B8%AD%20%E6%96%87.txt
browser download filename: 中 文.txt
When browser resolve file name, they don’t decode “+” to “ “, so we need replace “+” to “%20”.
@RestController |
java.io.FileInputStream
InputStream is = new FileInputStream("D:\\My Desktop\\test.txt"); |
org.springframework.core.io.UrlResource
Spring framework Resource Interface
Java’s standard
java.net.URL
class and standard handlers for various URL prefixes unfortunately are not quite adequate enough for all access to low-level resources. For example, there is no standardizedURL
implementation that may be used to access a resource that needs to be obtained from the classpath, or relative to aServletContext
. While it is possible to register new handlers for specializedURL
prefixes (similar to existing handlers for prefixes such ashttp:
), this is generally quite complicated, and theURL
interface still lacks some desirable functionality, such as a method to check for the existence of the resource being pointed to.
String filepath = "D:\\My Desktop\\test.txt"; |
java.net.URL
String filepath = "D:\\My Desktop\\test.txt"; |
org.springframework.core.io.ClassPathResource
// src/main/resources/application.yml |
org.springframework.core.io.ResourceLoader
@Autowired |
byte[] data = new String("data...").getBytes(StandardCharsets.UTF_8); |
java.net.URL
InputStream is = new URL("http://demo.com/test.txt").openStream(); |
org.springframework.core.io.UrlResource
Resource resource = new UrlResource("http://demo.com/test.txt"); |
java.net.HttpURLConnection
URLConnection urlConnection = new URL("http://demo.com/test.txt").openConnection(); |
Reference my another post: Common OSS Java SDK Usage
byte[] data = new String("data").getBytes(StandardCharsets.UTF_8); |
byte[] data = new String("data").getBytes(StandardCharsets.UTF_8); |
Reference my another post: Common OSS Java SDK Usage
stream
InputStream is = new FileInputStream("D:\\My Desktop\\test.txt"); |
java.nio.file.Files
Path path = Paths.get("D:\\My Desktop\\test.txt"); |
basic zip
try ( |
nested zip
try ( |
Using buffer to decrease calls to the underlying runtime system
String inputFilePath = "C:\\Users\\Taogen\\Desktop\\input.txt"; |
String inputFilePath = "C:\\Users\\Taogen\\Desktop\\input.txt"; |
BufferedInputStream
‘s default buffer size is int DEFAULT_BUFFER_SIZE = 8192;
BufferedInputStream
+ Buffer arrayString inputFilePath = "C:\\Users\\Taogen\\Desktop\\recovery_data.sql"; |
Time cost: BufferedInputStream + Direct Buffer array < Direct Buffer array < Using a BufferedInputStream < Read Method.
Using BufferedInputStream rather than direct buffer is probably “right” for most applications. Because your used buffer size of direct buffer may be worse than BufferedInputStream default buffer size in speed.
Will making the buffer bigger make I/O go faster? Java buffers typically are by default 1024 or 2048 bytes long. A buffer larger than this may help speed I/O, but often by only a few percent, say 5 to 10%.
java.io.tmpdir
System.getProperty("java.io.tmpdir") |
Windows 10: C:\Users\{user}\AppData\Local\Temp\
Debian: /tmp
Create temporary file
// If you don't specify the file suffix, the default file suffix is ".tmp". |
Java get file’s mimeType
// 1 |
Content-Type(Mime-Type) | Kind of document | Extension |
---|---|---|
application/octet-stream | Any kind of binary data | .bin |
text/plain | Text, (generally ASCII or ISO 8859-n) | .txt |
<Images> |
||
image/bmp | Windows OS/2 Bitmap Graphics | .bmp |
image/jpeg | JPEG images | .jpeg .jpg |
image/png | Portable Network Graphics | .png |
image/gif | Graphics Interchange Format (GIF) | .gif |
image/vnd.microsoft.icon | Icon format | .ico |
image/svg+xml | Scalable Vector Graphics (SVG) | .svg |
<media> |
||
audio/mpeg | MP3 audio | .mp3 |
video/mp4 | MP4 video | .mp4 |
<code> |
||
text/css | Cascading Style Sheets (CSS) | .css |
text/csv | Comma-separated values (CSV) | .csv |
application/json | JSON format | .json |
text/javascript | JavaScript, JavaScript module | .js .mjs |
text/html | HyperText Markup Language (HTML) | .htm .html |
<doc> |
||
application/msword | Microsoft Word | .doc |
application/vnd.openxmlformats-officedocument.wordprocessingml.document | Microsoft Word (OpenXML) | .docx |
application/pdf | Adobe Portable Document Format (PDF) | |
<archive> |
||
application/gzip | GZip Compressed Archive | .gz |
application/vnd.rar | RAR archive | .rar |
application/x-tar | Tape Archive (TAR) | .tar |
application/zip | ZIP archive | .zip |
application/x-7z-compressed | 7-zip archive | .7z |
Two primary MIME types are important for the role of default types:
text/plain
is the default value for textual files. A textual file should be human-readable and must not contain binary data.application/octet-stream
is the default value for all other cases. An unknown file type should use this type. Browsers pay a particular care when manipulating these files, attempting to safeguard the user to prevent dangerous behaviors.