Nearly 8000 words of Spring common annotation summary, 80% of people do not know

0. Preface

Hello, I'm brother Guide! This is my 221 excellent original articles. If you need to reprint, please indicate the address at the beginning of the article, crab!

This article has been included in my open source Java project JavaGuide of 75K Star: github.com/Snailclimb/... Related reading: Version 2.0 of "JavaGuide interview shock edition" is coming! Come with its online reading version!

It's no exaggeration to say that the Spring/SpringBoot common annotations introduced in this article basically cover most of the common scenarios you encounter in your work. For each annotation, I have said the specific usage, master and understand. There is no big problem in using spring boot to develop projects!

Why write this article?

Recently, I saw that there are many articles about spring boot common annotations reprinted on the Internet. After reading the contents of the articles, I really think that the quality is a little low, and it will mislead people who don't have much practical experience (these people occupy the majority). So, I spent about two days simply summarizing.
Here also note: breaking through the experience of high paid Java architecture projects is always the core. If you don't have the latest Java architecture practical course and the big factory 30k + interview book, you can go to the small-scale Java architecture learning. Skirt: you can find it under the transformation of seven bar umbrella and zero clothing umbrella (Digital homophony). There are many new Java architecture project courses in it, and you can also exchange with the old driver for advice!  

Because my personal ability and energy are limited, if there is anything wrong or need to be improved, please help to point out! Brother Guide, thank you very much!

1. @SpringBootApplication

Here I'll introduce @ SpringBootApplication separately, although we usually don't take the initiative to use it.

Guide: this annotation is the cornerstone of the Spring Boot project. After the Spring Boot project is created, it will be added to the main class by default.

@SpringBootApplication
public class SpringSecurityJwtGuideApplication {
      public static void main(java.lang.String[] args) {
        SpringApplication.run(SpringSecurityJwtGuideApplication.class, args);
    }
}
Copy code

We can think of @ SpringBootApplication as a collection of @ Configuration, @ EnableAutoConfiguration, @ ComponentScan annotations.

package org.springframework.boot.autoconfigure;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
  @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
  @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
   ......
}

package org.springframework.boot;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {

}
Copy code

According to the SpringBoot official website, the functions of these three annotations are as follows:

  • @Enable autoconfiguration: enable the autoconfiguration mechanism of SpringBoot
  • @ComponentScan: scan the bean annotated by @ Component (@ Service,@Controller). The annotation will scan all classes under the package where the class is located by default.
  • @Configuration: allows additional bean s to be registered or other configuration classes to be imported in the Spring context

2. Spring Bean related

2.1. @Autowired

Automatically import objects into classes. The injected classes are also managed by Spring containers. For example, Service classes are injected into Controller classes.

@Service
public class UserService {
  ......
}

@RestController
@RequestMapping("/users")
public class UserController {
   @Autowired
   private UserService userService;
   ......
}
Copy code

2.2. Component,@Repository,@Service, @Controller

We usually use @ Autowired annotation to let Spring container help us automatically assemble beans. To identify the class as a class that can be used for @ Autowired annotation to automatically assemble beans, the following annotation can be used:

  • @Component: a general annotation that can mark any class as a Spring component. If a Bean does not know which layer it belongs to, it can be annotated with @ Component annotation.
  • @Repository: the corresponding persistence layer, namely Dao layer, is mainly used for database related operations.
  • @Service: the corresponding service layer, mainly involving some complex logic, needs to use the Dao layer.
  • @Controller: corresponding to the Spring MVC control layer, the main user accepts the user request and calls the Service layer to return the data to the front-end page.

2.3. @RestController

@The RestController annotation is a collection of @ Controller and @ ResponseBody, indicating that this is a Controller bean, and the return value of the function is directly filled into the HTTP response body, which is a REST style Controller.

Guide brother: now it's all front and back end separation. To be honest, I haven't used @ Controller for a long time. If your project is too old, think I didn't say it.

When @ controller is used alone without @ ResponseBody, it is generally used when a view is to be returned. This is a more traditional Spring MVC application, which corresponds to the situation where the front and back ends are not separated. @Controller + @ ResponseBody returns JSON or XML data

For a comparison between @ RestController and @ Controller, see this article: @RestController vs @Controller.

2.4. @Scope

Declare the scope of Spring Bean using the following methods:

@Bean
@Scope("singleton")
public Person personSingleton() {
    return new Person();
}
Copy code

The scope of four common spring beans:

  • Singleton: the only bean instance. By default, all beans in Spring are singleton.
  • prototype: each request creates a new bean instance.
  • Request: each HTTP request will generate a new bean, which is only valid in the current HTTP request.
  • Session: each HTTP request will generate a new bean, which is only valid in the current HTTP session.

2.5. Configuration

It is generally used to declare Configuration classes, and can be replaced by @ Component annotation, but it is more semantic to use Configuration annotation to declare Configuration classes.

@Configuration
public class AppConfig {
    @Bean
    public TransferService transferService() {
        return new TransferServiceImpl();
    }

}
Copy code

3. Handle common HTTP request types

Five common request types:

  • GET: requests to GET a specific resource from the server. For example: GET /users
  • POST: create a new resource on the server. For example: POST /users (create students)
  • PUT: update the resources on the server (the client provides the whole updated resources). For example: PUT /users/12 (update student number 12)
  • DELETE: deletes a specific resource from the server. For example: DELETE /users/12
  • PATCH: update the resources on the server (the client provides the changed attributes, which can be seen as part of the update). The usage is relatively small. Here is no example.

3.1. GET request

@GetMapping("users") is equivalent to @ RequestMapping(value="/users",method=RequestMethod.GET)

@GetMapping("/users")
public ResponseEntity<List<User>> getAllUsers() {
 return userRepository.findAll();
}
Copy code

3.2. POST request

@PostMapping("users") is equivalent to @ RequestMapping(value="/users",method=RequestMethod.POST)

About the use of @ RequestBody annotation, we will talk about it in the "pass value before and after" section below.

@PostMapping("/users")
public ResponseEntity<User> createUser(@Valid @RequestBody UserCreateRequest userCreateRequest) {
 return userRespository.save(user);
}
Copy code

3.3. PUT request

@PutMapping("/users/{userId}") is equivalent to @ RequestMapping(value="/users/{userId}",method=RequestMethod.PUT)

@PutMapping("/users/{userId}")
public ResponseEntity<User> updateUser(@PathVariable(value = "userId") Long userId,
  @Valid @RequestBody UserUpdateRequest userUpdateRequest) {
  ......
}
Copy code

3.4. DELETE request

@DeleteMapping("/users/{userId}") is equivalent to @ RequestMapping(value="/users/{userId}",method=RequestMethod.DELETE)

@DeleteMapping("/users/{userId}")
public ResponseEntity deleteUser(@PathVariable(value = "userId") Long userId){
  ......
}
Copy code

3.5. PATCH request

In general, in actual projects, we use PATCH request to update data only when PUT is not enough.

  @PatchMapping("/profile")
  public ResponseEntity updateStudent(@RequestBody StudentUpdateRequest studentUpdateRequest) {
        studentRepository.updateDetail(studentUpdateRequest);
        return ResponseEntity.ok().build();
    }
Copy code

4. Front and rear end transmission value

Mastering the correct posture of front and back end transmission is the first step for you to start CRUD!

4.1. @ PathVariable and @ RequestParam

@PathVariable is used to get the path parameter, @ RequestParam is used to get the query parameter.

Take a simple example:

@GetMapping("/klasses/{klassId}/teachers")
public List<Teacher> getKlassRelatedTeachers(
         @PathVariable("klassId") Long klassId,
         @RequestParam(value = "type", required = false) String type ) {
...
}
Copy code

If the url we requested is: / klasses/{123456}/teachers?type=web

Then the data obtained by our service is: klassId=123456,type=web.

4.2. @RequestBody

It is used to read the body part of the Request (maybe POST,PUT,DELETE,GET Request) and the data with the content type of application/json format. After receiving the data, it will automatically bind the data to the Java object. The system will use HttpMessageConverter or custom HttpMessageConverter to convert json strings in the requested body into Java objects.

I use a simple example to demonstrate the basic use!

We have a registered interface:

@PostMapping("/sign-up")
public ResponseEntity signUp(@RequestBody @Valid UserRegisterRequest userRegisterRequest) {
  userService.save(userRegisterRequest);
  return ResponseEntity.ok().build();
}
Copy code

UserRegisterRequest object:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserRegisterRequest {
    @NotBlank
    private String userName;
    @NotBlank
    private String password;
    @FullName
    @NotBlank
    private String fullName;
}
Copy code

We send a post request to this interface, and the body carries JSON data:

{"userName":"coder","fullName":"shuangkou","password":"123456"}
Copy code

In this way, our backend can directly map the json format data to our UserRegisterRequest class.

A kind of Note: a request method can only have one @ RequestBody, but it can have multiple @ RequestParam and @ PathVariable. If your method has to use two @ requestbodies to accept data, maybe your database design or system design is out of order!

5. Read configuration information

In many cases, we need to put some common configuration information, such as Alibaba cloud oss, SMS, wechat authentication and so on, into the configuration file.

Let's take a look at how Spring can help us read the configuration information from the configuration file.

Our data source application.yml is as follows:

wuhan2020: novel coronavirus broke out in Wuhan in early 2020, and the epidemic was serious. But I believe everything will be over. Come on, Wuhan! Go China!

my-profile:
name: Guide brother
  email: koushuangbwcx@163.com

library:
location: Wuhan, Hubei, China
  books:
- name: Basic Law of genius
description: on the day when her father diagnosed Alzheimer's disease, Lin Chaoxi, 22, learned that Pei Zhi, the campus God he had been secretly in love with for many years, was about to go abroad for further education. The school that the other side admitted was the one that her father gave up for her.
- name: time order
description: why do we remember the past, not the future? What does time "pass" mean? Are we in time, or is time in us? Carlo Lowe uses poetic words to invite us to think about the essence of time.
- name: Amazing me
description: how to form a new habit? How to make the mind more mature? How to have a high quality relationship? How to get out of the difficult time of life?
Copy code

5.1 @ value (common)

Use @ Value("${property}") to read simpler configuration information:

@Value("${wuhan2020}")
String wuhan2020;
Copy code

5.2 @ configurationproperties (common)

Read the configuration information through @ ConfigurationProperties and bind to the bean.

@Component
@ConfigurationProperties(prefix = "library")
class LibraryProperties {
    @NotEmpty
    private String location;
    private List<Book> books;

    @Setter
    @Getter
    @ToString
    static class Book {
        String name;
        String description;
    }
  ellipsis getter/setter
  ......
}
Copy code

You can inject it into a class just as you would with a normal Spring bean.

5.3. PropertySource (not commonly used)

@PropertySource reads the specified properties file

@Component
@PropertySource("classpath:website.properties")

class WebSite {
    @Value("${url}")
    private String url;

  ellipsis getter/setter
  ......
}
Copy code

For more information, see this article:< How to read the configuration file gracefully in 10 minutes?> .

6. Parameter verification

The importance of data verification is needless to say. Even in the case of front-end data verification, we still need to verify the data passed into the back-end again to avoid users bypassing the browser and directly requesting some illegal data from the back-end through some HTTP tools.

JSR(Java Specification Requests) is a set of JavaBean parameter verification standards. It defines many commonly used verification annotations. We can directly add these annotations to the properties of our JavaBean, so that we can verify when we need to verify, which is very convenient!

During the verification, we actually use the Hibernate Validator framework. Hibernate Validator is the original data validation framework of Hibernate team, Hibernate Validator 4.x is the reference implementation of Bean Validation 1.0 (JSR 303), Hibernate Validator 5.x is the reference implementation of Bean Validation 1.1 (JSR 349), and the latest version of Hibernate Validator 6.x is the reference implementation of Bean Validation 2.0 (JSR 380).

The hibernate validator package already exists in the spring boot starter web dependency of the spring boot project, so there is no need to reference the dependency. As shown in the following figure (generated through the idea plug-in Maven Helper):

Non spring boot projects need to introduce their own dependent packages. I will not explain them here. For details, please refer to my article:< How to do parameter verification in Spring/Spring Boot? All you need to know is here!>.

A kind of Note: for all annotations, it is recommended to use JSR annotation, namely javax.validation.constraints instead of org.hibernate.validator.constraints

6.1. Notes on some common field validation

  • @NotEmpty of the commented string cannot be null or empty
  • @NotBlank the commented string is not null and must contain a non blank character
  • @Null the annotated element must be null
  • @NotNull the annotated element must not be null
  • @AssertTrue the annotated element must be true
  • @AssertFalse the annotated element must be false
  • @Pattern(regex=,flag =) the annotated element must conform to the specified regular expression
  • @Email the annotated element must be in email format.
  • @Min(value) the annotated element must be a number whose value must be greater than or equal to the specified minimum value
  • @Max(value) the annotated element must be a number whose value must be less than or equal to the specified maximum value
  • @DecimalMin(value) the annotated element must be a number whose value must be greater than or equal to the specified minimum value
  • @DecimalMax(value) the annotated element must be a number whose value must be less than or equal to the specified maximum value
  • @Size(max=, min =) the size of the annotated element must be within the specified range
  • @The annotated element of Digits (integer, fraction) must be a number, and its value must be within the acceptable range
  • @The element that paste is annotated must be a date in the Past
  • @Future the annotated element must be a future date
  • ......

6.2. Request body

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {

    @NotNull(message = "classId Cannot be empty")
    private String classId;

    @Size(max = 33)
    @NotNull(message = "name Cannot be empty")
    private String name;

    @Pattern(regexp = "((^Man$|^Woman$|^UGM$))", message = "sex Value not in optional range")
    @NotNull(message = "sex Cannot be empty")
    private String sex;

    @Email(message = "email Incorrect format")
    @NotNull(message = "email Cannot be empty")
    private String email;

}
Copy code

We added @ Valid annotation to the parameters to be verified. If the verification fails, it will throw MethodArgumentNotValidException.

@RestController
@RequestMapping("/api")
public class PersonController {

    @PostMapping("/person")
    public ResponseEntity<Person> getPerson(@RequestBody @Valid Person person) {
        return ResponseEntity.ok().body(person);
    }
}
Copy code

6.3. Verify request parameters (Path Variables and Request Parameters)

Be sure not to forget to add the "Validated" annotation to the class. This parameter can tell Spring to verify the method parameters.

@RestController
@RequestMapping("/api")
@Validated
public class PersonController {

    @GetMapping("/person/{id}")
    public ResponseEntity<Integer> getPersonByID(@Valid @PathVariable("id") @Max(value = 5,message = "Exceed id The scope of") Integer id) {
        return ResponseEntity.ok().body(id);
    }
}
Copy code

For more information on how to verify parameters in Spring projects, see< How to do parameter verification in Spring/Spring Boot? All you need to know is here! >This article.

7. Global handling of Controller layer exceptions

Introduce the global handling of Controller layer exceptions necessary for our Spring project.

Related notes:

  1. @ControllerAdvice: annotation defines global exception handling class
  2. @ExceptionHandler: annotation declaration exception handling method

How to use it? Take our parameter verification in Section 5 for example. If the method parameter is wrong, MethodArgumentNotValidException will be thrown. Let's handle this exception.

@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

    /**
     * Request parameter exception handling
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, HttpServletRequest request) {
       ......
    }
}
Copy code

For more information on Spring Boot exception handling, please refer to my two articles:

  1. Several common postures of spring boot handling exceptions
  2. Simply encapsulate an elegant Spring Boot global exception handling with enumeration!

8. JPA related

8.1. Create table

@Entity declares that a class corresponds to a database entity.

@Table settings indicate

@Entity
@Table(name = "role")
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String description;
    ellipsis getter/setter......
}
Copy code

8.2. Create primary key

@Id: declare a field as the primary key.

After using @ Id declaration, we also need to define the primary key generation policy. We can use @ GeneratedValue to specify the primary key generation policy.

1. Use @ GeneratedValue directly to specify the primary key generation policy by using the four primary key generation policies provided by JPA.

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Copy code

JPA uses enumeration to define the common primary key generation strategies in 4, as follows:

Guige: a use of enumerating substitution constants

public enum GenerationType {

    /**
* use a specific database table to save the primary key
* the persistence engine generates the primary key through a specific table in the relational database,
     */
    TABLE,

    /**
* in some databases, self growth of primary key is not supported. For example, Oracle and PostgreSQL provide a mechanism called "sequence" to generate primary key
     */
    SEQUENCE,

    /**
* primary key self growth
     */
    IDENTITY,

    /**
* give the primary key generation policy to the persistence engine,
* the persistence engine will select one of the above three primary key generation strategies based on the database
     */
    AUTO
}

Copy code

@The default policy used by the generated value annotation is GenerationType.AUTO

public @interface GeneratedValue {

    GenerationType strategy() default AUTO;
    String generator() default "";
}
Copy code

Generally speaking, when using MySQL database, the GenerationType.IDENTITY strategy is more common (for distributed system, distributed ID needs to be considered additionally).

2. Declare a primary key policy through @ GenericGenerator, and then @ GeneratedValue uses this policy

@Id
@GeneratedValue(generator = "IdentityIdGenerator")
@GenericGenerator(name = "IdentityIdGenerator", strategy = "identity")
private Long id;
Copy code

Equivalent to:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Copy code

The primary key generation strategies provided by jpa are as follows:

public class DefaultIdentifierGeneratorFactory
  implements MutableIdentifierGeneratorFactory, Serializable, ServiceRegistryAwareService {

 @SuppressWarnings("deprecation")
 public DefaultIdentifierGeneratorFactory() {
  register( "uuid2", UUIDGenerator.class );
  register( "guid", GUIDGenerator.class );   // can be done with UUIDGenerator + strategy
  register( "uuid", UUIDHexGenerator.class );   // "deprecated" for new use
  register( "uuid.hex", UUIDHexGenerator.class );  // uuid.hex is deprecated
  register( "assigned", Assigned.class );
  register( "identity", IdentityGenerator.class );
  register( "select", SelectGenerator.class );
  register( "sequence", SequenceStyleGenerator.class );
  register( "seqhilo", SequenceHiLoGenerator.class );
  register( "increment", IncrementGenerator.class );
  register( "foreign", ForeignGenerator.class );
  register( "sequence-identity", SequenceIdentityGenerator.class );
  register( "enhanced-sequence", SequenceStyleGenerator.class );
  register( "enhanced-table", TableGenerator.class );
 }

 public void register(String strategy, Class generatorClass) {
  LOG.debugf( "Registering IdentifierGenerator strategy [%s] -> [%s]", strategy, generatorClass.getName() );
  final Class previous = generatorStrategyToClassNameMap.put( strategy, generatorClass );
  if ( previous != null ) {
   LOG.debugf( "    - overriding [%s]", previous.getName() );
  }
 }

}
Copy code

8.3. Set field type

@Column declares the field.

Example:

Set the database field name corresponding to the attribute userName as user name, with a length of 32 and non empty

@Column(name = "user_name", nullable = false, length=32)
private String userName;
Copy code

It is quite common to set the field type and add the default value.

Column(columnDefinition = "tinyint(1) default 1")
private Boolean enabled;
Copy code

8.4. Specify not to persist specific fields

@Transient: declare the fields that do not need to be mapped with the database, and do not need to be saved into the database when saving.

If we want the secrect field not to be persisted, we can declare it with the @ Transient keyword.

Entity(name="USER")
public class User {

    ......
    @Transient
    private String secrect; // not persistent because of @Transient

}
Copy code

In addition to the @ Transient keyword declaration, you can also use the following methods:

static String secrect; // not persistent because of static
final String secrect = "Satish"; // not persistent because of final
transient String secrect; // not persistent because of transient
Copy code

Generally, there are many ways to use annotations.

8.5. Declaration of large fields

@Lob: declare a field as a large field.

@Lob
private String content;
Copy code

More detailed statement:

@Lob
//Specify the acquisition strategy of Lob type data. FetchType.eagle indicates non delayed loading, while FetchType. LAZY indicates delayed loading;
@Basic(fetch = FetchType.EAGER)
//The columnDefinition property specifies the Lob field type corresponding to the data table
@Column(name = "content", columnDefinition = "LONGTEXT NOT NULL")
private String content;
Copy code

8.6. Create field of enumeration type

You can use fields of enumeration type, but enumeration fields need to be decorated with @ Enumerated annotation.

public enum Gender {
    MALE("Male"),
    FEMALE("Female sex");

    private String value;
    Gender(String str){
        value=str;
    }
}
Copy code
@Entity
@Table(name = "role")
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String description;
    @Enumerated(EnumType.STRING)
    private Gender gender;
    ellipsis getter/setter......
}
Copy code

The corresponding storage in the database is MAIL/FEMAIL.

8.7. Add audit function

As long as the class inherits AbstractAuditBase, the following four fields will be added by default.

@Data
@AllArgsConstructor
@NoArgsConstructor
@MappedSuperclass
@EntityListeners(value = AuditingEntityListener.class)
public abstract class AbstractAuditBase {

    @CreatedDate
    @Column(updatable = false)
    @JsonIgnore
    private Instant createdAt;

    @LastModifiedDate
    @JsonIgnore
    private Instant updatedAt;

    @CreatedBy
    @Column(updatable = false)
    @JsonIgnore
    private String createdBy;

    @LastModifiedBy
    @JsonIgnore
    private String updatedBy;
}

Copy code

The corresponding configuration class of our audit function may be as follows (Spring Security project):


@Configuration
@EnableJpaAuditing
public class AuditSecurityConfiguration {
    @Bean
    AuditorAware<String> auditorAware() {
        return () -> Optional.ofNullable(SecurityContextHolder.getContext())
                .map(SecurityContext::getAuthentication)
                .filter(Authentication::isAuthenticated)
                .map(Authentication::getName);
    }
}
Copy code

Briefly introduce some notes designed above:

  1. @CreatedDate: indicates that this field is a creation time field. When this entity is insert ed, the value will be set

  2. @CreatedBy: indicates that the field is created by. When the entity is insert ed, the value will be set

    @LastModifiedDate, @ LastModifiedBy are the same.

@Enable JPA Auditing: enable JPA auditing.

8.8. Delete / modify data

@The Modifying annotation prompts JPA that this operation is a modification operation, and it should be used in conjunction with the @ Transactional annotation.

@Repository
public interface UserRepository extends JpaRepository<User, Integer> {

    @Modifying
    @Transactional(rollbackFor = Exception.class)
    void deleteByUserName(String userName);
}
Copy code

8.9. Relationship

  • @OneToOne declares a one-to-one relationship
  • @OneToMany declares a one to many relationship
  • @ManyToOne declares many to one relationship
  • MangToMang declares many to many relationships

For more articles about Spring Boot JPA, see my article: Understand how to use JPA correctly in Spring Boot .

9. Transaction

Just use @ Transactional annotation on the method to open the transaction!

@Transactional(rollbackFor = Exception.class)
public void save() {
  ......
}

Copy code

We know that exceptions are divided into runtime exceptions and non runtime exceptions. In the @ Transactional annotation, if the rollbackFor attribute is not configured, things will only roll back when they encounter a RuntimeException. With rollbackFor=Exception.class, things can also roll back when they encounter non runtime exceptions.

@Transactional annotations are generally used to act on classes or methods.

  • For class: when the @ Transactional annotation is placed on the class, it means that all public methods of the class are configured with the same transaction attribute information.
  • Action on method: when the class is configured with @ Transactional and the method is configured with @ Transactional, the transaction of the method will overwrite the transaction configuration information of the class.

For more information about Spring transactions, see:

  1. Probably the most beautiful detailed explanation of Spring transaction management
  2. Say six @ Transactional annotation failure scenarios in one breath

10. json data processing

10.1. Filtering json data

@JsonIgnoreProperties is used on classes to filter out specific fields that are not returned or parsed.

//Filter the userRoles property when generating json
@JsonIgnoreProperties({"userRoles"})
public class User {

    private String userName;
    private String fullName;
    private String password;
    @JsonIgnore
    private List<UserRole> userRoles = new ArrayList<>();
}
Copy code

@JsonIgnore is generally used for the properties of a class. It has the same effect as @ JsonIgnoreProperties above.


public class User {

    private String userName;
    private String fullName;
    private String password;
   //Filter the userRoles property when generating json
    @JsonIgnore
    private List<UserRole> userRoles = new ArrayList<>();
}
Copy code

10.2. Format json data

@JsonFormat is generally used to format json data. :

For example:

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone="GMT")
private Date date;
Copy code

10.3. Flattening objects

@Getter
@Setter
@ToString
public class Account {
    @JsonUnwrapped
    private Location location;
    @JsonUnwrapped
    private PersonInfo personInfo;

  @Getter
  @Setter
  @ToString
  public static class Location {
     private String provinceName;
     private String countyName;
  }
  @Getter
  @Setter
  @ToString
  public static class PersonInfo {
    private String userName;
    private String fullName;
  }
}

Copy code

Before flattening:

{
    "location": {
        "provinceName":"Hubei",
        "countyName":"Wuhan"
    },
    "personInfo": {
        "userName": "coder1234",
        "fullName": "shaungkou"
    }
}
Copy code

After using the @ JsonUnwrapped flat object:

@Getter
@Setter
@ToString
public class Account {
    @JsonUnwrapped
    private Location location;
    @JsonUnwrapped
    private PersonInfo personInfo;
    ......
}
Copy code
{
"provinceName": "Hubei",
"countyName": "Wuhan",
  "userName": "coder1234",
  "fullName": "shaungkou"
}
Copy code

11. Test related

@ActiveProfiles are generally used on test classes to declare valid Spring configuration files.

@SpringBootTest(webEnvironment = RANDOM_PORT)
@ActiveProfiles("test")
@Slf4j
public abstract class TestBase {
  ......
}
Copy code

@Test declares a method as a test method

@The data of the declared test method of Transactional will be rolled back to avoid polluting the test data.

@Provided by WithMockUser Spring Security to simulate a real user and grant permissions.

    @Test
    @Transactional
    @WithMockUser(username = "user-id-18163138155", authorities = "ROLE_TEACHER")
    void should_import_student_success() throws Exception {
        ......
    }

Summary note: breaking through the experience of high salary Java architecture project is always the core. If you don't have the latest Java architecture practical course and the big factory 30k + interview treasure book, you can go to the small-scale Java architecture learning. Skirt: under the transformation of seven bar umbrella and Zero clothing umbrella (Digital homophony), you can find many new Java architecture project tutorials, and you can also exchange with the old driver for advice!  

The text and pictures of this article come from the Internet and my own ideas. They are only for learning and communication. They have no commercial use. The copyright belongs to the original author. If you have any questions, please contact us in time for handling

Tags: Java Spring JSON Database

Posted on Thu, 07 May 2020 00:57:27 -0700 by Lorik