使用Spring Boot 2.x构建Web服务的详细代码

目录
  • 架构:
  • 库:
  • 运行应用的步骤
  • 关于项目配置
  • Web服务声明
  • 示例
  • 通用错误处理
  • 示例
  • Spring Data(JPA)配置
  • Entity类
  • Repository接口
  • 在application.properties中的JPA数据库配置
  • 数据库配置
  • application.properties
  • application-dev.properties
  • application-pro.properties
  • 数据库密码加密
  • SampleWebservice.java
  • JWT身份验证配置
  • 创建令牌的过程
  • UnAuthorisedAccessServiceImpl.java
  • 过滤和验证令牌的过程
  • WebConfig.java
  • JwtAuthenticationTokenFilter.java
  • 应用用户密码加密
  • PasswordEncryptingService.java
  • 使用Slf4j配置日志
  • 示例
  • UserServiceImpl.java
  • 基于Swagger的API文档
  • Pom.xml
  • SwaggerAPIDocConfig.java
  • Postman脚本

架构:

  • MVC架构
  • 基于JWT的身份认证
  • Spring Data (JPA)
  • 应用用户密码加密
  • 数据库密码加密
  • SQL Server
  • Slf4j
  • 基于Swagger的API文档

库:

  • 应用源代码
  • 数据库的SQL脚本以及关键数据
  • 包含数据库配置信息的DB.txt文件
  • 用于测试Web服务的Postman JSON脚本

运行应用的步骤

  • 安装JDK11或最新版本
  • 克隆项目库到本地
  • Git地址:https://github.com/VishnuViswam/sample-web-service.git
  • 安装SQL server 2012
  • 创建应用数据库和用户
  • 插入数据库密钥数据
  • 将数据库密码的解码密钥添加到系统变量,它位于DB.txt文件中
  • 有时可能需要重新启动窗口以获取更新后的系统变量
  • 运行项目源代码
  • 导入预先提供的postman JSON脚本到postman客户端,调用Web服务

关于项目配置

Web服务声明

应用程序的每个Web服务都将在controller层中声明。

示例

@RequestMapping("/api/v1/user")
@RestController
@Validated
public class UserController {

  private static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @Autowired
   private GeneralServices generalServices;

   @Autowired
   private UserService userService;

   /**
     * Web service to create new user
     *
     * @param httpServletRequest
    * @param user
     * @return
    */
   @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
   public ResponseEntity<Object> createUser(HttpServletRequest httpServletRequest,
                                             @Valid @RequestBody UserCreateModel user) {
       logger.debug("<--- Service to save new user request : received --->");
       ApiSuccessResponse apiResponse = userService.createUser(user, generalServices.getApiRequestedUserId(httpServletRequest));
        logger.debug("<--- Service to save new user response : given --->");
       return ResponseEntity.status(HttpStatus.CREATED).body(apiResponse);

    }

}
  • @RequestMapping("/api/v1/user")注解用来声明Web服务的类别
  • @RestController注解配置该类来接收Restful的 Web服务调用
  • @PostMapping()注解决定了HTTP请求类型
  • consume和consume标记来确定HTTP请求和响应的内容类型

通过controller层,API请求将被带到服务层。所有业务逻辑都将在这里处理,然后它将使用JPA与数据库通信。

通用错误处理

每当异常发生时,它将从相应的类抛出,并在CommonExceptionHandlingController中处理。我们必须分别处理每种异常类型。这个功能是在ControllerAdvice注解的帮助下执行的。

示例

@ControllerAdvice
public class CommonExceptionHandlingController extends ResponseEntityExceptionHandler {

    private static final Logger logger = 
        LoggerFactory.getLogger(CommonExceptionHandlingController.class);
   @Override
    protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException httpRequestMethodNotSupportedException,
                                                                         HttpHeaders headers, HttpStatus status, WebRequest request) {
       return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ApiErrorResponse(Constants.WRONG_HTTP_METHOD,
                Constants.WRONG_HTTP_METHOD_ERROR_MESSAGE, Calendar.getInstance().getTimeInMillis()));
   }
   protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException methodArgumentNotValidException,
                                                                 HttpHeaders headers, HttpStatus status, WebRequest request) {
       return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiErrorResponse(Constants.MANDATORY_FIELDS_ARE_NOT_PRESENT_CODE,
               Constants.MANDATORY_FIELDS_ARE_NOT_PRESENT_ERROR_MESSAGE, Calendar.getInstance().getTimeInMillis()));

Spring Data(JPA)配置

  • 应用程序与数据库的所有交互都将由JPA处理
  • JPA将为应用程序中的所有逻辑对象提供一个Entity类和一个相应的Repository接口

Entity类

@Entity
@Table(name = "tbl_users")
public class Users implements Serializable {
   private static final long serialVersionUID = 1L;

  @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "id", columnDefinition = "bigint")
    private Long id;

  @OneToOne(fetch = FetchType.EAGER)
  @JoinColumn(name = "user_account_id", columnDefinition = "bigint", nullable = false)
   private UserAccounts userAccount;

Repository接口

public interface UserRepository extends JpaRepository<Users, Long> {

   /**
     * To find user object using username
     *
    * @param username
    * @return
     */
  Users findByUserAccountUsername(String username);
  • 其他的JPA配置将会在application.properties文件中完成

在application.properties中的JPA数据库配置

spring.jpa.show-sql=false
spring.jpa.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
spring.jpa.hibernate.ddl-auto = update

spring.jpa.properties.hibernate.show_sql=false
spring.jpa.properties.hibernate.format_sql=false
spring.jpa.properties.hibernate.use_sql=true
spring.jpa.open-in-view=false
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.hibernate.connection.provider_class=org.hibernate.hikaricp.internal.HikariCPConnectionProvider

数据库配置

  • 数据库名称写在application.properties文件中
  • 其他信息(比如URL连接地址和账号密码)将写到另外两个不同属性文件中

application-dev.properties

此处写开发环境的配置信息

application-pro.properties

此处写生产环境的配置信息

spring.profiles.active=dev
  • 上述提到的属性配置写到application.properties文件中
  • 它将决定系统使用哪个子配置文件(开发环境还是生产环境)

application.properties

#DB config
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver

application-dev.properties

#DB config
spring.datasource.url=jdbc:sqlserver://localhost:1433;databaseName=sample_webservice_db_dev
spring.datasource.username=dbuser
spring.datasource.password=ENC(tZTfehMYyz4EO0F0uY8fZItE7K35RtkA)
#spring.datasource.username=dbuser
#spring.datasource.password=dbuserpassword

application-pro.properties

#DB config
spring.datasource.url=jdbc:sqlserver://192.168.1.119:1433;databaseName=sample_webservice_db
spring.datasource.username=proUser
spring.datasource.password=ENC(proUserPswd)

数据库密码加密

  • 应用程序数据库密码会使用加密密钥通过__Jasypt __ 库加密。
  • 加密密钥需要添加到系统环境变量中的JASYPT_ENCRYPTOR_PASSWORD变量中。
  • 必须在属性文件中声明加密后的数据库密码。如此,系统就会了解密码需要解密,而解密则需要使用添加在系统变量中的密钥来进行。
spring.datasource.password=ENC(tZTfehMYyz4EO0F0uY8fZItE7K35RtkA)
  • 对于__Jasypt __加密,我们在属性文件中使用默认的加密配置,如下所示:
jasypt.encryptor.algorithm=PBEWithMD5AndDES
jasypt.encryptor.iv-generator-classname=org.jasypt.iv.NoIvGenerator
  • 我们也可以在应用的main方法中使用@EnableEncryptableProperties注解,规定数据库密码的加密配置

SampleWebservice.java

@SpringBootApplication
@EnableEncryptableProperties
public class SampleWebservice extends SpringBootServletInitializer {
--------
--------

JWT身份验证配置

  • 使用Spring Security实现基于JSON Web令牌的身份验证
  • 当用户登录成功时,我们会创建两个token(accessToken 和 refreshToken)并把他们返回给客户端
  • accessToken由私钥,过期时间(1小时),用户ID和角色名生成
  • refreshToken由私钥,过期时间(24小时),用户ID和角色名生成
  • 登陆成功后,每个API请求都需要在请求头Header中的Authorization键中添加accessToken
  • 在accessToken开头添加"bearer"字符串
  • 即为”bearer accessToken”
  • accessToken将会监控每一个Web服务请求
  • 如果accessToken过期,系统会以HTTP 401状态码回复请求
  • 此时客户端需要使用refreshToken重新获取accessToken
  • 然后我们会检查refreshToken的有效性,如果没有过期则会生成一个新的accessToken和refreshToken
  • 客户端会继续使用这些新令牌
  • 如果refreshToken也过期了,就需要用户使用账号密码重新登陆了

创建令牌的过程

UnAuthorisedAccessServiceImpl.java

@Override
   public ApiSuccessResponse userLoginService(String username, String password) {
      Tokens tokens = null;
       Users user = userService.findByUsername(username);
       if (user != null) {
           if (passwordEncryptingService.matches(password,
                   user.getUserAccount().getPassword())) {
               if (user.getUserAccount().getStatus() == Constants.ACTIVE_STATUS) {
                   String roleName = user.getUserAccount().getUserRole().getRoleName();
                   // Creating new tokens
                  try {
                       tokens = createTokens(user.getUserAccount().getId().toString(), roleName);
                  } catch (Exception exception) {
                        logger.error("Token creation failed : ", exception);
                      throw new UnknownException();
                   }

                   // Validating tokens
                  if (validationService.validateTokens(tokens)) {
                       tokens.setUserId(user.getUserAccount().getId());
                     return new ApiSuccessResponse(tokens);
                  } else {
                       throw new UnknownException();
                  }
              } else {
                 return new ApiSuccessResponse(new ApiResponseWithCode(Constants.USER_ACCOUNT_IS_INACTIVE_ERROR_CODE,
                           Constants.USER_ACCOUNT_IS_INACTIVE_ERROR_MESSAGE));
             }
          } else {
              return new ApiSuccessResponse(new ApiResponseWithCode(Constants.USERNAME_OR_PASSWORD_IS_INCORRECT_ERROR_CODE,
                       Constants.USERNAME_OR_PASSWORD_IS_INCORRECT_ERROR_MESSAGE));
           }
      } else {
           return new ApiSuccessResponse(new ApiResponseWithCode(Constants.USERNAME_OR_PASSWORD_IS_INCORRECT_ERROR_CODE,
                  Constants.USERNAME_OR_PASSWORD_IS_INCORRECT_ERROR_MESSAGE));
       }
    }
    @Override
   public ApiSuccessResponse createNewAccessTokenUsingRefreshToken(String refreshToken) {
        UserAccounts userAccount = null;
       AppConfigSettings configSettings = appConfigSettingsService.findByConfigKeyAndStatus(Constants.JWT_SECRET_KEY,
               Constants.ACTIVE_STATUS);
      // Validate Refresh token
       userAccount = jwtTokenHandler.validate(configSettings.getConfigValue(), refreshToken);
       if (userAccount != null) {
            // Creating new tokens if provided refresh token is valid
           try {
               tokens = createTokens(userAccount.getId().toString(), userAccount.getRole());
           } catch (Exception exception) {
              logger.error("Token creation failed : ", exception);
               throw new UnknownException();
          if (validationService.validateTokens(tokens)) {
               tokens.setUserId(userAccount.getId());
              return new ApiSuccessResponse(tokens);
           } else {
          }
       } else {
           return new ApiSuccessResponse(new ApiResponseWithCode(Constants.REFRESH_TOKEN_EXPIRED_ERROR_CODE,
                  Constants.REFRESH_TOKEN_EXPIRED_ERROR_MESSAGE));
      }
   }
  • 上述代码中的userLoginService方法会检查用户凭据,如果有效则颁发令牌。
  • CreateNewAccessTokenUsingRefreshToken方法会在refreshToken验证成功后,生成新的accessToken和refreshToken。

过滤和验证令牌的过程

WebConfig.java

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebConfig extends WebSecurityConfigurerAdapter {

   @Autowired
   private JwtAuthenticationProvider authenticationProvider;
    @Autowired
   private JwtAuthenticationEntryPoint entryPoint;
    @Bean
    public AuthenticationManager authenticationManager() {
        return new ProviderManager(Collections.singletonList(authenticationProvider));
   }
  public JwtAuthenticationTokenFilter authenticationTokenFilter() {
      JwtAuthenticationTokenFilter filter = new JwtAuthenticationTokenFilter();
        filter.setAuthenticationManager(authenticationManager());
      filter.setAuthenticationSuccessHandler(new JwtSuccessHandler());
        return filter;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
       http.csrf().disable()
               .exceptionHandling().authenticationEntryPoint(entryPoint).and().sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
             .addFilterBefore(new WebSecurityCorsFilter(), ChannelProcessingFilter.class)
               .addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class)
                .headers().cacheControl();
    }
}
  • 这个配置将使用@EnableWebSecurity和@EnableGlobalMethodSecurity(prePostEnabled = true)两个注解来启用spring security模块
  • 这里,我们将把JWT过滤器注入到系统的HTTP请求中

JwtAuthenticationTokenFilter.java

public class JwtAuthenticationTokenFilter extends AbstractAuthenticationProcessingFilter {

   private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
   private GeneralServices generalServices;
  public JwtAuthenticationTokenFilter() {
       super("/api/**");
   }
    @Override
    public Authentication attemptAuthentication(HttpServletRequest httpServletRequest,
                                                HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {
                                                 -------
                                                 --------
  • 在如上的类中,JwtAuthenticationTokenFilter()的方法将过滤所有URL中含有“api”命名关键字的Web服务请求
  • 所有经过过滤的Web服务请求将到达attemptAuthentication方法
  • 我们可以在这个方法里处理所有的业务逻辑

应用用户密码加密

  • 该应用中所有的用户密码都将会使用BCrypt加密

PasswordEncryptingService.java

public class PasswordEncryptingService {

    public String encode(CharSequence rawPassword) {
        return BCrypt.hashpw(rawPassword.toString(), BCrypt.gensalt(6));
    }

    public boolean matches(CharSequence rawPassword, String encodedPassword) {
        return BCrypt.checkpw(rawPassword.toString(), encodedPassword);
    }
  • 这里,encode方法用来加密密码
  • matches方法用来交叉检查提供的密码和用户的实际密码

使用Slf4j配置日志

  • 在一个叫logback-spring.xml的文件中配置日志
  • 为了记录每个类的日志,我们需要在相应的类中注入Slf4j

示例

UserServiceImpl.java

@Service("UserService")
@Scope("prototype")
public class UserServiceImpl implements UserService {
    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
  • 上面的代码片段显示了我们如何将类注入到logger
  • 以下是记录日志的一些基本方法

logger.error("Error");

logger.info("Info");

logger.warn("Warn");

基于Swagger的API文档

  • API文档在Web服务应用程序中扮演着重要的角色
  • 之前,我们使用静态Excel文档创建API文档
  • 这个库将帮助我们在应用程序中使用注释创建API文档

Pom.xml

  <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>${springfox.swagger.version}</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${springfox.swagger.version}</version>
        </dependency>
  • 为了集成Swagger,上述这些是我们要在pom文件中添加的库
  • 我们需要在应用程序中做一些配置来启用API文档

SwaggerAPIDocConfig.java

@Configuration
@EnableSwagger2
public class SwaggerAPIDocConfig {

    public static final Contact DEFAULT_CONTACT = new Contact("Demo", "http://www.demo.ae/",
            "info@demo.ae");
    public static final ApiInfo DEFAUL_API_INFO = new ApiInfo("Sample Application",
            "Sample Application description.",
            "1.0.0",
            "http://www.sampleapplication.ae/",
            DEFAULT_CONTACT, "Open licence",
            "http://www.sampleapplication.ae/#license",
            new ArrayList<VendorExtension>());
    private static final Set<String> DEFAULT_PRODICERS_AND_CONSUMERS =
            new HashSet<>(Arrays.asList("application/json", "application/xml"));
    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(DEFAUL_API_INFO)
                .produces(DEFAULT_PRODICERS_AND_CONSUMERS)
                .consumes(DEFAULT_PRODICERS_AND_CONSUMERS)
                .select()
                .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
                .paths(PathSelectors.any())
                .build();
    }
}
  • 正如在上边的类中看到的,我们需要添加关于项目的基本信息
  • 我们需要告诉Swagger从哪个类创建API文档,这是在.apis(RequestHandlerSelectors.withClassAnnotation,(RestController.class))命名行下配置的
  • 我们可以通过http://localhost:8080/sampleWebService/apidoc来访问Swagger的API文档

Postman脚本

  • 我们可以在代码库中找到2个Postman JSON脚本,然后将它们导入到Postman客户端
  • 首先执行登陆的Web服务请求,然后执行其余web服务请求

到此这篇关于使用Spring Boot 2.x构建Web服务的详细代码的文章就介绍到这了,更多相关Spring Boot 2.x构建Web服务内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot2.x设置Session失效时间及失效跳转方式

    目录 设置Session失效时间及失效跳转 Session失效后如何跳转到Session失效地址 设置Session失效的几种方式 如果是1.5.6版本 还可以设置 设置Session失效时间及失效跳转 #Session超时时间设置,单位是秒,默认是30分钟  server.servlet.session.timeout=10 然而并没有什么用,因为SpringBoot在TomcatServletWebServerFactory代码中写了这个     private long getSessio

  • Springboot 2.x RabbitTemplate默认消息持久化的原因解析

    目录 前言 springboot测试 测试现象 源码分析 联想 前言 之前在Java直接测试mq消息持久化时,采取如下的配置实现消息的持久化: //消息持久化测试 Builder builder = new Builder(); builder.deliveryMode(2); BasicProperties properties = builder.build(); channel.basicPublish("", queue_name, properties, string.get

  • SpringBoot整合WebService服务的实现代码

    目录 为什么使用WebService? 适用场景: 不适用场景: Axis2与CXF的区别 SpringBoot使用CXF集成WebService WebService是一个SOA(面向服务的编程)的架构,它是不依赖于语言,不依赖于平台,可以实现不同的语言间的相互调用,通过Internet进行基于Http协议的网络应用间的交互. 其实WebService并不是什么神秘的东西,它就是一个可以远程调用的类,或者说是组件,把你本地的功能开放出去共别人调用. 为什么使用WebService? 简单解释一

  • springboot2.x引入feign踩的坑及解决

    目录 springboot2.x引入feign踩的坑 一.需求 二.什么是feign 三.springboot1.x中feign的使用 四.springboot2.x中feign的使用 feign调用方式比较 一.事发原因 二.方式1介绍 三.方式2介绍 四.调用结果测试 五.两种方式对比 六.小结一下 springboot2.x引入feign踩的坑 一.需求 最近公司项目需求,需要调用第三方服务的接口,所以选用了feign来实现(这里只说springboot2.x的pom引用,没有怎么使用,网

  • 使用SpringBoot内置web服务器

    目录 一.SpringBoot默认web服务器? 二.如何配置当前web容器? 三.内嵌Web服务器如何切换(从tomcat到jetty)? 四.Web容器怎么自动配置? 五.web容器启动源码解析? 六.SpringBoot内置服务器不使用SPI机制特别说明? 本文介绍SpringBoot内置web服务器.知识点有SpringBoot默认web服务器:如何配置当前web容器:内嵌Web服务器如何切换(从tomcat到jetty):Web容器怎么自动配置:web容器启动源码解析:SpringBo

  • SpringBoot2.x实现给Controller的RequestMapping添加统一前缀

    目录 给Controller的RequestMapping添加统一前缀 总结一下 有几个方法 springboot项目添加全局前缀 spring的配置 spring boot的配置 给Controller的RequestMapping添加统一前缀 如何给Controller的RequestMapping添加统一前缀,比如"/api",为什么要添加统一访问前缀,其实是为了后面的接口的管理. 切记:约定与规范好过一切技术处理 ! 比如: 项目A必须所有访问接口URL必须增加 /api/pr

  • 使用Spring Boot 2.x构建Web服务的详细代码

    目录 架构: 库: 运行应用的步骤 关于项目配置 Web服务声明 示例 通用错误处理 示例 Spring Data(JPA)配置 Entity类 Repository接口 在application.properties中的JPA数据库配置 数据库配置 application.properties application-dev.properties application-pro.properties 数据库密码加密 SampleWebservice.java JWT身份验证配置 创建令牌的过程

  • Spring Boot搭建文件上传服务的方法

    本文实例为大家分享了Spring Boot搭建文件上传服务的具体代码,供大家参考,具体内容如下 一.服务端 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http:/

  • Spring Boot 集成 Swagger2构建 API文档

    目录 一.Swagger是什么 1.SwaggerEditor 2.SwaggerUI 3.SwaggerCodegen 4.SwaggerUI 二.SpringBoot集成Swagger 1.创建SpringBoot项目 2.引入依赖 3.构建Swagger配置类 4.编写接口 5.查看并测试接口 前言: 不管你是从事前端还是后端开发,相信都难免被接口文档折磨过.如果你是一个前端开发者,可能你会经常发现后端给的接口文档跟实际代码有所出入.而假设你是一个后端开发者,你可能又会觉得自己开发后端接口

  • spring boot使用WebClient调用HTTP服务代码示例

    这篇文章主要介绍了spring boot使用WebClient调用HTTP服务代码示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 WebClient的请求模式属于异步非阻塞,能够以少量固定的线程处理高并发的HTTP请求 WebClient是Spring WebFlux模块提供的一个非阻塞的基于响应式编程的进行Http请求的客户端工具,从Spring5.0开始提供 在Spring Boot应用中 1.添加Spring WebFlux依赖 <d

  • Spring Boot 使用 Swagger 构建 RestAPI 接口文档

    源码地址:https://github.com/laolunsi/spring-boot-examples 目前SpringBoot常被用于开发Java Web应用,特别是前后端分离项目.为方便前后端开发人员进行沟通,我们在SpringBoot引入了Swagger. Swagger作用于接口,让接口数据可视化,尤其适用于Restful APi 本节分两部分介绍,第一部分是SpringBoot引入Swagger的两种方式,第二部分是详细介绍在Web接口上应用Swagger的注解. 本篇文章使用Sp

  • spring boot 1.5.4 web容器定制(端口号等修改)方法

    spring boot 默认采用tomcat作为嵌入的web容器 定制方式有三种 1. 2.如下 @Component public class CustomizationBean implements EmbeddedServletContainerCustomizer{ /** * 定制方法一:实现EmbeddedServletContainerCustomizer * @param container */ @Override public void customize(Configura

  • Spring Boot与Kotlin处理Web表单提交的方法

    我们在做web开发的时候,肯定逃不过表单提交,这篇文章通过Spring Boot使用Kotlin 语言 创建和提交一个表单. 下面我们在之前<Spring Boot 与 Kotlin使用Freemarker模板引擎渲染web视图>项目的基础上,增加处理表单提交. build.gradle 文件没有变化,这里贴一下完整的build.gradle group 'name.quanke.kotlin' version '1.0-SNAPSHOT' buildscript { ext.kotlin_v

  • Spring Boot和Docker实现微服务部署的方法

    Spring boot 开发轻巧的微服务提供了便利,Docker 的发展又极大的方便了微服务的部署.这篇文章介绍一下如果借助 maven 来快速的生成微服务的镜像以及快速启动服务. 其实将 Spring Boot 项目用 Docker 部署也不是什么多么神秘的技术,也要先生成镜像,再用镜像启动容器,如果说有什么方便的地方,也就是一些工具可以帮助我们节省手动操作的过程. 知识背景: 掌握 docker 的安装以及基本的操作,熟悉 Dockerfile 文件创建镜像的方法. 创建 Spring bo

  • 使用Python FastAPI构建Web服务的实现

    FastAPI是一个使用 Python 编写的 Web 框架,还应用了 Python asyncio 库中最新的优化.本文将会介绍如何搭建基于容器的开发环境,还会展示如何使用 FastAPI 实现一个小型 Web 服务. 起步 我们将使用 Fedora 作为基础镜像来搭建开发环境,并使用 Dockerfile 为镜像注入 FastAPI.Uvicorn和 aiofiles这几个包. FROM fedora:32 RUN dnf install -y python-pip \ && dnf

  • Spring Boot 与 Kotlin 上传文件的示例代码

    如果我们做一个小型的web站,而且刚好选择的kotlin 和Spring Boot技术栈,那么上传文件的必不可少了,当然,如果你做一个中大型的web站,那建议你使用云存储,能省不少事情. 这篇文章就介绍怎么使用kotlin 和Spring Boot上传文件 构建工程 如果对于构建工程还不是很熟悉的可以参考<我的第一个Kotlin应用> 完整 build.gradle 文件 group 'name.quanke.kotlin' version '1.0-SNAPSHOT' buildscript

随机推荐