去除全局的数据格式化,统一后续使用 CommonResult

ps:全局的格式化,也会格式化掉 swagger 的返回,会导致 swagger 无法使用的问题的。
This commit is contained in:
YunaiV 2019-02-26 12:10:14 +08:00
parent 6cbce27412
commit 4b0038759f
13 changed files with 211 additions and 102 deletions

View File

@ -1,31 +0,0 @@
package cn.iocoder.common.framework.config;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.RestResult;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
@ControllerAdvice
public class GlobalResponseBodyAdvice implements ResponseBodyAdvice {
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
return true; // TODO 芋艿未来这里可以剔除掉一些需要特殊返回的接口
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
if (body instanceof RestResult) {
return body;
}
if (body instanceof CommonResult) { // TODO 芋艿后续要改下
return body;
}
return RestResult.ok(body);
}
}

View File

@ -0,0 +1,36 @@
package cn.iocoder.mall.order.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
@EnableWebMvc
@Configuration
public class MVCConfiguration implements WebMvcConfigurer {
// @Autowired
// private SecurityInterceptor securityInterceptor;
// @Reference
// private OAuth2Service oauth2Service;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// registry.addInterceptor(securityInterceptor);
}
// @Override
// public void addViewControllers(ViewControllerRegistry registry) {
// registry.addRedirectViewController("/api/v2/api-docs", "/v2/api-docs");
// registry.addRedirectViewController("/api/swagger-resources/configuration/ui", "/swagger-resources/configuration/ui");
// registry.addRedirectViewController("/api/swagger-resources/configuration/security", "/swagger-resources/configuration/security");
// registry.addRedirectViewController("/api/swagger-resources", "/swagger-resources");
// }
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 解决 swagger-ui.html 的访问参考自 https://stackoverflow.com/questions/43545540/swagger-ui-no-mapping-found-for-http-request 解决
registry.addResourceHandler("swagger-ui.html**").addResourceLocations("classpath:/META-INF/resources/swagger-ui.html");
registry.addResourceHandler("webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}

View File

@ -0,0 +1,36 @@
package cn.iocoder.mall.order.config;
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 SwaggerConfiguration {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("cn.iocoder.mall.order.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("订单子系统")
.description("订单子系统")
.termsOfServiceUrl("http://www.iocoder.cn")
.version("1.0.0")
.build();
}
}

View File

@ -1,16 +1,14 @@
package cn.iocoder.mall.product.config; package cn.iocoder.mall.product.config;
import cn.iocoder.common.framework.config.GlobalExceptionHandler;
import cn.iocoder.common.framework.config.GlobalResponseBodyAdvice;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@EnableWebMvc @EnableWebMvc
@Configuration @Configuration
@Import(value = {GlobalResponseBodyAdvice.class, GlobalExceptionHandler.class}) // 统一全局返回 //@Import(value = {GlobalExceptionHandler.class}) // 统一全局返回
public class MVCConfiguration implements WebMvcConfigurer { public class MVCConfiguration implements WebMvcConfigurer {
// @Autowired // @Autowired
@ -24,4 +22,11 @@ public class MVCConfiguration implements WebMvcConfigurer {
// registry.addInterceptor(securityInterceptor); // registry.addInterceptor(securityInterceptor);
} }
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 解决 swagger-ui.html 的访问参考自 https://stackoverflow.com/questions/43545540/swagger-ui-no-mapping-found-for-http-request 解决
registry.addResourceHandler("swagger-ui.html**").addResourceLocations("classpath:/META-INF/resources/swagger-ui.html");
registry.addResourceHandler("webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
} }

View File

@ -24,7 +24,7 @@ public class ProductCategoryController {
@GetMapping @GetMapping
@ApiOperation("获得指定编号下的子分类的数组") @ApiOperation("获得指定编号下的子分类的数组")
@ApiImplicitParam(name = "pid", value = "指定分类编号", required = true) @ApiImplicitParam(name = "pid", value = "指定分类编号", required = true, example = "0")
public List<ProductCategoryVO> list(@RequestParam("pid") Integer pid) { public List<ProductCategoryVO> list(@RequestParam("pid") Integer pid) {
return ProductCategoryConvert.INSTANCE.convertToVO( return ProductCategoryConvert.INSTANCE.convertToVO(
productCategoryService.getListByPid(pid) productCategoryService.getListByPid(pid)

View File

@ -10,7 +10,7 @@ spring:
# server # server
server: server:
port: 8080 port: 8081
# mybatis # mybatis
mybatis: mybatis:

View File

@ -68,7 +68,6 @@
<version>${org.mapstruct.version}</version> <version>${org.mapstruct.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.springfox</groupId> <groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId> <artifactId>springfox-swagger2</artifactId>
@ -79,6 +78,7 @@
<artifactId>springfox-swagger-ui</artifactId> <artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version> <version>2.9.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>cn.iocoder.mall</groupId> <groupId>cn.iocoder.mall</groupId>
<artifactId>user-service-api</artifactId> <artifactId>user-service-api</artifactId>

View File

@ -3,7 +3,7 @@ package cn.iocoder.mall.user;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = "cn.iocoder.mall.user") @SpringBootApplication(scanBasePackages = {"cn.iocoder.mall.user"})
public class UserApplication { public class UserApplication {
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -1,18 +1,18 @@
package cn.iocoder.mall.user.config; package cn.iocoder.mall.user.config;
import cn.iocoder.common.framework.config.GlobalExceptionHandler; import cn.iocoder.common.framework.config.GlobalExceptionHandler;
import cn.iocoder.common.framework.config.GlobalResponseBodyAdvice;
import cn.iocoder.mall.user.sdk.interceptor.SecurityInterceptor; import cn.iocoder.mall.user.sdk.interceptor.SecurityInterceptor;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@EnableWebMvc @EnableWebMvc
@Configuration @Configuration
@Import(value = {GlobalResponseBodyAdvice.class, GlobalExceptionHandler.class, // 统一全局返回 @Import(value = {GlobalExceptionHandler.class, // 统一全局返回
SecurityInterceptor.class}) // 安全拦截器实现认证和授权功能 SecurityInterceptor.class}) // 安全拦截器实现认证和授权功能
public class MVCConfiguration implements WebMvcConfigurer { public class MVCConfiguration implements WebMvcConfigurer {
@ -21,7 +21,14 @@ public class MVCConfiguration implements WebMvcConfigurer {
@Override @Override
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(securityInterceptor); // registry.addInterceptor(securityInterceptor).addPathPatterns("/user/**", "/admin/**"); // 只拦截我们定义的接口
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 解决 swagger-ui.html 的访问参考自 https://stackoverflow.com/questions/43545540/swagger-ui-no-mapping-found-for-http-request 解决
registry.addResourceHandler("swagger-ui.html**").addResourceLocations("classpath:/META-INF/resources/swagger-ui.html");
registry.addResourceHandler("webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
} }
} }

View File

@ -0,0 +1,36 @@
package cn.iocoder.mall.user.config;
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 SwaggerConfiguration {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("cn.iocoder.mall.user.controller"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("用户子系统")
.description("用户子系统")
.termsOfServiceUrl("http://www.iocoder.cn")
.version("1.0.0")
.build();
}
}

View File

@ -1,22 +1,24 @@
package cn.iocoder.mall.user.controller; package cn.iocoder.mall.user.controller;
import cn.iocoder.common.framework.exception.ServiceException;
import cn.iocoder.common.framework.util.ExceptionUtil;
import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.user.convert.PassportConvert;
import cn.iocoder.mall.user.sdk.annotation.PermitAll; import cn.iocoder.mall.user.sdk.annotation.PermitAll;
import cn.iocoder.mall.user.service.api.MobileCodeService; import cn.iocoder.mall.user.service.api.MobileCodeService;
import cn.iocoder.mall.user.service.api.OAuth2Service; import cn.iocoder.mall.user.service.api.OAuth2Service;
import cn.iocoder.mall.user.service.api.UserService; import cn.iocoder.mall.user.service.api.UserService;
import cn.iocoder.mall.user.service.api.bo.OAuth2AccessTokenBO; import cn.iocoder.mall.user.service.api.bo.OAuth2AccessTokenBO;
import cn.iocoder.mall.user.service.api.constant.UserErrorCodeEnum; import cn.iocoder.mall.user.vo.MobileRegisterVO;
import com.alibaba.dubbo.config.annotation.Reference; import com.alibaba.dubbo.config.annotation.Reference;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@RequestMapping("/passport") @RequestMapping("user/passport")
public class PassportController { public class PassportController {
@Reference @Reference
@ -33,63 +35,17 @@ public class PassportController {
// return oauth2Service.getAccessToken(clientId, clientSecret, mobile, password); // return oauth2Service.getAccessToken(clientId, clientSecret, mobile, password);
// } // }
/**
* 手机号 + 验证码登陆
*
* @see #mobileRegister2(String, String) 使用替代
*
* @param mobile 手机号
* @param code 验证码
* @return 授权信息
*/
@Deprecated
@PermitAll @PermitAll
@PostMapping("/mobile/login") @PostMapping("/mobile/register")
public OAuth2AccessTokenBO mobileRegister(@RequestParam("mobile") String mobile, @ApiOperation(value = "手机号 + 验证码登陆(注册)", notes = "如果手机对应的账号不存在,则会自动创建")
@RequestParam("code") String code) { @ApiImplicitParams({
// 尝试直接授权 @ApiImplicitParam(name = "mobile", value = "手机号", required = true, example = "15601691300"),
OAuth2AccessTokenBO accessTokenDTO; @ApiImplicitParam(name = "code", value = "验证码", required = true, example = "9999")
try { })
accessTokenDTO = oauth2Service.getAccessToken(mobile, code); public CommonResult<MobileRegisterVO> mobileRegister(@RequestParam("mobile") String mobile,
return accessTokenDTO; @RequestParam("code") String code) {
} catch (Exception ex) { CommonResult<OAuth2AccessTokenBO> result = oauth2Service.getAccessToken2(mobile, code);
ServiceException serviceException = ExceptionUtil.getServiceException(ex); return PassportConvert.INSTANCE.convert(result);
if (serviceException == null) {
throw ex;
}
if (!serviceException.getCode().equals(UserErrorCodeEnum.USER_MOBILE_NOT_REGISTERED.getCode())) { // 如果是未注册异常忽略下面发起自动注册逻辑
throw serviceException;
}
}
// 上面尝试授权失败说明用户未注册发起自动注册
try {
userService.createUser(mobile, code);
} catch (Exception ex) {
ServiceException serviceException = ExceptionUtil.getServiceException(ex);
if (serviceException == null) {
throw ex;
}
if (!serviceException.getCode().equals(UserErrorCodeEnum.USER_MOBILE_ALREADY_REGISTERED.getCode())) { // 如果是已注册异常忽略下面再次发起授权
throw serviceException;
}
}
// 再次发起授权
accessTokenDTO = oauth2Service.getAccessToken(mobile, code);
return accessTokenDTO;
}
/**
* 手机号 + 验证码登陆
*
* @param mobile 手机号
* @param code 验证码
* @return 授权信息
*/
@PermitAll
@PostMapping("/mobile/login2")
public CommonResult<OAuth2AccessTokenBO> mobileRegister2(@RequestParam("mobile") String mobile,
@RequestParam("code") String code) {
return oauth2Service.getAccessToken2(mobile, code);
} }
/** /**

View File

@ -0,0 +1,21 @@
package cn.iocoder.mall.user.convert;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.user.service.api.bo.OAuth2AccessTokenBO;
import cn.iocoder.mall.user.vo.MobileRegisterVO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface PassportConvert {
PassportConvert INSTANCE = Mappers.getMapper(PassportConvert.class);
@Mappings({})
MobileRegisterVO convert(OAuth2AccessTokenBO oauth2AccessTokenBO);
@Mappings({})
CommonResult<MobileRegisterVO> convert(CommonResult<OAuth2AccessTokenBO> oauth2AccessTokenBO);
}

View File

@ -0,0 +1,43 @@
package cn.iocoder.mall.user.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel("手机注册结果VO")
public class MobileRegisterVO {
@ApiModelProperty(value = "访问令牌", required = true, example = "2e3d7635c15e47e997611707a237859f")
private String accessToken;
@ApiModelProperty(value = "刷新令牌", required = true, example = "d091e7c35bbb4313b0f557a6ef23d033")
private String refreshToken;
@ApiModelProperty(value = "过期时间,单位:秒", required = true, example = "2879")
private Integer expiresIn;
public String getAccessToken() {
return accessToken;
}
public MobileRegisterVO setAccessToken(String accessToken) {
this.accessToken = accessToken;
return this;
}
public String getRefreshToken() {
return refreshToken;
}
public MobileRegisterVO setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
return this;
}
public Integer getExpiresIn() {
return expiresIn;
}
public MobileRegisterVO setExpiresIn(Integer expiresIn) {
this.expiresIn = expiresIn;
return this;
}
}