Spring Boot with MyBatis and JPA

Spring Boot with MyBatis and JPA

What is Spring Boot

Spring features

  • Ability to create stand-alone Spring Boot applications

  • Embed Tomcat,Jetty Undertow and don't need to deploy them

  • Provides "starters" poms to simplify Maven configuration

    https://www.cnblogs.com/qlqwjy/p/7979159.html

    Spring brings a lot of magic into the development of Spring applications, the most important of which are the following four cores.

    • Automatic Configuration: Spring Boot automatically provides configuration for common application features in many Spring applications
    • Start Dependency: Tell Spring Boot what features it needs to bring in the libraries it needs.
    • Command Line Interface: This is an optional feature of Spring Boot so that you can write code to complete the entire application without requiring traditional project builds.
    • Actuator: Allows you to delve into running Spring Boot applications and explore them.
  • Automatically configure Spring applications whenever possible

  • Provide production metrics, robustness checks, and external configuration

  • Before the advent of spring boot, a large number of xml configurations were required when using the spring framework, but now you can have a small number or no configurations

    Spring Advantages

    The goal of Spring is not to provide new solutions to the problem areas that you are solving, but to provide a new development experience for the platform to simplify the use of these existing technologies.

    [External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-PjiW834j-1638550633743)(SpringBoot.assets/image-20210420104137977.png)]

Steps for integrating third-party class libraries with Spring Boot

  • Introducing springboot-XXXX-starter through maven

  • Modify yml or properties global unified profile

  • Join a Java Config. This is a personalized configuration, which is not required if you use a generic configuration.

    • Official default integrated class library reference:
    • https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-starter

What is Spring Boot Starter

Spring Boot Starter is a collection of third-party class libraries that are dependent on

  • If you develop a WEB application, you can simply introduce Spring-boot-starter-web, which will automatically introduce the following class libraries:

    • spring - spring Core, baens, context, AOP Face-to-Face

    • Web MVC -Spring MVC

    • Jackson - Serialization and Deserialization of JSON Data

    • Embedded Servlet Container--Tomcat

    • Loggin-logback,slf4j Log Framework

Create Spring Boot Project

Baidu by oneself

You can also add the web environment directly - Baidu itself

boot comes with LOG_PATH Log

Project Structure Catalog

Directory Locationfunction
src / main / javaProject's java file location, initialization package contains main program entry
XXXApplication, Srping Boot applications can be started by running this class directly
src / main / resourcesStore static resources, pictures, CSS, javaScript, web page template files, etc.
src / testUnit Test Code Directory
.gitignoregit version management exclusion file
target folderProject Code Construction Packaging Result File Storage Location, does not require maintenance
pom.xmlmaven project configuration file
application.properties
(application.yml)
Used to store configuration information for various dependent modules of the program, such as server ports, database connection configurations, etc.
src / main / resources / staticMainly used to store static files for development of CSS, pictures, js, etc.
src / main / resources / pulicUsed to store html files that can be accessed directly
src / main / resources / templaFor storing web development template files

Hot Loading and Hot Deployment

### devtools for hot loading
  • Dependencies (add the following dependencies if not checked when creating a project)

    org.springframework.boot

    spring-boot-devtools

    true

Set IDEA

  • Runtime compilation configuration:'shift + Ctrl + Alt + /', select'Registry', check the tick compiler.automake.allow.when.app.running

After code modification

  • Use Ctrl + shift + F9 to recompile the modified class (setting Running Application Update Policies also works)

Controller Deep

I. Controller Role

  • Processing user requests

  • Similar to Servlet, but more flexible than Servlet, automating a lot of work

    Automatically receive request parameters

    Type Conversion

    data validation

2. Common Notes

  1. @Controller

    Define a bean as a controller

  2. @RestController

    • RestConntroller is equivalent to combining @Controller with @ResponseBody

      • Controller injects a controller class into the Spring context labeled as an HTTP service endpoint
      • The role of ResponseBody, which uses JSON as the default serialization method for request responses, is not to jump to a jsp or template page.
  3. @RequestMapping annotation

    • value: Apply the request endpoint, the core property, to mark the uniqueness of the request processing method;
    • Method: The method type of HTTP protocol, such as GET, POST, PUT, DELETE, etc.
    • consumes: The data type (Content-Type) of the HTTP protocol request content, such as application/json, text/html;
    • produces: The data type of the HTTP protocol response content. produces = text/plain;charset=utf-8"
    • params: The annotated method is only allowed to handle requests when certain parameter values must be included in the HTTP request.
    • headers: The HTTP request must contain some specified header value to allow the annotated method to process the request.
  4. @RequestBody and @ResponseBody

    • @RequestBody modifies the request parameter, annotates the body used to receive HTTP, and by default uses the JSON format to receive front-end data using objects or nested objects

    • @ResponseBody modifies the return value, annotations are used to carry response data in HTTP body s, using the JSON format by default. If you do not add this comment, the spring response string type is the development mode for jumping to a template page or a jsp page. That is, a data interface is developed with this annotation, and a page Jump controller is developed without this annotation.
      The @ResponseBody function is to convert java objects to json-formatted data. This comment must be added when requests are PUT and DELETE. Note: Instead of going to the view processor after using this annotation, you write the data directly into the input stream, which is equivalent to outputting the data in the specified format through the response object.

          @GetMapping("/toIndex4")
          //Add @ResponseBody to indicate that a string or json is returned
          @ResponseBody
          public UserVo toIndex4(){
              UserVo user = new UserVo();
              user.setUid(11);
              user.setPwd("ss");
              user.setUname("Xu Xian");
              return user;
          }
      
  5. @ModelAttribute

    The main function of @ModelAttribute is to add data to model objects for view page display.

  6. @PathVariable and @RequestParam

    • @PathVariable is used for the {parameter} on the URI, as follows to delete an article with an ID of the article. For example: Our request URL is'/article/1', then DeleteMapping will be matched and PathVariable receive parameter id=1; @ PathVariable is used to map template variables in URLs requesting RESTFUL style to parameters of the functional processing method, that is, to take variables from URI templates as parameters

    • RequestParam, on the other hand, receives parameter data submitted by a generic form or an ajax simulation form.

      @DeleteMapping("/article/{id}")
      public @ResponseBody AjaxResponse deleteArticle(@PathVariable Long id) 
      @PostMapping("/article")
      public @ResponseBody AjaxResponse deleteArticle(@RequestParam Long id) 
              @GetMapping("/toIndex")
      //    Bind the name of the unparameter it receives to the alias uname
          public ModelAndView toIndex2(@RequestParam("un")String uname){
              ModelAndView mv = new ModelAndView("index");
              mv.addObject("uname",uname);
              return mv;
          }
      
  7. RequestMapping

    • The @PostMapping method is equal to @RequestMapping and is equal to POST.

    • GetMapping is equivalent to @RequestMapping whose method is equal to GET.

    • The method @PutMapping is equal to @RequestMapping and is equal to PUT.

    • The @DeleteMapping method is equal to @RequestMapping and is equal to DELETE.

8.@RequestBody and @PathVariable

Equivalent to parameters passed in from get or post,

Equivalent to the value on the path

/**
 * @author XuLuBao
 * @version V1.0
 * @Package com.trkj.boot1.controller
 * @date 2021/4/20 16:11
 */
@Log4j2
@RestController
//Equivalent to both @Controller + @ResponseBody
public class RestFulController {
    @GetMapping("/user/{id}")
    public UserVo findUser(@PathVariable("id")int id){
        UserVo vo = new UserVo();
        vo.setUname("Xu Xian");
        vo.setUid(1);
       log.debug("Success");
        return  vo;
    }
    @DeleteMapping("/user/{uid}/{na}")
    public String delUser(@PathVariable("uid")int id,@PathVariable("na")String na){
        System.out.println(id+na);
        log.debug("Delete succeeded");
        return "Successfully deleted!";
    }
    @PutMapping("/user")
//    Correspond
    public String alertUser( @RequestBody  UserVo vo){
        log.debug("Successful modification");
        return "Successful modification";
    }
    @PostMapping("/user")
    public UserVo addUser(@RequestBody UserVo vo){
        vo.setPwd("ss");
        log.debug("Added Successfully");
        return vo;
    }
}

3. Common return value methods to clients in Controller

1. Return String, which is used to represent the view name and, if data needs to be returned to the client, can be used with the Model object in the method parameter. Or use @ModelAttribute("xx") to add values to Model directly after giving an alias for the parameter.

	2. Return String,Used to indicate that a string result is returned directly to the client, not to the view, but to the number of direct returns	According to. The string can be either a normal string or a Json Format string. Requires use on Methods```<@ResponseBody>```Notes. 
	3. Return ModelAndView,Views add data, and if you need to return data to the client, use```ModelAndView```It will be more convenient.

4. Common ways of passing data by Controller

  • General parameters

  • Parameter is a JavaBean object

  • Receives Date type parameters, only dates in yyyy/dd/mm format are supported by default

  • RESTFul style way parameters

5. Redirection

Forward by default, and redirect prefix the returned results if redirected

@RequestMapping("redirect")
public String redirect(){
	return "redirect:/hello.jsp";
}

List

    @PostMapping("/show")
//    It will also help me wrap it up, adding @ModelAttribute("user") just adds data to the scope for access
    public String toShowUser(UserVo user, Model model){
        user.setPwd("15111666207");
//        It's equivalent to automatically storing values in a scope, boot automatically helps me do these things
//
        model.addAttribute("vo",user);
        return "show";
    }

Problems encountered

@SessionAttributes(value = {"user"},types = {User.class})

SessionAttributes stores a parameter named "user" in session s before running

Add it directly to the method when you need to be clear about it: SessionStatus, which calls SessionStatus.setComplete() in the method body; Clean up, but it only clears values stored in the SesionAttributes

Determine if the object is empty

    @GetMapping(value = "/indexU" )
    public String chkLong(User user,SessionStatus status) {
        if (user!=null&&user.getName()!=null) {
            if (user.getName().length()>=6) {
                return "index";
            }else {
                status.setComplete();
                return "login";
            }
        } else {
            status.setComplete();
            return "login";
        }
    }

Because of the above addition to the class, the resulting user is the object that has been created, but the value inside it is not empty, you need to judge the object and then also the attribute.

  • List errors in Session Attributes, we recommend using Model for value storage, always errors, no value

Spring Boot Add Log

Add the logback-spring.xml log file to the resources directory and the corresponding log code

Spring Boot Integration Swagger

Add Maven related dependencies, where you need to add WEB and SWAGGER dependencies.

  • WEB Dependency
<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  • swagger depends, choose version 2.9.2 here.
<!-- swagger -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>

Add Configuration Class

  • Add a swagger configuration class, create a new config package under the project, and add a SwaggerConfig configuration class.

    • SwaggerConfig.java

      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import springfox.documentation.builders.ApiInfoBuilder;
      import springfox.documentation.builders.PathSelectors;
      import springfox.documentation.builders.RequestHandlerSelectors;
      import springfox.documentation.service.ApiInfo;
      import springfox.documentation.spi.DocumentationType;
      import springfox.documentation.spring.web.plugins.Docket;
      import springfox.documentation.swagger2.annotations.EnableSwagger2;
      
      @Configuration
      @EnableSwagger2
      public class SwaggerConfig {
      
          @Bean
          public Docket createRestApi(){
              return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
                      .select()
                      .apis(RequestHandlerSelectors.any())
                      .paths(PathSelectors.any()).build();
          }
      
          private ApiInfo apiInfo(){
              return new ApiInfoBuilder()
                      .title("Kitty API Doc")
                      .description("This is a restful api document of Kitty.")
                      .version("1.0")
                      .build();
          }
      
      }
      
  • Add a control class

    /**
     * @author XuLuBao
     * @version V1.0
     * @Package com.trkj.boot1test1.controller
     * @date 2021/4/21 15:12
     */
    /*Method Notes*/
    @Api(value = "desc of class")
    @RestController
    public class TestController {
        /*Method Notes*/
        @ApiOperation(value="desc of method",notes="notes")
        @GetMapping
        public Object hello(/*Parametric Note*/@ApiParam(value = "desc of param",required = true)@RequestParam String name){
            return "Hello" + name + "!";
        }
    
    }
    

Spring Cross Domain

  • Add Configuration Class

    @Configuration
    @Slf4j
    public class AppCorsConfiguration {
        private CorsConfiguration buildConfig() {
            log.debug("Start Setting");
            CorsConfiguration appCorsConfiguration = new CorsConfiguration();
            appCorsConfiguration.addAllowedOrigin("http://localhost:8081");
            appCorsConfiguration.addAllowedOrigin("http://127.0.0.1:8081");
            appCorsConfiguration.addAllowedHeader("*"); // 2 Allow any header
            appCorsConfiguration.addAllowedMethod("OPTIONS");
            appCorsConfiguration.addAllowedMethod("HEAD");
            appCorsConfiguration.addAllowedMethod("GET");
            appCorsConfiguration.addAllowedMethod("PUT");
            appCorsConfiguration.addAllowedMethod("POST");
            appCorsConfiguration.addAllowedMethod("DELETE");
            appCorsConfiguration.addAllowedMethod("PATCH");
            appCorsConfiguration.setAllowCredentials(true);//You cannot upload files across domains without adding these two sentences.
            appCorsConfiguration.setMaxAge(3600L);//Add it in
            return appCorsConfiguration;
        }
    
        @Bean
        public CorsFilter corsFilter() {
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            source.registerCorsConfiguration("/**", buildConfig()); // 4
            return new CorsFilter(source);
        }
    }
    
    • Or add

      @CrossOrigin
      

Spring Boot+ JWT

What is jwt

Json Web Token (JWT): A JSON network token is an open standard based on JSON (RFC 7519) developed to deliver declarations between network applications. JWT is a lightweight, secure, cross-platform transmission format that defines a compact, self-contained way for secure transmission of information between communicating parties using JSON objects. Because digital signatures exist, this information is trusted.

  • Token is a string generated by the server as a token for the client to request. When the server generates a Token after the first login, the server returns the Token to the client. In the future, the client only needs to bring the Token to request data without having to bring the user name and password again.

  • JWT is made up of three pieces of information, which together form a JWT string.

    + >eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
    

The composition of jwt

jwt consists of three parts

  • header

    • The header generally has two parts of information: the token type and the encryption algorithm used

    {

    "alg": "HS256",

    "typ": "JWT"

    }

  • Load plyload

    • This section generally stores some valid information. Valid information consists of three parts: declarations registered in the standard, declarations in common, and private declarations (i.e. custom fields).

      A registration declaration is a declaration whose name is registered in the IANA JSON Web Token registry and defined in the specification. A declaration registered in the JWT standard (recommended but not mandatory) contains seven fields:

      • iss (issuer): issuer
      • exp (expiration time): expiration time
      • sub (subject): subject
      • aud (audience): Audience (recipient)
      • nbf (Not Before): Effective time
      • Issued At: Issuance time
      • jti (JWT ID): Number
    • A public declaration is a declaration that is not defined in the specification but is registered in the IANA JSON Web Token registry or named with a conflict-proof name (for example, containing a namespace).

    • Private claims refer to claims that are not registered but customized by consumers and producers of JWT. That is why there is a possibility of name conflicts.

      {

      "sub": "1234567890",

      "name": "John Doe",

      "iat": 1516239022

      }

  • Visa signature

    • The last part of the visa JWT. This part is the data encrypted using HS256; It consists of three parts:

      • Hander (after base64)

      • Payload (after base64)

      • secret private key

        Secret is stored on the server side. JWT signature generation is also on the server side. Secret is used for JWT signing and JWT authentication. Therefore, it is the key of your server side and should not be disclosed in any scenario. Once the client knows this secret, it means that the client can issue the JWT itself.

Comparison of Traditional Cookid+Session and JWT

  1. Cookies+sessions are typically stored in memory, and session sharing is a problem for services ranging from single to multiple services. As the number of users increases, the overhead increases.

  2. Cook+session limits the scalability of applications, especially how servers share sessions in distributed applications is a very difficult problem.

  3. JWT only needs the server to generate a token, which is saved by the client, and each time the token is requested to be brought along, the server can resolve the authentication and reduce the server pressure. It is also ideal for distributed application development.

  4. JWT is stateless and one-time. To modify the contents, you must issue a new JWT. That is, once issued, the service background cannot refuse requests to carry the JWT (such as kicking the user)

    1. If the API is designed to be canonical stateless RESTful, token is recommended
    2. If API s are consumed by different terminals and cookies are restricted, token is recommended
    3. If front-end and back-end separate applications, token is recommended
    4. If you are not developing in the above way, it is recommended that you choose Cookie Session

JWT Access Process

[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-6W5Lp87Z-1638550633746) (SpringBoot.assets/image-202104250947539.png)]

Spring boot JWT project

  1. Maven Dependency Configuration

    ​ io.jsonwebtoken

    ​ jjwt

    ​ 0.9.1

  2. application.yml Configuration

    jwt:
    	#Key key
    	secret: JWTSecret
    	#HeaderKEY
    	header: JWThEADERnAME
    	#Expiration time milliseconds
    	expire: 100
    
    server:
      port: 8089
      #Connection pool configuration
      servlet:
        context-path: /jwttest
    spring:
      datasource:
        url: jdbc:mysql://127.0.0.1:3308/mydb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
        username: root
        password: root2020
        driver-class-name: com.mysql.cj.jdbc.Driver
        # Use druid data source
        type: com.alibaba.druid.pool.DruidDataSource
        druid:
          # Configure Test Query Statement
          validationQuery: SELECT 'x'
          # Initialization size, minimum, maximum
          initialSize: 10
          minIdle: 10
          maxActive: 200
          # Configure a connection's minimum lifetime in milliseconds in the pool
          minEvictableIdleTimeMillis: 180000
          testOnBorrow: false
          testWhileIdle: true
          removeAbandoned: true
          removeAbandonedTimeout: 1800
          logAbandoned: true
          # Open the PSCache and specify the size of the PSCache on each connection
          poolPreparedStatements: true
          maxOpenPreparedStatements: 100
          # Configure filters intercepted by monitoring statistics, sql cannot be counted after removal,'wall'for firewall
          filters: stat,wall,log4j2
          # Open the mergeSql function through the connectProperties property; Slow SQL Records
          connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      redis:
        database: 0 # Redis database index (default 0)
        host: 127.0.0.1 # Redis Server Address
        port: 6379 # Redis Server Connection Port
        password: redis2020 # Redis server connection password (blank by default)
        lettuce:
          pool:
            max-active: 8 # Maximum number of connections in connection pool (no limit with negative value) default 8
            max-wait: -1 # Connection pool maximum blocking wait time (unlimited with negative value) default-1
            max-idle: 8 # Maximum idle connection in connection pool default 8
            min-idle: 0 # Minimum idle connection in connection pool default 0
    # JWT Configuration
    jwt:
      # Key KEY
      secret: JWTSecret
      # HeaderKEY
      header: JWTHeaderName
      # Token prefix character
      tokenPrefix: Security-c
      # Expiration time milliseconds
      expire: 100000
    
    
    mybatis:
      mapper-locations: classpath:mapper/*.xml
      type-aliases-package: com.trkj.jwtdemo.entity
    
    pagehelper:
      helperDialect: mysql
      reasonable: true
      supportMethodsArguments: true
      params: count=countS
    
    
  3. Write the jwtTokenUtil tool class

    @Slf4j
    @Data
    @ConfigurationProperties(prefix = "jwt")
    @Component
    public class JwtTokenUtil {
    
        private String secret;
        private Long expire;
        private String header;
    
    
        /**
         * Generate token token
         *
         * @param userName user
         * @return Token token
         */
        public String generateToken(String userName) {
            Map<String, Object> claims = new HashMap<>(2);
            claims.put("sub", userName);
            //claims.put("id",user.getId());
            claims.put("created", new Date());
            return generateToken(claims);
        }
    
        /**
         * Get user name from token
         *
         * @param token token
         * @return User name
         */
        public String getUsernameFromToken(String token) {
            String username;
            try {
                Claims claims = getClaimsFromToken(token);
                username = claims.getSubject();
            } catch (Exception e) {
                username = null;
            }
            return username;
        }
    
        /**
         * Determine whether a token is expired
         *
         * @param token token
         * @return Is it expired
         */
        public Boolean isTokenExpired(String token) {
            try {
                Claims claims = getClaimsFromToken(token);
                Date expiration = claims.getExpiration();
                log.info("in isTokenExpired date:{}",expiration.toLocaleString());
                Date date=new Date();
                log.info("in isTokenExpired now:{},exp:{} ,{}",date.toLocaleString(),expiration.toLocaleString(),expiration.before(date));
                return expiration.before(date);
            } catch (Exception e) {
                e.printStackTrace();
                return true;
            }
        }
    
        /**
         * Get token expiration time, test, delete
         * @param token
         * @return
         */
        public Date  expirationDate(String token){
            Claims claims = getClaimsFromToken(token);
            Date expiration = claims.getExpiration();
            return expiration;
        }
    
        /**
         * refresh token
         * @param token Original token
         * @return New token
         */
        public String refreshToken(String token) {
            String refreshedToken;
            try {
                Claims claims = getClaimsFromToken(token);
                claims.put("created", new Date());
                refreshedToken = generateToken(claims);
            } catch (Exception e) {
                e.printStackTrace();
                refreshedToken = null;
            }
            return refreshedToken;
        }
    
        /**
         * Authentication token
         *
         * @param token       token
         * @param userName user
         * @return Is it valid
         */
        public Boolean validateToken(String token, String userName) {
    
            String uname = getUsernameFromToken(token);
            return (uname.equals(userName) && !isTokenExpired(token));
        }
    
    
        /**
         * Generating tokens from claims
         * @param claims Data declaration
         * @return token
         */
        private String generateToken(Map<String, Object> claims) {
            Date expirationDate = new Date(System.currentTimeMillis() + expire);
            /**
             * signWith() Signature method. The two parameters are the signature algorithm and the custom signature Key (salt).
             * The signature key can be passed in as byte[], String, and Key.
             * The first two forms are stored in the builder's keyBytes property, and the second in the builder's key property.
             * If the key of the second (and String type) is the key, decode it with base64 to get byte[].
             * compact() Generate JWT
             */
            return Jwts.builder()
                    .setHeaderParam("typ", "JWT")
                    .setClaims(claims)
                    .setExpiration(expirationDate)
                    .setIssuedAt((Date)claims.get("created"))
                    .signWith(SignatureAlgorithm.HS512, secret)
                    .compact();
        }
    
        /**
         * Get data declaration from token
         *
         * @param token token
         * @return Data declaration
         */
        private Claims getClaimsFromToken(String token) {
            Claims claims;
            try {
                claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
            } catch (Exception e) {
                claims = null;
            }
            return claims;
        }
    
    }
    
    
  4. Write interceptor TokenInterceptor class

    @Slf4j
    @Component
    public class TokenInterceptor extends HandlerInterceptorAdapter {
    
        @Resource
        private JwtTokenUtil jwtTokenUtil;
        @Override
        public boolean preHandle(HttpServletRequest request,
                                 HttpServletResponse response,
                                 Object handler) throws SignatureException {
            /** Address filtering */
            String uri = request.getRequestURI() ;
            System.out.println(uri);
            if (uri.contains("/login")){
                return true ;
            }
            /** Token Verification */
            String token = request.getHeader(jwtTokenUtil.getHeader());
            if(StringUtils.isEmpty(token)){
                token = request.getParameter(jwtTokenUtil.getHeader());
            }
            if(StringUtils.isEmpty(token)){
                throw new SignatureException(jwtTokenUtil.getHeader()+ "Cannot be empty");
            }
            if(jwtTokenUtil.isTokenExpired(token))
                throw new SignatureException(jwtTokenUtil.getHeader() + "Failed, please log in again.");
            /** Set identityId user identity ID */
           // request.setAttribute("identityId", jwtTokenUtil.getUsernameFromToken(token));
            return true;
        }
    }
    
  5. Register Interceptor

    @Slf4j
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
        @Resource
        private TokenInterceptor tokenInterceptor ;
        public void addInterceptors(InterceptorRegistry registry) {
            log.debug("register TokenInterceptor");
            registry.addInterceptor(tokenInterceptor).addPathPatterns("/**");
        }
    }
    
  6. Write Controller

    @Slf4j
    @RestController
    public class IndexController {
        @Autowired
        private JwtTokenUtil jwtTokenUtil;
        @PostMapping("/login")
        public AjaxResponse login(@RequestBody User user){
            log.info(user.toString());
            String token=jwtTokenUtil.generateToken(user.getName(),user.getId()+"");
            return AjaxResponse.success(token);
        }
        @GetMapping("/user/{id}")
        public AjaxResponse findUser(@PathVariable("id") int id){
            log.info("FindUser........................");
            User user=new User();
            user.setId(id);
            user.setName("TestName");
            user.setPwd("testPwd");
            return AjaxResponse.success(user);
        }
    }
    
  7. PostMan Test and VUE Test

File Upload

Integrate Mybatis

[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-292RcHSC-1638550633747)(SpringBoot.assets/image-20210429142405443.png)]

rely on

Basic dependency, database dependency, data source dependency

	......

<dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>2.1.4</version>
</dependency>
<!--        jPaginate-->
<dependency>
     <groupId>com.github.pagehelper</groupId>
     <artifactId>pagehelper-spring-boot-starter</artifactId>
     <version>1.2.13</version>
</dependency>
<!--        orable Coding aspects-->
<dependency>
      <groupId>cn.easyproject</groupId>
      <artifactId>orai18n</artifactId>
      <version>12.1.0.2.0</version>
</dependency>
<dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>druid-spring-boot-starter</artifactId>
     <version>1.1.21</version>
</dependency>

.yml Configuration

server:
  port: 8088
  servlet:
    context-path: /oraclemybatis
  #Connection pool configuration
spring:
  datasource:
    url: jdbc:oracle:thin:@127.0.0.1:1521:orcl
    username: scott
    password: tiger
    driver-class-name: oracle.jdbc.driver.OracleDriver
      #mysql is configured as follows:
      #url: jdbc:mysql://127.0.0.1:3308/mydb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
      #username: root
      #password: root2020
      #driver-class-name: com.mysql.cj.jdbc.Driver
      # Use druid data source
    #type: com.alibaba.druid.pool.DruidDataSource

    # Use druid data source
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      # Configure Test Query Statement
      validationQuery: SELECT 1 FROM DUAL
      # Initialization size, minimum, maximum
      initialSize: 10
      minIdle: 10
      maxActive: 200
      # Configure a connection's minimum lifetime in milliseconds in the pool
      minEvictableIdleTimeMillis: 180000
      testOnBorrow: false
      testWhileIdle: true
      removeAbandoned: true
      removeAbandonedTimeout: 1800
      logAbandoned: true
      # Open the PSCache and specify the size of the PSCache on each connection
      poolPreparedStatements: true
      maxOpenPreparedStatements: 100
      # Configure filters intercepted by monitoring statistics, sql cannot be counted after removal,'wall'for firewall
      filters: stat,wall
mybatis:
# Mapping File Configuration
  mapper-locations: classpath:mapper/*.xml
#  Configuration of entity classes, mainly changing location
  type-aliases-package: com.trkj.mybatisboot.entity

pagehelper:
#  Indicates that this is an oracle configuration
  helperDialect: oracle
  reasonable: true
  supportMethodsArguments: true
  params: count=countS

Configure druid connection pool, data source monitoring

  • Add druid StatViewServlet to display Druid statistics
    • To use functionality that uses other Servlet or fiter components, Spring boot must borrow the Servlet RegistrationBean interface provided by Spring Boot
    • Configure Druid Service Filters
    • Access address: http://localhost:8088/druid/login.html
// Under config directory
package com.trkj.oraclemybatis.config;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration   /*Declare that this is a configuration class*/
public class DataSourceConfig {
 
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")   /*Read the prefix is a follow-up to this and build the Datasource! If we don't have this step, it doesn't produce what we want*/
    /*It works without writing, but it's not what you want.*/
    public DataSource dataSource() {
        return DruidDataSourceBuilder.create().build();
    }
    /**
     * Configure Monitoring Server
     * @return Returns a monitor registered servlet object
     * @author SimpleWu
     */
    @Bean
    public ServletRegistrationBean statViewServlet() {
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        // Add IP Whitelist
        servletRegistrationBean.addInitParameter("allow", "127.0.0.1");
        // Add IP blacklist, which takes priority when the whitelist and blacklist are duplicated
        //servletRegistrationBean.addInitParameter("deny", "127.0.0.1");
        // Add Console Management User
        servletRegistrationBean.addInitParameter("loginUsername", "scott");
        servletRegistrationBean.addInitParameter("loginPassword", "tiger");
        // Is it possible to reset the data
        servletRegistrationBean.addInitParameter("resetEnable", "false");
        return servletRegistrationBean;
    }

    /**
     * Configure Druid Service Filters
     * @return Return filter configuration object
     */
    @Bean
    public FilterRegistrationBean statFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        // Add Filter Rule
        filterRegistrationBean.addUrlPatterns("/*");
        // Ignore filter formats
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*,");
        return filterRegistrationBean;
    }
}

Create related page s

  • dao

    • DAO must be @Mapper to be created by Spring
    package com.trkj.oraclemybatis.dao;
    
    import com.trkj.oraclemybatis.entity.Dept;
    import org.apache.ibatis.annotations.Mapper;
    
    @Mapper
    public interface DeptDao {
        int deleteByPrimaryKey(Short deptno);
    
        int insert(Dept record);
    
        int insertSelective(Dept record);
    
        Dept selectByPrimaryKey(Short deptno);
    
        int updateByPrimaryKeySelective(Dept record);
    
        int updateByPrimaryKey(Dept record);
    }
    
  • entity

    package com.trkj.oraclemybatis.entity;
    
    import java.io.Serializable;
    import lombok.Data;
    
    /**
     * DEPT
     * @author 
     */
    @Data
    public class Dept implements Serializable {
        private Short deptno;
    
        private String dname;
    
        private String loc;
    
        private static final long serialVersionUID = 1L;
    }
    
  • service

    public interface DeptService {
        public Dept findDeptById(Short deptno);
    }
    
    @Service
    public class DeptServiceImpl implements DeptService {
        
        @Resource
        private DeptDao deptDao;
        @Override
        public Dept findDeptById(Short deptno) {
            return deptDao.selectByPrimaryKey(deptno);
        }
    }
    
    
  • controller

    @RestController
    @Slf4j
    public class DeptController {
        @Autowired
        private DeptService deptService;
        @GetMapping("/dept/{id}")
        public Dept selectFindById(@PathVariable("id") Short deptno){
            return  deptService.findDeptById(deptno);
        }
    }
    

Integrate JPA

Import JPA Starter Dependency Library

[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-IwJwdbKW-1638550633747)(SpringBoot.assets/image-20210429162318432.png)]

<properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.oracle.database.jdbc</groupId>
            <artifactId>ojdbc8</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>cn.easyproject</groupId>
            <artifactId>orai18n</artifactId>
            <version>12.1.0.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.21</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>jakarta.validation</groupId>
            <artifactId>jakarta.validation-api</artifactId>
        </dependency>
    </dependencies>

.yml

server:
  port: 8088
  #Connection pool configuration
  servlet:
    context-path: /jpaboot
spring:
  datasource:
    url: jdbc:oracle:thin:@127.0.0.1:1521:orcl
    username: scott
    password: tiger
    driver-class-name: oracle.jdbc.driver.OracleDriver
      #mysql is configured as follows:
      #url: jdbc:mysql://127.0.0.1:3308/mydb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
      #username: root
      #password: root2020
      #driver-class-name: com.mysql.cj.jdbc.Driver
      # Use druid data source
    #type: com.alibaba.druid.pool.DruidDataSource

    # Use druid data source
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      # Configure Test Query Statement
      validationQuery: SELECT 1 FROM DUAL
      # Initialization size, minimum, maximum
      initialSize: 10
      minIdle: 10
      maxActive: 200
      # Configure a connection's minimum lifetime in milliseconds in the pool
      minEvictableIdleTimeMillis: 180000
      testOnBorrow: false
      testWhileIdle: true
      removeAbandoned: true
      removeAbandonedTimeout: 1800
      logAbandoned: true
      # Open the PSCache and specify the size of the PSCache on each connection
      poolPreparedStatements: true
      maxOpenPreparedStatements: 100
      # Configure filters intercepted by monitoring statistics, sql cannot be counted after removal,'wall'for firewall
      filters: stat,wall
  jpa:
    database: ORACLE
    database-platform: org.hibernate.dialect.OracleDialect
    show-sql: true
    format-sql: true
    hibernate:
      ddl-auto: update

If it is Mysql then
jpa:
database: mysql
database-platform: org.hibernate.dialect.MySQL5Dialect
show-sql: true
hibernate:
ddl-auto: update

Configure druid connection pool, data source monitoring

Define the configuration class (see note, as with mybaits)
Add druid StatViewServlet to display Druid statistics
To use functionality that uses other Servlet or fiter components, Spring boot must borrow the Servlet RegistrationBean interface provided by Spring Boot
Configure Druid Service Filters
Access address: http://localhost:8088/druid/login.html

@Configuration
public class DataSourceConfig {
 
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        return DruidDataSourceBuilder.create().build();
    }
    /**
     * Configure Monitoring Server
     * @return Returns a monitor registered servlet object
     * @author SimpleWu
     */
    @Bean
    public ServletRegistrationBean statViewServlet() {
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        // Add IP Whitelist
        servletRegistrationBean.addInitParameter("allow", "127.0.0.1");
        // Add IP blacklist, which takes priority when the whitelist and blacklist are duplicated
        //servletRegistrationBean.addInitParameter("deny", "127.0.0.1");
        // Add Console Management User
        servletRegistrationBean.addInitParameter("loginUsername", "root");
        servletRegistrationBean.addInitParameter("loginPassword", "root2020");
        // Is it possible to reset the data
        servletRegistrationBean.addInitParameter("resetEnable", "false");
        return servletRegistrationBean;
    }

    /**
     * Configure Druid Service Filters
     * @return Return filter configuration object
     */
    @Bean
    public FilterRegistrationBean statFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        // Add Filter Rule
        filterRegistrationBean.addUrlPatterns("/*");
        // Ignore filter formats
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*,");
        return filterRegistrationBean;
    }
}

Configure JPA

  • Configuration classes for jpa can be configured separately, and configurations in yml can be used directly without special requirements.
  • Comment on this class, program is still executable
  • This class can be configured in multiple data sources
@Slf4j
@Configuration
@EnableTransactionManagement   // Turn on annotation transaction management, equivalent to <tx:annotation-driven />in the xml configuration file
@EnableJpaRepositories(
        // Entity Management Factory Reference Name, corresponding to the method for the @Bean annotation
        entityManagerFactoryRef="entityManagerFactory",
        //Transaction management factory reference name, corresponding to method for @Bean annotation
        transactionManagerRef="transactionManager",
        basePackages= { "com.trkj.jpaboot.dao" }) //Set Repository Location
public class JpaDataConfig {
    @Resource
    @Qualifier("japDataSource")
    private DataSource japDataSource;        //primary data source injection
    @Value("${spring.jpa.database-platform}")
    private  String primaryDialect;
    @Value("${spring.jpa.database}")
    private String dataBase;
    @Value("${spring.jpa.show-sql}")
    private String showSql;
    @Value("${spring.jpa.hibernate.ddl-auto}")
    private String ddlAuto;
    @Value("${spring.jpa.format-sql}")
    private String formatSql;

    @Bean(name = "entityManager")        //primary Entity Manager
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return entityManagerFactory(builder).getObject().createEntityManager();
    }
    @Bean(name = "entityManagerFactory")    //primary Entity Factory
    public LocalContainerEntityManagerFactoryBean entityManagerFactory (EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(japDataSource)
                .properties(getVendorProperties())
                .packages("com.trkj.jpaboot.entity")     //Set the location of the entity class
                .persistenceUnit("primaryPersistenceUnit")
                .build();
    }
    @Autowired
    private HibernateProperties hibernateProperties;
    @Autowired
    private JpaProperties jpaProperties;
    private Map getVendorProperties() {
        jpaProperties.getProperties().put("hibernate.show_sql",showSql);
        jpaProperties.getProperties().put("hibernate.format_sql",formatSql);
        //jpaProperties.getProperties().put("hibernate.dialect","org.hibernate.dialect.Oracle10gDialect");
        jpaProperties.getProperties().put("database-platform",primaryDialect);
        jpaProperties.setDatabase(Database.valueOf(dataBase));
        hibernateProperties.setDdlAuto(ddlAuto);
        return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(),new HibernateSettings());
    }
    @Bean(name = "transactionManager")         //Transaction Manager
    public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactory(builder).getObject());
    }
}

Generating POJO from JPA tools

@Data
@Validated
public class DeptVo {
    @Max(value = 10000,message = "Number cannot exceed 100000")
    private long deptno;
    @NotEmpty(message = "Name cannot be empty")
    private String dname;
    private String loc;
}

@Entity
@Table(name = "DEPT", schema = "SCOTT", catalog = "")
public class DeptEntity {
    private long deptno;
    private String dname;
    private String loc;

    @Id
    @Column(name = "DEPTNO")
    public long getDeptno() {
        return deptno;
    }

    public void setDeptno(long deptno) {
        this.deptno = deptno;
    }

    @Basic
    @Column(name = "DNAME")
    public String getDname() {
        return dname;
    }

    public void setDname(String dname) {
        this.dname = dname;
    }

    @Basic
    @Column(name = "LOC")
    public String getLoc() {
        return loc;
    }

    public void setLoc(String loc) {
        this.loc = loc;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        DeptEntity that = (DeptEntity) o;
        return deptno == that.deptno &&
                Objects.equals(dname, that.dname) &&
                Objects.equals(loc, that.loc);
    }

    @Override
    public String toString() {
        return "DeptEntity{" +
                "deptno=" + deptno +
                ", dname='" + dname + '\'' +
                ", loc='" + loc + '\'' +
                '}';
    }

    @Override
    public int hashCode() {
        return Objects.hash(deptno, dname, loc);
    }
}

Define DAO

import com.trkj.jpaboot.entity.DeptEntity;
import org.springframework.data.repository.CrudRepository;

public interface DeptDao extends CrudRepository<DeptEntity,Integer> {

}

Define Service

public interface DeptService {
    public DeptEntity addDeptEntity(DeptEntity dept);
    public DeptEntity editDept(DeptEntity dept);
    public DeptEntity findDept(DeptEntity dept);
}



@Service
@Slf4j
public class DeptServiceImpl implements DeptService {
    @Autowired
    private DeptDao deptDao;


    @Transactional(transactionManager = "transactionManager")
    public DeptEntity addDeptEntity(DeptEntity dept) {
        log.info("addDeptEntity insert data..................");
        log.info(dept.toString());
        deptDao.save(dept);
        log.info("addDeptEntity insert data over..................");
        return dept;
    }


    @Override
    @Transactional(transactionManager = "transactionManager")
    public DeptEntity editDept(DeptEntity dept) {
        return this.deptDao.save(dept);
    }

    @Override
    public DeptEntity findDept(DeptEntity dept) {
        long id=dept.getDeptno();
        DeptEntity entity=this.deptDao.findById((int)id).orElse(null);
        return entity ;
    }
}

Define Controller

@RestController
@Slf4j
public class IndexController {
    @Autowired
    private DeptService deptService;
    @PostMapping("/dept")
    public AjaxResponse addDept(@RequestBody @Valid DeptVo detpVo){
        log.info("Start inserting data.");
        DeptEntity dept=new DeptEntity();
        BeanUtils.copyProperties(detpVo,dept);
        deptService.addDeptEntity(dept);
        AjaxResponse response=AjaxResponse.success(dept);
        return response;
    }
    @PutMapping("/dept")
    public AjaxResponse editDept(@RequestBody @Valid DeptVo detpVo){
        log.info("Start modifying.");
        DeptEntity dept=new DeptEntity();
        BeanUtils.copyProperties(detpVo,dept);
        deptService.editDept(dept);
        AjaxResponse response=AjaxResponse.success(dept);
        return response;
    }
}

Integrating Mybatis with JPA

  • Integrate both JPA and MyBatis
  • Import Maven Dependency Library
  • Define the data source class (same as above)
  • Configure druid connection pool (same example), MyBatis, jpa
  • Define jpa related entity\DAO\profile
  • Define MyBatis Related Entity\DAO\Profile
  • Define Service Business Class
  • Define Controller Controller Controller

Cross-domain Configuration Class

@Configuration
@Slf4j
public class AppCorsConfiguration {
    private CorsConfiguration buildConfig() {
        log.debug("Start Setting");
        CorsConfiguration appCorsConfiguration = new CorsConfiguration();
        appCorsConfiguration.addAllowedOrigin("http://localhost:8082");
        appCorsConfiguration.addAllowedOrigin("http://127.0.0.1:8081");
        appCorsConfiguration.addAllowedOrigin("http://localhost:8082");
        appCorsConfiguration.addAllowedOrigin("http://127.0.0.1:8082");
        appCorsConfiguration.addAllowedHeader("*"); // 2 Allow any header
        appCorsConfiguration.addAllowedMethod("OPTIONS");
        appCorsConfiguration.addAllowedMethod("HEAD");
        appCorsConfiguration.addAllowedMethod("GET");
        appCorsConfiguration.addAllowedMethod("PUT");
        appCorsConfiguration.addAllowedMethod("POST");
        appCorsConfiguration.addAllowedMethod("DELETE");
        appCorsConfiguration.addAllowedMethod("PATCH");
        appCorsConfiguration.setAllowCredentials(true);//You cannot upload files across domains without adding these two sentences.
        appCorsConfiguration.setMaxAge(3600L);//Add it in
        return appCorsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); // 4
        return new CorsFilter(source);
    }
}

Deactivate Port

1. >   netstat -ano|findstr 8080

2. >   >taskkill /pid 15184 /F

antic

Change name when serializing

//Display as name when displaying json format
@JsonProperty("name")
 private String dname;

ss AppCorsConfiguration {
private CorsConfiguration buildConfig() {
Log.debug (Start Setup);
CorsConfiguration appCorsConfiguration = new CorsConfiguration();
appCorsConfiguration.addAllowedOrigin("http://localhost:8082");
appCorsConfiguration.addAllowedOrigin("http://127.0.0.1:8081");
appCorsConfiguration.addAllowedOrigin("http://localhost:8082");
appCorsConfiguration.addAllowedOrigin("http://127.0.0.1:8082");
AppCorsConfiguration.addAllowedHeader ('*'); // 2 Allow any header
appCorsConfiguration.addAllowedMethod("OPTIONS");
appCorsConfiguration.addAllowedMethod("HEAD");
appCorsConfiguration.addAllowedMethod("GET");
appCorsConfiguration.addAllowedMethod("PUT");
appCorsConfiguration.addAllowedMethod("POST");
appCorsConfiguration.addAllowedMethod("DELETE");
appCorsConfiguration.addAllowedMethod("PATCH");
appCorsConfiguration.setAllowCredentials(true);// You cannot upload files across domains without adding these two sentences.
appCorsConfiguration.setMaxAge(3600L);// Add it in
return appCorsConfiguration;
}

@Bean
public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", buildConfig()); // 4
    return new CorsFilter(source);
}

}

# Deactivate Port

```cmake
1. >   netstat -ano|findstr 8080

2. >   >taskkill /pid 15184 /F

antic

Change name when serializing

//Display as name when displaying json format
@JsonProperty("name")
 private String dname;

Tags: Java Mybatis Spring Spring Boot jpa

Posted on Fri, 03 Dec 2021 17:20:38 -0500 by djs1