文档章节

SpringBoot+rest接口+swagger2生成API文档+validator+mybatis+aop+国际化

文小杰
 文小杰
发布于 2017/09/08 13:37
字数 1964
阅读 15
收藏 2
点赞 0
评论 0

我的博客园文章地址

代码地址:JillWen_SpringBootDemo

mybatis

1. 添加依赖:

<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
            <version>${mybatis.version}</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<!--这里如果不写版本会自动继承spring-boot-starter-parent里的版本号-->
			<version>${mysql.version}</version>
</dependency>

2. dao层定义UserMapper.xml文件和UserMapper类

3. 使用注意:

  1. 使用mybatisGenerator插件(idea里直接装需要收费,参考:http://blog.csdn.net/luanlouis/article/details/43192131)
  2. 添加依赖
<plugin>
               <groupId>org.mybatis.generator</groupId>
               <artifactId>mybatis-generator-maven-plugin</artifactId>
               <version>${mybatis-generator.version}</version>
               <configuration>
                   <verbose>true</verbose>
                   <overwrite>true</overwrite>
               </configuration>
</plugin>

添加一个“Run运行”选项,使用maven运行mybatis-generator-maven-plugin插件, 在 “Command line” 选项中输入“mybatis-generator:generate -e”

  1. 当mapper.xml文件不是放在resource文件下时,需要加插件将其生成到target里。 每次修改后需要install。
<plugin>
				<artifactId>maven-resources-plugin</artifactId>
				<version>2.5</version>
				<executions>
					<execution>
						<id>copy-xmls</id>
						<phase>process-sources</phase>
						<goals>
							<goal>copy-resources</goal>
						</goals>
						<configuration>
							<outputDirectory>${basedir}/target/classes</outputDirectory>
							<resources>
								<resource>
									<directory>${basedir}/src/main/java</directory>
									<includes>
										<include>**/*.xml</include>
									</includes>
								</resource>
							</resources>
						</configuration>
					</execution>
				</executions>
</plugin>
  1. 只添加@Mapper注解或者(@MapperScan("com.example.demo.server.dao")) 时idea会报错,但是可以运行,所以强迫症可以加一个@Repository。

restful接口

1. restful接口定义

(参考:http://websystique.com/spring-boot/spring-boot-rest-api-example/):

  • GET request to /users/ returns a list of users
  • GET request to /users/1 returns the user with ID 1
  • POST request to /users/ with a user object as JSON creates a new user
  • PUT request to /users/1 with a user object as JSON updates the user with ID 1
  • DELETE request to /users/1 deletes the user with ID 1
  • DELETE request to /users/ deletes all the users

2. controller里主要代码

@Autowired
   IUserService userService;

   /**
    * 查询所有用户
    * @return
    */
   @RequestMapping(value = "/", method = RequestMethod.GET)
   public List<User> listAllUsers() {
       List<User> users = userService.findAllUsers();
       return users;
   }

   /**
    * 根据id查询用户
    * @param id
    * @return
    */
   @RequestMapping(value = "/{id}", method = RequestMethod.GET)
   public User getUser(@PathVariable("id") int id) {
       logger.info("Fetching User with id {}", id);
       User user = userService.findById(id);
       if (user == null) {
           logger.error("User with id {} not found.", id);
       }
       return user;
   }

   /**
    * 新建一个用户
    * @param user
    * @return
    */
   @RequestMapping(value = "/", method = RequestMethod.POST)
   public String createUser(@ModelAttribute  User user) {
       //除了@ModelAttribute绑定参数之外,还可以通过@RequestParam从页面中传递参数/RequestBody ?
       logger.info("Creating User : {}", user);
       User exitUser = new User();
       exitUser.setId(user.getId());
       if (userService.isUserExist(exitUser)) {
           logger.error("Unable to create. A User with id {} already exist", exitUser.getId());
       }
       userService.saveUser(user);
       return "success";
   }

   /**
    * 根据id更新用户信息
    * @param id
    * @param user
    * @return
    */
   @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
   public String updateUser(@PathVariable("id") int id, @ModelAttribute User user) {
       //RequestBody
       logger.info("Updating User with id {}", id);

       User currentUser = userService.findById(id);

       if (currentUser == null) {
           logger.error("Unable to update. User with id {} not found.", id);
           return "fail";
       }
       currentUser.setName(user.getName());
       currentUser.setAge(user.getAge());
       userService.updateUser(currentUser);
       return "success";
   }

   /**
    * 根据id删除用户
    * @param id
    * @return
    */
   @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
   public String deleteUser(@PathVariable("id") int id) {
       logger.info("Fetching & Deleting User with id {}", id);

       User user = userService.findById(id);
       if (user == null) {
           logger.error("Unable to delete. User with id {} not found.", id);
           return "fail";
       }
       userService.deleteUserById(id);
       return "success";
   }


   /**
    * 删除所有用户
    * @return
    */
   @RequestMapping(value = "/", method = RequestMethod.DELETE)
   public String deleteAllUsers() {
       logger.info("Deleting All Users");

       userService.deleteAllUsers();
       return "success";
   }

3.使用swagger2生成api文档

(参考http://blog.didispace.com/springbootswagger2/)

  1. 引入依赖
<dependency>
           <groupId>io.springfox</groupId>
           <artifactId>springfox-swagger2</artifactId>
           <version>2.2.2</version>
       </dependency>
       <dependency>
           <groupId>io.springfox</groupId>
           <artifactId>springfox-swagger-ui</artifactId>
           <version>2.2.2</version>
</dependency>
  1. 创建Swagger2配置类
@Configuration
@EnableSwagger2
public class Swagger2 {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example.demo.server.controller"))
                .paths(PathSelectors.any())
                .build();
    }
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Spring Boot中使用Swagger2构建RESTful APIs")
                .description("使用Swagger2构建RESTful APIs")
                .termsOfServiceUrl("http://www.wjcoding.cn/")
                .contact("Jill")
                .version("1.0")
                .build();
    }
}
  1. controller里使用:
@ApiOperation(value="创建用户", notes="根据User对象创建用户")
    @ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User")
    @RequestMapping(value = "/", method = RequestMethod.POST)
    public String createUser(@ModelAttribute  User user) {
    //代码略
    }
  1. 查看api文档: 启动Spring Boot程序,访问:http://localhost:8080/swagger-ui.html

国际化

(参考博客:http://412887952-qq-com.iteye.com/blog/2312274)

1. 页面中使用国际化

创建messages.properties(messages_zh_CN.properties,messages_en_US.properties)文件 thymeleaf里使用#{key}显示,例如:<p th:text="#{welcome}"></p>

2. 国际化文件相关配置

#指定message的basename,多个以逗号分隔,如果不加包名的话,默认从classpath路径开始,默认: messages spring.messages.basename=i18n/messages #设定加载的资源文件缓存失效时间,-1的话为永不过期,默认为-1 spring.messages.cache-seconds=3600 #设定Message bundles的编码,默认: UTF-8 #spring.messages.encoding=UTF-8

3. 代码中使用国际化

  1. 创建messages.properties(messages_zh_CN.properties,messages_en_US.properties)文件
  2. 代码里先获取区域,再国际化信息:
Locale locale = LocaleContextHolder.getLocale();
(或者Locale locale = RequestContextUtils.getLocale(request);)
String msg = messageSource.getMessage("welcome", null,locale);
  • 区域解析器 默认:AcceptHeaderLocaleResolver 根据HTTP请求的头部信息accept-language来解析区域

  • 会话区域解析器:SessionLocaleResolver

@Bean
  public LocaleResolver localeResolver() {
      SessionLocaleResolver slr = new SessionLocaleResolver();
      //设置默认区域
      slr.setDefaultLocale(Locale.CHINA);
      return slr;
  }
request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, new Locale("en", "US"))
  • Cookie区域解析器:CookieLocaleResolver
@Bean
    public LocaleResolver localeResolver() {
       CookieLocaleResolver slr = new CookieLocaleResolver();
        //设置默认区域
        slr.setDefaultLocale(Locale.CHINA);
        slr.setCookieMaxAge(3600);//设置cookie有效期.
        returnslr;
    }
  • 固定的区域解析器:FixedLocaleResolver
@Bean
    public LocaleResolver localeResolver() {
       FixedLocaleResolver slr = new FixedLocaleResolver ();
        //设置默认区域
        slr.setDefaultLocale(Locale.US);
        returnslr;
    }
  • 使用参数修改用户的区域 将LocaleChangeInterceptor拦截器应用到处理程序映射中,它会发现当前HTTP请求中出现的特殊参数。 其中的参数名称可以通过拦截器的paramName属性进行自定义。 如果这种参数出现在当前请求中,拦截器就会根据参数值来改变用户的区域。
@Bean
 public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
        // 设置请求地址的参数,默认为:locale
        // lci.setParamName(LocaleChangeInterceptor.DEFAULT_PARAM_NAME);
        return lci;
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
   registry.addInterceptor(localeChangeInterceptor());
}

注意这个是可以和会话区域解析器以及Cookie区域解析器一起使用的, 但是不能和FixedLocaleResolver一起使用,否则会抛出异常信息。

aop

(参考:http://blog.didispace.com/springbootaoplog/)

1. 添加依赖

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. 使用:

实现AOP的切面主要有以下几个要素:

  • 使用@Aspect注解将一个java类定义为切面类
  • @Order(i)注解来标识切面的优先级。i的值越小,优先级越高。
    1. 在切入点前的操作,按order的值由小到大执行
    1. 在切入点后的操作,按order的值由大到小执行
  • 使用@Pointcut定义一个切入点,可以是一个规则表达式,比如下例中某个package下的所有函数,也可以是一个注解等。 根据需要在切入点不同位置的切入内容
  • 使用@Before在切入点开始处切入内容
  • 使用@After在切入点结尾处切入内容
  • 使用@AfterReturning在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
  • 使用@Around在切入点前后切入内容,并自己控制何时执行切入点自身的内容
  • 使用@AfterThrowing用来处理当切入内容部分抛出异常之后的处理逻辑
@Aspect
@Component
@Order(1)
public class WebLogAspect {
    private Logger logger = Logger.getLogger(WebLogAspect.class);
    ThreadLocal<Long> startTime = new ThreadLocal<>();

    @Pointcut("execution(public * com.example.demo.server.controller..*.*(..))")
    public void webLog(){}

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        startTime.set(System.currentTimeMillis());
        // 接收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        // 记录下请求内容
        logger.info("URL : " + request.getRequestURL().toString());
        logger.info("HTTP_METHOD : " + request.getMethod());
        logger.info("IP : " + request.getRemoteAddr());
        logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        logger.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));
    }

    @AfterReturning(returning = "ret",pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 处理完请求,返回内容
        logger.info("RESPONSE : " + ret);
        logger.info("RESPONSE : " + ret);
        logger.info("SPEND TIME : " + (System.currentTimeMillis() - startTime.get()));
    }
}

validator

(参考http://www.jianshu.com/p/a9b1e2f7a749)

1. 添加限制

//这里不能用@NotBlank,因为id类型为int
  private int id;

  //使用groups属性来给分组命名,然后在需要的地方指定命令即可
  @NotBlank(groups=NAME.class)
  private String name;

  @Min(1)
  private Integer age;

2. 使用验证

@RestController
public class ValidateController {
    @RequestMapping(value="testUser")
    public void testStudent(@Validated User user) {
    }

    @RequestMapping(value="testUser1")
    public void testStudent1(@Validated(User.NAME.class) User user) {
    }
}

使用 @ScriptAssert 注解校验复杂的业务逻辑: 如果需要校验的业务逻辑比较复杂,可以使用@ScriptAssert来指定进行校验的方法, 通过方法来进行复杂业务逻辑的校验,然后返回 true或false来表明是否校验成功。

@ScriptAssert(lang="javascript",script="com.learn.validate.domain
.Student.checkParams(_this.name,_this.age,_this.classes)",
groups=CHECK.class)
public class Student {
//其他代码
/注意进行校验的方法要写成静态方法,否则会出现
 //TypeError: xxx is not a function 的错误
 public static boolean checkParams(String name,int age,String classes) {
  if(name!=null&&age>8&classes!=null)
  {
   return true;
  }
  else
  {
   return false;
  }
 }
}

3. 注意:

在Hibernate Validator(org.hibernate.validator.constraints)中:

@NotEmpty://CharSequence, Collection, Map 和 Array 对象不能是 null 并且相关对象的 size 大于 0。 @NotBlank://String 不是 null 且去除两端空白字符后的长度(trimmed length)大于 0。

© 著作权归作者所有

共有 人打赏支持
文小杰

文小杰

粉丝 12
博文 3
码字总数 4017
作品 0
长沙
程序员
使用Swagger2构建Spring Boot RESTful AIP 文档

上一篇我们介绍了如何使用Spring Boot快速构建RESTful API “Spring Boot与RESTful API ” ,本篇则介绍一个配合Spring Boot快速构建RESTful文档的工具 由于Spring Boot具有快速开发、便捷部...

老虎是个蛋蛋 ⋅ 2016/12/23 ⋅ 5

Swagger2 Zuul 整合

Swagger2 Swagger2是一个RESTful接口进行描述和展示的工具,可以通过 springfox-swagger2 整合,生成相应的文档,需引入两个库: 通过 @Configuration 注解为配置类,通过 @EnableSwagger2 ...

林塬 ⋅ 2017/12/28 ⋅ 0

SpringBoot接口文档自动生成

由于Spring Boot能够快速开发、便捷部署等特性,相信有很大一部分Spring Boot的用户会用来构建RESTful API。而我们构建RESTful API的目的通常都是由于多终端的原因,这些终端会共用很多底层业...

mkStone ⋅ 04/10 ⋅ 0

Spring Boot中使用Swagger2生成RESTful API文档(转)

效果如下图所示: 添加Swagger2依赖 在中加入Swagger2的依赖 注意:如果是2.2版本的,有可能在右下角会出现错误,那么请升级为2.7版本的即可解决这个问题。 创建Swagger2配置类 在同级创建S...

easonjim ⋅ 2017/09/13 ⋅ 0

spring boot 1.5.4 集成Swagger2构建Restful API(十八)

上一篇博客地址:springboot 1.5.4 整合rabbitMQ(十七) 1 Spring Boot集成Swagger2构建RESTful API文档 1.1 Swagger2简介 Swagger2官网:http://swagger.io/ 由于Spring Boot能够快速开发、...

wyait ⋅ 2017/11/03 ⋅ 0

Swagger使用指南

1:认识Swagger Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和...

玄影镜心 ⋅ 2016/12/19 ⋅ 0

SpringBoot集成SwaggerUI

Swagger是当前最好用的Restful API文档生成的开源项目,通过swagger-spring项目,实现了与SpingMVC框架的无缝集成功能,方便生成spring restful风格的接口文档,同时swagger-ui还可以测试spr...

黄步欢 ⋅ 2017/05/19 ⋅ 0

Spring Boot中使用Swagger2构建RESTful API文档

随着前后端的分离,借口文档变的尤其重要,今天我们来说一说用SWAGGER2,来风骚的生成api文档。配置很简单,废话少说,直接上代码: build.gradle SwaggerConfig.java DemoApplication.java...

不正经茂 ⋅ 2016/12/02 ⋅ 0

SpringMVC集成springfox-swagger2构建restful API

在集成springfox-swagger2之前,我也尝试着集成了swagger-springmvc,方式差不多,但是swagger-springmvc相对麻烦一点,因为要把它的静态文件copy到自己的项目中。所以还是用新版本的。 至于...

u014231523 ⋅ 2017/01/13 ⋅ 0

springboot 学习笔记【5】使用Swagger2构建RESTful APIs

接上一篇springboot 学习笔记【4】Spring Boot构建RESTful API***上一篇博客中写了一个简单的Restful接口的服务,在实际开发中我们的RESTful API就有可能要面对多个开发人员或多个开发团队:...

shane_zhou ⋅ 2016/11/02 ⋅ 2

没有更多内容

加载失败,请刷新页面

加载更多

下一页

C++内存映射文件居然是这样?!

内存映射文件大家都时不时听过,但它到底是个什么?赶紧来看看吧 内存映射文件到底是干嘛的呢?让我们先来思考下面几个问题: 如果您想读的内容大于系统分配的内存块怎么办?如果您想搜索的字...

柳猫 ⋅ 24分钟前 ⋅ 0

MySQL 数据库设计总结

规则1:一般情况可以选择MyISAM存储引擎,如果需要事务支持必须使用InnoDB存储引擎。 注意:MyISAM存储引擎 B-tree索引有一个很大的限制:参与一个索引的所有字段的长度之和不能超过1000字节...

OSC_cnhwTY ⋅ 今天 ⋅ 0

多线程(四)

线程池和Exector框架 什么是线程池? 降低资源的消耗 提高响应速度,任务:T1创建线程时间,T2任务执行时间,T3线程销毁时间,线程池没有或者减少T1和T3 提高线程的可管理性。 线程池要做些什...

这很耳东先生 ⋅ 今天 ⋅ 0

使用SpringMVC的@Validated注解验证

1、SpringMVC验证@Validated的使用 第一步:编写国际化消息资源文件 编写国际化消息资源ValidatedMessage.properties文件主要是用来显示错误的消息定制 [java] view plain copy edit.userna...

瑟青豆 ⋅ 今天 ⋅ 0

19.压缩工具gzip bzip2 xz

6月22日任务 6.1 压缩打包介绍 6.2 gzip压缩工具 6.3 bzip2压缩工具 6.4 xz压缩工具 6.1 压缩打包介绍: linux中常见的一些压缩文件 .zip .gz .bz2 .xz .tar .gz .tar .bz2 .tar.xz 建立一些文...

王鑫linux ⋅ 今天 ⋅ 0

6. Shell 函数 和 定向输出

Shell 常用函数 简洁:目前没怎么在Shell 脚本中使用过函数,哈哈,不过,以后可能会用。就像java8的函数式编程,以后获取会用吧,行吧,那咱们简单的看一下具体的使用 Shell函数格式 linux ...

AHUSKY ⋅ 今天 ⋅ 0

单片机软件定时器

之前写了一个软件定时器,发现不够优化,和友好,现在重写了 soft_timer.h #ifndef _SOFT_TIMER_H_#define _SOFT_TIMER_H_#include "sys.h"typedef void (*timer_callback_function)(vo...

猎人嘻嘻哈哈的 ⋅ 今天 ⋅ 0

好的资料搜说引擎

鸠摩搜书 简介:鸠摩搜书是一个电子书搜索引擎。它汇集了多个网盘和电子书平台的资源,真所谓大而全。而且它还支持筛选txt,pdf,mobi,epub、azw3格式文件。还显示来自不同网站的资源。对了,...

乔三爷 ⋅ 今天 ⋅ 0

Debian下安装PostgreSQL的表分区插件pg_pathman

先安装基础的编译环境 apt-get install build-essential libssl1.0-dev libkrb5-dev 将pg的bin目录加入环境变量,主要是要使用 pg_config export PATH=$PATH:/usr/lib/postgresql/10/bin 进......

玛雅牛 ⋅ 今天 ⋅ 0

inno安装

#define MyAppName "HoldChipEngin" #define MyAppVersion "1.0" #define MyAppPublisher "Hold Chip, Inc." #define MyAppURL "http://www.holdchip.com/" #define MyAppExeName "HoldChipE......

backtrackx ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部