Use AWS SDK for Java 2.0,Set S3 object public access

Region region = Region.AP_SOUTHEAST_1;
        s3 = S3Client.builder().region(region).build();
        

        String bucket = "your bucket name";// "bucket" + System.currentTimeMillis();
        String key = "your file name";
	    
        //create bucket if it is not exist
        createBucket(bucket, region);

        // Put Object
        PutObjectRequest request = PutObjectRequest.builder().bucket(bucket).key(key).build();
        s3.putObject(request,RequestBody.fromByteBuffer(getRandomByteBuffer(10_000)));
 
        //set public acl
        PutObjectAclRequest putAclReq = PutObjectAclRequest.builder()
        		.bucket(bucket)
        		.key(key)
        		.acl(ObjectCannedACL.PUBLIC_READ)
        		//.accessControlPolicy(acl)
        		.build();
        s3.putObjectAcl(putAclReq);
        
	//set email acl
	 // get the current ACL
        	GetObjectAclRequest objectAclReq = GetObjectAclRequest.builder()
            		.bucket(bucket_name)
            		.key(object_key)
            		.build();
		String email = "your email adress";
        	GetObjectAclResponse getAclRes = s3.getObjectAcl(objectAclReq);
            Grantee grantee = Grantee.builder().emailAddress(email).build();
            Permission permission = Permission.valueOf(Permission.Read);
            List<Grant> grants = getAclRes.grants();
            Grant newGrantee = Grant.builder()
            		.grantee(grantee)
            		.permission(permission)
            		.build();
            grants.add(newGrantee);

            //put the new acl
            AccessControlPolicy acl = AccessControlPolicy.builder()
            		.grants(grants)
            		.build();
            PutObjectAclRequest putAclReq = PutObjectAclRequest.builder()
            		.bucket(bucket_name)
            		.key(object_key)
            		.accessControlPolicy(acl)
            		.build();
            s3.putObjectAcl(putAclReq);

IOS enterprise app application installation and https certificate generation

In addition to being able to publish on the Appstore, the IOS application can also apply for a corporate certificate and deploy the server to publish and provide downloads. However, after the enterprise certificate is in IOS 7.1, the application download needs to use the trusted https release to download normally. Otherwise, Prompt that an error such as a server could not be found;

First, developers need to package an ipa, and provide a plist file, the plist file can refer to the following:

Plist file (test.plist):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>items</key>
<array>
<dict>
<key>assets</key>
<array>
<dict>
<key>kind</key>
<string>software-package</string>
<key>url</key>
<string>https://192.168.0.8/test.ipa</string>
</dict>
</array>
<key>metadata</key>
<dict>
<key>bundle-identifier</key>
<string>com.test</string>
<key>bundle-version</key>
<string>1.0</string>
<key>kind</key>
<string>software</string>
<key>title</key>
<string>test</string>
</dict>
</dict>
</array>
</dict>
</plist>
Create a new page, assuming index.html, as follows:
<script>
Location.href="itms-services:///?action=download-manifest&url=https://192.168.0.8/test.plist";
</script>

OR

<a href="itms-services:///?action=download-manifest&url=https://192.168.0.8/test.plist">Click to download</a>
 Visit: https://192.168.0.8/test.html (open with safari)

Note: The value of the url in the plist file may not be https, but in the page, the url parameter after the items-services protocol must be https, and must be trusted https, that is, if you apply for a certificate from an authority, directly If you configure it on the server, you can trust it. Otherwise, the certificate generated by the client must be installed with the ca certificate to be trusted. In addition, remember to remind the user that it can only be downloaded in the safari browser. Other browsers do not recognize the itms-services protocol.

If you need to download the LAN, you can only generate the certificate yourself. The steps are as follows:

1.Generate the private key of the server

Openssl genrsa -out server.key 1024

2.Generate a signing application (note that it can be empty except for Common Name, Common Name must be the server’s ip or domain name)

Openssl req -new -key server.key -out server.csr

3.Generate CA private key

Openssl genrsa -out ca.key 1024

4.Use the CA’s private key to generate a self-signed certificate for the CA

Openssl req -new -x509 -days 365 -key ca.key -out ca.crt

5.Create a demoCA in the current directory, which creates the file index.txt and serial, the serial content is 01, the index.txt is empty, and the folder newcerts

Openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key

Thus, the generated file has server.crt, server.key, ca.crt

Configure server.crt, server.key to the server, apache, nginx are different, Baidu, a lot of configuration instructions, here will not repeat; in addition, ca.crt into the service root directory, so that users can Access installation

After the server configures the certificate and restarts the service, you can access https://192.168.0.8/test.html at this time, but it is still not fully credited. The client must install ca.crt to download normally. Guide the client to access http. ://192.168.0.8/ca.crt, safari will directly jump to the certificate installation interface. After the certificate is installed, it can be downloaded normally through https://192.168.0.8/test.html.

jstl JasperException error

Today, my jsp project has an error. I checked it for a long time before I solved this error.The solution is as follows.

1,Error Description
org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application

2,Solution
Copy all the tld files from the META-INF directory in the jstl.jar package and put them into the WEB-INF under the jsp project.

You can create a tlds directory under WEB-INF/, put all the tld files into this directory, the directory name can be arbitrarily named

Mybatis annotation application mapping statement

MyBatis provides a variety of annotation mappings such as SELECT, UPDATE, INSERT, and DELETE. Let me take a closer look at the application of these mappings.

1.@Insert
We can use the @Insert annotation to declare an INSERT mapping.

Package com.owen.mybatis.mappers;
Public interface StudentMapper
{
@Insert(“INSERT INTO STUDENTS(STUD_ID, NAME, EMAIL, ADDR_ID, PHONE)
VALUES(#{studId},#{name},#{email},#{address.addrId},#{phone})”)
Int insertStudent(Student student);
}
In the insertStudent() method, we annotated @Insert, which will return the number of affected rows through the declaration of the insert.

When we used the xml file earlier, we declared the statement that automatically generated the primary key. In this annotation method, we can also use the @Options method to annotate the declaration to generate the primary key. This method contains the parameters of useGeneratedKeys and keyProperty. These two parameters are for the data to form the column value of auto_increment, the value of which is the column of an object in the existing column as the value.

@Insert(“INSERT INTO STUDENTS(NAME,EMAIL,ADDR_ID, PHONE)
VALUES(#{name},#{email},#{address.addrId},#{phone})”)
@Options(useGeneratedKeys=true, keyProperty=”studId”)
Int insertStudent(Student student);
The column of STUD_ID here will be automatically generated by the MYSQL database, and its value will be the same as the value of studId.

StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
mapper.insertStudent(student);
Int studentId = student.getStudId();
Some databases, such as Oracle can not provide the AUTO_INCREMENT column and we need to use SEQUENCE to form the primary key. We can use the @Selectkey annotation to specify any SQL declaration, and it can be used as the value of the primary key.

@Insert(“INSERT INTO STUDENTS(STUD_ID, NAME, EMAIL, ADDR_ID, PHONE)
VALUES(#{studId},#{name},#{email},#{address.addrId},#{phone})”)
@SelectKey(statement=”SELECT STUD_ID_SEQ.NEXTVAL FROM DUAL”,
keyProperty=”studId”, resultType=int.class, before=true)
Int insertStudent(Student student);
Here we apply @SelectKey to generate the value of the primary key and save it in the attribute of the student’s studId. Because we defined before=true, the primary key was already generated when it was inserted.

If you use the trigger of SEQUENCE to generate the primary key, we can get the primary key from sequence_name.currval and then execute the insert statement.

 @Insert(“INSERT INTO STUDENTS(NAME,EMAIL,ADDR_ID, PHONE)
VALUES(#{name},#{email},#{address.addrId},#{phone})”)
@SelectKey(statement=”SELECT STUD_ID_SEQ.CURRVAL FROM DUAL”,
keyProperty=”studId”, resultType=int.class, before=false)
Int insertStudent(Student student);

2.@Update
We can use the @Update annotation to declare an UPDATE.

@Update(“UPDATE STUDENTS SET NAME=#{name}, EMAIL=#{email},
PHONE=#{phone} WHERE STUD_ID=#{studId}”)
Int updateStudent(Student student);
In the updateStudent() method, we used the @Update annotation and will return the affected rows.

StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Int noOfRowsUpdated = mapper.updateStudent(student);

3.@Delete
We can use @Delete to implement the declaration of DELETE.

@Delete(“DELETE FROM STUDENTS WHERE STUD_ID=#{studId}”)
Int deleteStudent(int studId);
The method of deleteStudent() will return the affected row.

4.@Select
We can use the @Select annotation to implement the SELECT mapping.

 Package com.owen.mybatis.mappers;
Public interface StudentMapper
{
@Select(“SELECT STUD_ID AS STUDID, NAME, EMAIL, PHONE FROM
STUDENTS WHERE STUD_ID=#{studId}”)
Student findStudentById(Integer studId);
}
To match the instance of the Student object, we use studId as an alias for stud_id. How to return a value with multiple rows will report a TooManyResultException error.