Nearly 8000 words of spring / springboot common annotation summary! Arrange!

Time:2021-10-20

@[toc]

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 89K star Java open source project javaguide:https://github.com/Snailclimb/JavaGuide

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!

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

Take it out here alone@SpringBootApplicationNote that 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 put@SpringBootApplicationAs@Configuration@EnableAutoConfiguration@ComponentScanA collection of 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:

  • @EnableAutoConfiguration: enables the auto configuration mechanism of springboot
  • @ComponentScan: scanned@Component (@Service,@Controller)For annotated beans, the annotation will scan all classes under the package where the class is located by default.
  • @Configuration: allows you to register additional beans 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 generally use@AutowiredAnnotations let the spring container help us assemble beans automatically. To identify a class as available for@AutowiredAnnotate the classes of automatically assembled beans, which can be implemented with the following annotations:

  • @ComponentAs a general annotation, any class can be marked:SpringComponents. If a bean does not know which layer it belongs to, it can be used@ComponentAnnotation.
  • @Repository: the corresponding persistence layer, namely Dao layer, is mainly used for database related operations.
  • @Service: the corresponding service layer mainly involves some complex logic, and the Dao layer is required.
  • @Controller: corresponding to the spring MVC control layer, the main users accept user requests and call the service layer to return data to the front-end page.

2.3. @RestController

@RestControllerAnnotation is@Controller and@ResponseBodyThe collection of indicates that this is a controller bean, and the return value of the function is directly filled 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 it for a long time@Controller。 If your project is too old, treat it as if I didn’t say it.

Use alone@ControllerNo@ResponseBodyIt is generally used to return a view. This is a traditional spring MVC application, which corresponds to the situation that the front and back ends are not separated.@Controller +@ResponseBodyReturn data in JSON or XML

about@RestControllerand@ControllerFor comparison, 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. You can use@ComponentAnnotation substitution, but useConfigurationAnnotations declare configuration classes more semantically.

@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 instance:GET /users(get all students)
  • POST: create a new resource on the server. for instance:POST /users(create student)
  • PUT: update the resource on the server (the client provides the updated entire resource). for instance:PUT /users/12(updated student No. 12)
  • DELETE: deletes a specific resource from the server. for instance:DELETE /users/12(delete student No. 12)
  • PATCH: update the resources on the server (the client provides the changed attributes, which can be seen as an artificial partial update), which is rarely used. There are no examples here.

3.1. Get request

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

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

3.2. Post request

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

about@RequestBodyThe use of annotations will be discussed in the “front and back end value transfer” below.

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

3.3. Put request

@PutMapping("/users/{userId}")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}")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. @PathVariableand@RequestParam

@PathVariableUsed to obtain path parameters,@RequestParamUsed to get 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 ) {
...
}

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

Used to read the body part of a request (possibly a post, put, delete, get request), andContent type is application / JSONAfter receiving the data, it will automatically bind the data to Java objects. The system will useHttpMessageConverterOr customHttpMessageConverterConvert the JSON string in the requested body to 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();
}

UserRegisterRequestObject:

@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 back-end can directly map the data in JSON format to our databaseUserRegisterRequestClass.

Nearly 8000 words of spring / springboot common annotation summary! Arrange!

It should be noted that:A request method can only have one@RequestBody, but there can be more than one@RequestParamand@PathVariable。 If your method has to use two@RequestBodyTo accept the data, the probability is that there is something wrong 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 sourceapplication.ymlThe contents are as follows:

Wuhan2020: in early 2020, New Coronavirus broke out in Wuhan. The epidemic is serious. But I believe everything will be over. Wuhan, come on! Go China!

my-profile:
  Name: brother Guide
  email: [email protected]

library:
  Location: Wuhan, Hubei come on, China come on
  books:
    -Name: Genius Basic Law
      Description: on the day when his father diagnosed Alzheimer's disease, Lin Chaoxi, 22, learned that Pei Zhi, the campus male god he had secretly loved for many years, was about to go abroad for further study - the school that the other party passed on was the one his father gave up for her.
    -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}")Read simple configuration information:

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

5.2. @ConfigurationProperties(common)

adopt@ConfigurationPropertiesRead the configuration information and bind with 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;
    }
  Omit getter / setter
  ......
}

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

5.3. PropertySource(not commonly used)

@PropertySourceRead the specified properties file

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

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

  Omit 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)It is a set of JavaBean parameter verification standards. 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!

When checking, we actually useHibernate ValidatorFrame. 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 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):

Nearly 8000 words of spring / springboot common annotation summary! Arrange!

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:JSR annotation is recommended for all annotations, i.ejavax.validation.constraints, notorg.hibernate.validator.constraints

6.1. Notes for some common field validation

  • @NotEmptyThe of the annotated string cannot be null or empty
  • @NotBlankThe annotated string is not null and must contain a non white space character
  • @NullThe annotated element must be null
  • @NotNullThe annotated element must not be null
  • @AssertTrueThe annotated element must be true
  • @AssertFalseThe annotated element must be false
  • @Pattern(regex=,flag=)The annotated element must conform to the specified regular expression
  • @EmailThe annotated element 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 and its value must be less than or equal to the specified maximum value
  • @DecimalMin(value)The annotated element must be a number and its value must be greater than or equal to the specified minimum value
  • @DecimalMax(value)The annotated element must be a number and its 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
  • @PastThe annotated element must be a past date
  • @FutureThe annotated element must be a future date
  • ……

6.2. Verification 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 is not in the optional range")
    @Notnull (message = "sex cannot be empty")
    private String sex;

    @Email (message = "email format is incorrect")
    @Notnull (message = "email cannot be empty")
    private String email;

}

We added the parameters to be verified@ValidAnnotation, which will be thrown if the validation failsMethodArgumentNotValidException

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

Make sure you don’t forget to addValidatedNote that 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 = "out of range of 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. @ControllerAdviceAnnotation: defines the global exception handling class
  2. @ExceptionHandler: annotation declaration exception handling method

How to use it? Take the parameter verification in Section 5 as an example. Thrown if the method parameters are incorrectMethodArgumentNotValidException, let’s handle 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

@EntityDeclare that a class corresponds to a database entity.

@TableSetting indicates

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

8.2. Create primary key

@Id: declare a field as the primary key.

use@IdAfter the declaration, we also need to define the generation strategy of the primary key. We can use@GeneratedValueSpecifies the primary key generation policy.

1. Adoption@GeneratedValueDirectly use the four primary key generation strategies provided by JPA to specify the primary key generation strategy.

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

@GeneratedValueThe default strategy for annotations isGenerationType.AUTO

public @interface GeneratedValue {

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

If MySQL database is generally used, useGenerationType.IDENTITYThe strategy is more common (for distributed systems, the use of distributed ID needs to be considered separately).

2. Adoption@GenericGeneratorDeclare a primary key policy, and then@GeneratedValueUse this strategy

@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. Setting field type

@ColumnDeclaration 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. Specify specific fields that are not persistent

@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 wantsecrectThis field is not persisted and can be used@TransientKeyword declaration.

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

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

}

except@TransientFor keyword declaration, the following methods can also be used:

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
//Specifies the acquisition policy of lob type data. Fetchtype. Eagle indicates non delayed loading, and 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 enumeration fields need to use@EnumeratedAnnotation modification.

public enum Gender {
    Mal ("male"),
    Female ("female");

    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;
    Omit getter / setter
}

Mail / femail is stored in the database.

8.7. Add audit function

Just inheritAbstractAuditBaseAll classes will add the following four fields 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 inserted, the value will be set
  2. @CreatedBy: indicates that the field is the creator, and the value will be set when the entity is inserted

    @LastModifiedDate@LastModifiedBySimilarly.

@EnableJpaAuditing: enable the JPA audit function.

8.8. Delete / modify data

@ModifyingThe annotation prompts JPA that this operation is a modification operation. Note that it should be coordinated@TransactionalAnnotation usage.

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

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

8.9. Relationship

  • @OneToOneDeclare a one-to-one relationship
  • @OneToManyDeclare a one to many relationship
  • @ManyToOneDeclare many to one relationships
  • MangToMangDeclare many to many relationships

For more articles on spring boot JPA, please see my article:How to correctly use JPA in spring boot

9. Services@Transactional

Use on the method to start the transaction@TransactionalJust annotate!

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

We know that exceptions are divided into runtime exceptions, runtimeexceptions and non runtime exceptions. stay@TransactionalIf not configured in the annotationrollbackForProperty, then things will only encounterRuntimeExceptionWill be rolled back when, plusrollbackFor=Exception.class, you can make things roll back when they encounter non runtime exceptions.

@TransactionalAnnotations are generally used toclassperhapsmethodCome on.

  • Act on class: when@When a transactional annotation is placed on a class, it represents all the attributes of the classPublic methods are configured with the same transaction attribute information.
  • Act on method: when the class is configured@Transactional, the method is also configured@Transactional, the transaction of the method will override 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. Filtering JSON data

@JsonIgnorePropertiesIt is used on a class to filter out specific fields and does not return or parse them.

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

@JsonIgnoreIt is generally used for the properties and functions of the class@JsonIgnorePropertiesSame.

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

@JsonFormatIt 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. Flattened 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"
    }
}

use@JsonUnwrappedAfter flattening 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

@ActiveProfilesIt is generally used on the test class to declare the effective spring configuration file.

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

@TestDeclare a method as a test method

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

@WithMockUserProvided 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 {
        ......
    }

That’s all for now! Although it took a long time to finish writing, some common annotations may still be missed. Therefore, I synchronized the article to GitHub. GitHub address:https://github.com/Snailclimb/JavaGuide/blob/master/docs/system-design/framework/spring/spring-annotations.md Welcome to perfect!

This article has been included in my 89K star Java open source project javaguide:https://github.com/Snailclimb/JavaGuide

Recommended Today

SQL exercise 20 – Modeling & Reporting

This blog is used to review and sort out the common topic modeling architecture, analysis oriented architecture and integration topic reports in data warehouse. I have uploaded these reports to GitHub. If you are interested, you can have a lookAddress:https://github.com/nino-laiqiu/TiTanI recorded a relatively complete development process in my hexo blog deployed on GitHub. You can […]