SpringMVC+JWT+Swagger UI+RestFul
前言:
其实很早就想写这篇文章了,因为我觉得这会对很多新手有指引作用,当初自己也是瞎子过河的摸索着过来的。目前后台开发比较流行的MVC框架中使用Spring MVC还是比较多的,当然还有Spring Boot,Spring Boot是基于 Spring4 的条件注册的一套快速开发整合包,说白了就是简化开发流程。大家可以尝试一下,但是这里还是以Spring MVC为例子。
之所以使用jwt(json web token),是因为做后台不同于做web,app因为是长时间的登录至少都是一两个月不操作任然处于登录状态,所以目前国内大多是都是使用token做鉴权而不是使用session。而jwt是一个不错的token技术。restful就不用多说了,现在比较流行的编程风格,多个客户端(安卓,ios, mobile,web)调用同一套后台接口,而这就使得这套后台接口尽量不附带太多业务逻辑,而是面向资源的风格。而swaggerui则是提供一个rest api的可视化接口文档,并且在开发完后,可以很轻松的测试。
当然你可以只整合jwt或者swaggerui,教程都是没问题的。
所有使用到的代码可以在这里查看:https://github.com/minchangchen/springmvc-jwt-swaggerui
1.Spring MVC
Spring MVC框架是有一个MVC框架,通过实现Model-View-Controller模式来很好地将数据、业务与展现进行分离。从这样一个角度来说,Spring MVC和Struts、Struts2非常类似。Spring MVC的设计是围绕DispatcherServlet展开的,DispatcherServlet负责将请求派发到特定的handler。通过可配置的handler mappings、view resolution、locale以及theme resolution来处理请求并且转到对应的视图。这里就不做太多介绍,开始想在维基百科上搜索下spring mvc的,结果发现并没有这个条目,百度是有的。所以说有时候盈利的并不是都不好。
2.JWT(Json Web Tokens)
定义:JWT是一种用于双方之间传递安全信息的简洁的、URL安全的表述性声明规范。JWT作为一个开放的标准( RFC 7519 ),定义了一种简洁的,自包含的方法用于通信双方之间以Json对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名。
说明:传统的鉴权机制是基于session-cookies,而随着认证用户的增多,服务端的开销会明显增大,且不适合做app应用验证。因为app是一次登录,退出后不需登录,所以现在主流的鉴权验证都是使用token验证。而jwt是一种不错的基于token的鉴权机制。
基本流程:
用户使用用户名密码来请求服务器
服务器进行验证用户的信息
服务器通过验证发送给用户一个token
客户端存储token,并在每次请求时附送上这个token值
服务端验证token值,并返回数据
推文:http://www.jianshu.com/p/576dbf44b2ae
3.RestFul
定义:网络应用程序,分为前端和后端两个部分。当前的发展趋势,就是前端设备层出不穷(手机、平板、桌面电脑、其他专用设备......)。因此,必须有一种统一的机制,方便不同的前端设备与后端进行通信。这导致API构架的流行,甚至出现"API First"的设计思想。RESTful API是目前比较成熟的一套互联网应用程序的API设计理论。
说明:restful风格,就是一种面向资源服务的API设计方式,它不是规范,不是标准,它一种设计模式。以前流行的web service服务都是面向过程,基于RPC协议的SOAP协议,对于现在或者未来,更多的人了解并且深受SOA思想影响,以面向服务为目标,而现在的SOAP虽然支持SOA,但存在很很大的差别,所以,慢慢就流行基于restful风格的web service。说简单一点,就是它纯粹面向资源,面向服务的思想,目前J2EE6的JAX-RS就是这种restful风格实现的新技术。
例子:
获取用户列表 GET:http://project.company.com/api/v1/users
获取单个用户 GET:http://project.company.com/api/v1/users/{uid:.{32}}
创建单个用户 POST:http://project.company.com/api/v1/users/{uid:.{32}}
完全替换用户 PUT:http://project.company.com/api/v1/users/{uid:.{32}}
局部更新用户 PATCH:http://project.company.com/api/v1/users/{uid:.{32}}
删除单个用户 DELETE:http://project.company.com/api/v1/users/{uid:.{32}}推文:http://www.ruanyifeng.com/blog/2014/05/restful_api.html
4.Swagger UI
定义:Swagger的目标是为REST APIs 定义一个标准的,与语言无关的接口,使人和计算机在看不到源码或者看不到文档或者不能通过网络流量检测的情况下能发现和理解各种服务的功能。当服务通过Swagger定义,消费者就能与远程的服务互动通过少量的实现逻辑。类似于低级编程接口,Swagger去掉了调用服务时的很多猜测。
说明:swagger ui用于管理项目中API接口,属当前最流行的API接口管理工具。是后端开发人员提供给app开发人员的一个查看、测试、的一个可视化,可操作的接口文档,在这里你可以知道需要给都太传入什么参数,使用哪种请求,以及返回的数据等等,这种就省去app端人员写测试接口。
图示:
代码:
1.maven
<!-- Spring --> <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.3.4.RELEASE</version><exclusions><!-- Exclude Commons Logging in favor of SLF4j --><exclusion><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions> </dependency> <dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>4.3.4.RELEASE</version> </dependency> <dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>4.3.4.RELEASE</version> </dependency> <dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>4.3.4.RELEASE</version> </dependency><!-- springfox-swagger2 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.5.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.5.0</version> </dependency><!-- Jwt --> <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.7.0</version> </dependency>
2.JWT
这里我不再解释下jwt了,looking this :http://www.jianshu.com/p/576dbf44b2ae 一定要看哦!
我先说下jwt使用流程:
a:用户登录server
b:server验证通过,生成token并返回
c:app端接收到token存起来,下去请求放在reuqest的header里面
d:server接收到app的请求,在拦截器中判断url是否为需要鉴权的路径,然后去验证token
e:当token过期时,且没有超过刷新期。自动添加一个新的token返回给app
拦截器:
public abstract class BaseWebInterceptor extends HandlerInterceptorAdapter {public static final String RedirectPrefix = "redirect:";private static Logger log = LoggerFactory.getLogger(BaseWebInterceptor.class);@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (isNeedJwtUrl(request.getRequestURI())) { //判断这个url是否需要jwt验证 ,比如login就不需要String token = request.getHeader("x-access-token"); //从request中获取token,key是自定义的,当然app端存也要是这个keyETokenState state = JwtUtil.validateJWT(token); //验证token,ETokenState这是我自定义的一个类,JwtUtil这也是自己写的一个类switch (state) { case invalid: //验证错误log.info(String.format("URL:%s need login, but the token is null or invalid... ", request.getRequestURL().toString()));response.setStatus(401);return false;case expired: //token过期if (refreshTokenHandler(request, response, token)) {break;} else {log.info(String.format("URL:%s need login, but the token is expired... ", request.getRequestURL().toString()));response.setStatus(403);return false;}case valid: //有效的break;default:break;}}return super.preHandle(request, response, handler);}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {super.afterCompletion(request, response, handler, ex);}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {super.postHandle(request, response, handler, modelAndView);}/*** 刷新token,子类重载* * @author chenmc* @date 2017年5月9日 下午3:41:05* @param token* @return*/protected boolean refreshTokenHandler(HttpServletRequest request, HttpServletResponse response, String token) {return false;}/*** 需要登录的uri* * @param requestURI* @return*/private boolean isNeedJwtUrl(String requestURI) {return MappingConf.isNeedJwtUrls(requestURI);}}
这里需要说明的是,一般的login和register的url是不拦截的,自己可以配置。关于jwt生成和验证的代码,请点击这里https://github.com/minchangchen/springmvc-jwt-swaggerui
2.Swagger UI
配置文件:
1,springmvc.xml
<!-- swagger2 --><context:component-scan base-package="com.gionee.swagger.conf"/><bean class="com.company.swagger.conf.SwaggerConfig"/><!-- Swagger资源重定向(仅作为后台使用不提供静态资源) --><mvc:resources location="classpath:/META-INF/resources/" mapping="swagger-ui.html"/><mvc:resources location="classpath:/META-INF/resources/webjars/" mapping="/webjars/**"/>
2,SwaggerConfig.java
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.web.servlet.config.annotation.EnableWebMvc;import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.ParameterBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.schema.ModelRef; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Parameter; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2;//@Configuration @EnableSwagger2 @EnableWebMvc @ComponentScan("com.company.web") public class SwaggerConfig {@Beanpublic Docket api(){ParameterBuilder tokenPar = new ParameterBuilder();List<Parameter> pars = new ArrayList<Parameter>();//增加一个request的header参数tokenPar.name("x-access-token").description("令牌").modelRef(new ModelRef("string")).parameterType("header").required(false).build();pars.add(tokenPar.build());return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any()).paths(PathSelectors.regex("/api/.*"))//对所有请求中包含api的url拦截.build().globalOperationParameters(pars).apiInfo(apiInfo());}private ApiInfo apiInfo() {return new ApiInfoBuilder().title("后台接口文档与测试").description("这是一个给app端人员调用server端接口的测试文档与平台").version("1.0.0").termsOfServiceUrl("http://terms-of-services.url")//.license("LICENSE")//.licenseUrl("http://url-to-license.com").build();}}
3,Controller
@Api(value="登录接口") @Controller @RequestMapping("/api/v1") public class LoginInterface extends BaseController {@AutowiredUserSO so;@ApiOperation(value="验证密文,并添加user", notes="密文和amigoInfo")@RequestMapping( value = {"/login"}, method = RequestMethod.POST, produces = "application/json;charset=UTF-8")@ResponseBodypublic String login(HttpServletRequest request, @RequestParam String fields, @PathVariable String useruid) {// do something}/**api开头的注解都是swagger的注解*方法参数上加有@RequestParam的参数会显示在swagger*所以上述login方法的三个参数只有fields会显示在swagger中*当然还有一个请求头的参数,存放token的那是在SaggerConfig.java中配置的*/ }
4,放开swagger的url不拦截
当你配置了jwt,因为jwt对url进行拦截,这里我们不能对swagger的URL进行拦截,这样页面才能正常显示。只整合swaggerui的可以忽略。
noNeedJwtUrls=.*swagger.*|.*docs.*|.*test.*|.*/index.*|.*/register.*|.*/login.*
至此,swaggerui已配置完成,请求访问http://localhost:8080/proj-name/swagger-ui.html即可得到以下页面
3.RestFul API
请参照以下这种方式来定义接口
获取用户列表 GET:http://proj.company.com/api/v1/users
获取单个用户 GET:http://proj.company.com/api/v1/users/{uid:.{32}}
创建单个用户 POST:http://proj.company.com/api/v1/users/{uid:.{32}}
完全替换用户 PUT:http://proj.company.com/api/v1/users/{uid:.{32}}
局部更新用户 PATCH:http://proj.company.com/api/v1/users/{uid:.{32}}
删除单个用户 DELETE:http://proj.company.com/api/v1/users/{uid:.{32}}
至此,所有配置应该都已经贴出,代码可在这里查找:https://github.com/minchangchen/springmvc-jwt-swaggerui。
若有遗失或错误希望大家提出!过段时间我会写一些与docker有关的教程,这段时间觉得自己对docker的使用还不够全及精,所以暂时不写!
SpringMVC+JWT+Swagger UI+RestFul相关推荐
- Swagger UI 与SpringMVC的整合 II
pom.xml <!-- swagger开始 --><dependency><groupId>io.springfox</groupId><art ...
- 使用 Swagger UI 与 Swashbuckle 创建 RESTful Web API 帮助文件
作者:Sreekanth Mothukuru 2016年2月18日 本文旨在介绍如何使用常用的 Swagger 和 Swashbuckle 框架创建描述 Restful API 的交互界面,并为 AP ...
- swagger ui 怎么输入对象_Swagger UI 传入对象类型参数
Swagger要传送对象作为参数,只需添加@ModelAttribute或@RequestBody @RestController @RequestMapping("/api/json/re ...
- springMVC整合swagger(亲自试验完全可用)
swagger是什么: [plain] view plaincopyprint? Swagger 是一款RESTFUL接口的文档在线自动生成+功能测试功能软件.本文简单介绍了在项目中集成swagger ...
- Spring Boot 集成 Swagger 生成 RESTful API 文档
原文链接: Spring Boot 集成 Swagger 生成 RESTful API 文档 简介 Swagger 官网是这么描述它的:The Best APIs are Built with Swa ...
- [第二篇]如何在ASP.Net Core的生产环境中使用OAuth保护swagger ui
在我上篇文章如何在ASP.Net Core的生产环境中保护swagger ui中,我们讨论了如何使用基本身份验证来保护 swagger ui. 使用 OAuth 2.0 和 OpenIdConnect ...
- Springdoc Swagger UI集成OAuth2认证
目录 引言 方式1:Bearer Token 方式2:标准OAuth2授权码流程 方式3:集成OIDC发现端点 扩展:同时支持多种认证方式 引言 之前的文章讲过OAuth2体系,以授权码流程为例(参见 ...
- Swagger UI使用指南
1:认识Swagger Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法 ...
- Swagger UI简介
Swagger UI 简介 Swagger UI允许任何人(无论您是开发团队还是最终用户)都可以可视化API资源并与之交互,而无需任何实现逻辑.它是根据您的OpenAPI(以前称为Swagger)规范 ...
最新文章
- Vim 自动文件头注释与模板定义
- matlab 中fft的用法
- 微信“支付”页全国多地上线“出行服务”,已覆盖108城
- 抖音2020研究报告_抖音音乐发布2020抖音音乐生态数据报告
- C++中? : 运算符的使用
- python椭圆识别_Python+pillow计算椭圆图形几何中心
- 各层电子数排布规则_核外电子的排布规律
- Arcgis Javascript那些事儿(八)--图层获取与图层顺序
- 我是如何学习Android源码的
- PSD网页切图制作HTML全过程教程
- 程序包清单签名验证失败
- 30段超实用CSS代码
- 美国在线黄页服务提供商YP控股拟竞购雅虎网络资产
- android gridview日历,Android使用GridView实现日历的方法
- FreeCMS视频教程 敏感词管理
- DeFi基准利率今日为3.38%
- 大数据NiFi(七):NiFi集群页面管理节点操作
- 用户使用报告_2020年抖音用户画像报告[附下载] | 行业数据报告研读
- 移动端开发工程师的AI突围之路
- php中input的onclick,onkeydown、onkeyup、onclick、onchange、oninput、onpropertychange 的用法和区别...
热门文章
- table类型数据提交_OGG数据同步异常问题总结
- spark如何防止内存溢出_spark开发十大原则
- global mapper 制作地形图_福州大飞机模型制作厂家,产品模型,期待合作_境海模型...
- 四、Go语言复合数据类型(上)
- 五十七、教用Python中的turtle海龟画图(下篇)
- 非递减数列JAVA_C语言实现两个递减数列中寻找某一个数
- 回溯算法-排列/组合/子集
- googlehelper手机版ios_二次元漫画控iOS苹果手机版下载v1.0.0下载|免费二次元漫画控iOS苹果手机版下载绿色版...
- Spring Boot配置文件加载顺序
- ActiveRecordException: The model attribute ysgl is not exists.