spring Boot common annotations

Reprint: https://segmentfault.com/a/1190000022521844

0. Preface

Hello, I'm brother! This is my 221 high-quality original articles. If you need to reprint, please indicate the address at the beginning of the text, crab!

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

It is no exaggeration to say that the common Spring/SpringBoot annotations introduced in this article have basically covered most common scenarios you encounter in your work. For each annotation, I have explained the specific usage and understood it. There is basically no big problem using SpringBoot to develop the project!

The whole directory is as follows, with a little more content:

Why write this article?

Recently, I saw an article on common annotations of SpringBoot on the Internet, which was reprinted more. After reading the content of the article, I found that the quality was a little low, and it would mislead people who did not have much practical experience (these people accounted for the majority). Therefore, I simply spent about two days to briefly summarize it.

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

1. @SpringBootApplication

Here's a separate @ SpringBootApplication note to explain, although we generally don't take the initiative to use it.

Brother Guide: this annotation is the cornerstone of the Spring Boot project. After creating the Spring Boot project, 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);
    }
}

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 {

}

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

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

2. Spring Bean related

2.1. @Autowired

Automatically import objects into classes. The injected classes should also be managed by the Spring container. For example, the Service class should be injected into the Controller class.

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

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

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

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

  • @Component: a general annotation that can label 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: corresponding to the service layer, which mainly involves some complex logic, and the Dao layer is required.
  • @Controller: corresponding to the Spring MVC control layer, the main user accepts the user request and calls the Service layer to return data to the front-end page.

2.3. @RestController

@The RestController annotation is a collection of @ Controller and @ ResponseBody, which indicates that it is a Controller bean and directly fills the return value of the function into the HTTP response body. It is a REST style Controller.

Brother Guide: now the front and rear ends are separated. To be honest, I haven't used @ Controller for a long time. If your project is too old, treat it as if I didn't say it.

If you use @ controller without @ ResponseBody alone, it is generally used when you want to return a view. This is a traditional Spring MVC application, which corresponds to the case where the front and back ends are not separated@ Controller + @ ResponseBody returns data in JSON or XML

For the comparison between @ RestController} and @ Controller, please see this article: @RestController vs @Controller.

2.4. @Scope

Declare the scope of Spring Bean, using the following method:

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

Four common scopes of spring beans:

  • Singleton: unique bean instance. All beans in Spring are singleton by default.
  • 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, which can be replaced by @ Component annotation. However, using Configuration annotation to declare Configuration classes is more semantic.

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

}

3. Handle common HTTP request types

5 common request types:

  • GET: request to GET a specific resource from the server. For example: GET /users
  • POST: create a new resource on the server. For example: POST /users
  • PUT: update the resources on the server (the client provides the whole updated resources). For example: PUT /users/12 (student with update 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 an artificial partial update). It is rarely used. There are no examples here.

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();
}

3.2. POST request

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

The use of @ RequestBody annotation will be discussed in the following "passing values from front to back".

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

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) {
  ......
}

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){
  ......
}

3.5. PATCH request

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

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

4. Front and rear end value transmission

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

4.1. @ PathVariable and @ RequestParam

@PathVariable is used to obtain path parameters, and @ RequestParam is used to obtain query parameters.

Take a simple example:

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

What 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 data in the body part of the Request (possibly post, put, delete and get requests) and the content type is in 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 the json string in the requested body into a Java object.

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();
}

UserRegisterRequest object:

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

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

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

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

👉 It should be noted that a request method can only have one @ RequestBody, but it can have multiple @ RequestParam and @ PathVariable. If your method must use two @ requestbodies to receive data, it is likely that there is a problem with your database design or system design!

5. Read configuration information

Many times, we need to put some commonly used configuration information, such as Alibaba cloud oss, sending SMS, wechat authentication and so on, into the configuration file.

Let's take a look at how Spring provides us with ways to help us read this configuration information from the configuration file.

Our data source application YML contents are as follows:

wuhan2020: 2020 In early, the outbreak of New Coronavirus in Wuhan was serious, but I believe everything will be over. Wuhan, come on! Go China!

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

library:
  location: Hubei Wuhan refueling China refueling
  books:
    - name: Genius Basic Law
      description: On the day when his father diagnosed Alzheimer's disease, Lin Chaoxi, 22, learned that Peizhi, the campus male god he had been secretly in love with for many years, was about to go abroad for further study - the school that his father had given up for her was the one he had passed up.
    - name: Order of time
      description: Why do we remember the past, not the future? What does the "passage" of time mean? Do we exist in time, or does time exist in us? Carlo·Lowe uses poetic words to invite us to think about this ancient problem - the essence of time.
    - name: Great 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 times of life?

5.1. @ value (common)

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

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

5.2. @ configurationproperties (common)

Read the configuration information through @ ConfigurationProperties and bind it 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
  ......
}

You can inject it into the class just like using ordinary spring beans.

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
  ......
}

For more information, please see my article:< How can SpringBoot gracefully read the configuration file in 10 minutes?> .

6. Parameter verification

It goes without saying the importance of data verification. Even when the front end verifies the data, we still need to verify the data transmitted to 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 standards for JavaBean parameter verification. It defines many common verification annotations. We can directly add these annotations to our JavaBean properties, so that we can verify when verification is needed. It is very convenient!

During verification, we actually use the Hibernate Validator framework. Hibernate Validator is the original data verification 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 SpringBoot project, and there is no need to reference the relevant dependency. As shown in the following figure (generated by idea plug-in Maven Helper):

Non SpringBoot projects need to introduce their own dependent packages, which will not be explained here. For details, please see my article:< How to do parameter verification in Spring/Spring Boot? All you need to know is here!>.

👉 It should be noted that for all annotations, it is recommended to use JSR annotations, that is, javax validation. Constraints, not org hibernate. validator. constraints

6.1. Some commonly used field validation annotations

  • @NotEmpty# the of the annotated string cannot be null or empty
  • @NotBlank - the annotated string is not null and must contain a non white space character
  • @Null annotated element must be null
  • @NotNull annotated elements 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} annotated elements must be in email format.
  • @Min(value) the annotated element must be a number and its 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
  • @Digits (integer, fraction) the annotated element must be a number and its value must be within an acceptable range
  • @Past annotated element must be a past date
  • @Future the annotated element must be a future date
  • ......

6.2. Validation 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 The value is not in the 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;

}

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);
    }
}

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

Don't forget to add the "Validated" annotation on the class. This parameter can tell Spring to verify 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);
    }
}

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

7. Handle Controller layer exceptions globally

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

Relevant notes:

  1. @ControllerAdvice: the annotation defines the global exception handling class
  2. @ExceptionHandler: the annotation declares an exception handling method

How to use it? Take the parameter verification in Section 5 as an example. If the method parameters are wrong, a MethodArgumentNotValidException will be thrown. Let's deal with this exception.

@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

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

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

  1. Several common postures for handling exceptions in SpringBoot
  2. Use enumeration to simply encapsulate an elegant Spring Boot global exception handling!

8. JPA related

8.1. Create table

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

@Table , setting indication

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

8.2. Create primary key

@Id: declare a field as the primary key.

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

1. Use @ GeneratedValue to specify the primary key generation strategy by directly using the four primary key generation strategies provided in JPA.

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

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

Guide: a use of enumerations instead of 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, primary key self growth is not supported, such as Oracle and PostgreSQL, which provide a mechanism called "sequence" to generate primary keys
     */
    SEQUENCE,

    /**
     * Primary key self growth
     */
    IDENTITY,

    /**
     *Give the primary key generation strategy to the persistence engine,
     *The persistence engine will select one of the above three primary key generation strategies according to the database
     */
    AUTO
}

@The default policy used for the GeneratedValue annotation is generationtype AUTO

public @interface GeneratedValue {

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

Generally, if you use MySQL database, use generationtype The identity policy is more common (for distributed systems, the use of Distributed ID S should be considered separately).

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;

Equivalent to:

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

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() );
        }
    }

}

8.3. Set field type

@Column declaration field.

Example:

Set the database field name corresponding to the attribute userName to user_name, 32 in length, not empty

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

Setting field types and adding default values is quite common.

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

8.4. Specifies that specific fields are not persisted

@Transient: declare fields that do not need to be mapped to 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 use the @ Transient keyword to declare it.

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

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

}

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

Generally, there are many ways to use annotations.

8.5. Declare large fields

@Lob: declare a field as a large field.

@Lob
private String content;

More detailed statement:

@Lob
//Specify the acquisition policy of Lob type data, fetchtype Eager indicates non deferred 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;

8.6. Create fields of enumeration type

You can use fields of enumeration type, but the enumeration field should be decorated with @ Enumerated annotation.

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

    private String value;
    Gender(String str){
        value=str;
    }
}
@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......
}

MAIL/FEMAIL is stored in the database.

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;
}

Our corresponding audit function configuration classes 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);
    }
}

Briefly introduce some notes designed above:

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

    @LastModifiedDate and @ LastModifiedBy are the same.

@Enable JPA Auditing: enables JPA auditing.

8.8. Delete / modify data

@The Modifying annotation prompts JPA that this operation is a modification operation. Note that it should also be used with the @ Transactional annotation.

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

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

8.9. Association relationship

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

For more articles on Spring Boot JPA, please see my article: How to correctly use JPA in Spring Boot .

9. Transaction @ Transactional

Use the @ Transactional annotation on the method to start the transaction!

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

We know that exceptions are divided into runtime exceptions, runtimeexceptions and non runtime exceptions. If the rollbackFor attribute is not configured in the @ Transactional annotation, the transaction will only roll back when it encounters RuntimeException, plus rollbackFor = Exception Class, which allows things to roll back when they encounter non runtime exceptions.

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

  • Acting on class: when the @ Transactional annotation is placed on a 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. Perhaps the most beautiful Spring transaction management explanation
  2. Say 6 @ Transactional annotation invalidation scenarios at one go

10. json data processing

10.1. Filter json data

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

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

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

@JsonIgnore is generally used for class properties, and its function is the same as @ JsonIgnoreProperties , above.

public class User {

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

10.2. Formatting 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;

10.3. Flatten object

@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;
  }
}

Before flattening:

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

After using @ JsonUnwrapped} flat objects:

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

11. Test related

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

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

@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.

@WithMockUser is provided by Spring Security. It is used to simulate a real user and can be granted permissions.

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

Reprint: https://segmentfault.com/a/1190000022521844

In case of infringement, delete the comments

Keywords: Java Spring Boot Back-end

Added by baby on Sun, 16 Jan 2022 12:58:39 +0200