当前位置: 首页 > news >正文

三亚网站制作公司谷歌seo是什么职业

三亚网站制作公司,谷歌seo是什么职业,知名网站建设商家,徐州市做网站今天遇到一个需求,在不改动原系统代码的情况下。将Controller的返回值和异常包装到一个统一的返回对象中去。 例如原系统的接口 public String myIp(ApiIgnore HttpServletRequest request);返回的只是一个IP字符串"0:0:0:0:0:0:0:1",目前接口…

今天遇到一个需求,在不改动原系统代码的情况下。将Controller的返回值和异常包装到一个统一的返回对象中去。

例如原系统的接口

public String myIp(@ApiIgnore HttpServletRequest request);

返回的只是一个IP字符串"0:0:0:0:0:0:0:1",目前接口需要包装为:

{"code":200,"message":"","result":"0:0:0:0:0:0:0:1","success":true}

而原异常跳转到error页面,需要调整为

{
  "success": false,
  "message": "For input string: \"fdsafddfs\"",
  "code": 500,
  "result": "message"
}

因此就有了2个工作子项需要完成:

1)Exception的处理

2)controller return值的处理

Exception的自动包装

返回的exception处理可以采用@RestControllerAdvice来处理。

建立自己的Advice类,注入国际化资源(异常需要支持多语言)
 

package org.ccframe.commons.mvc;import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.ccframe.commons.filter.CcRequestLoggingFilter;
import org.ccframe.commons.util.BusinessException;
import org.ccframe.config.GlobalEx;
import org.ccframe.subsys.core.dto.Result;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.core.MethodParameter;
import org.springframework.http.ResponseEntity;
import org.springframework.orm.ObjectOptimisticLockingFailureException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.NoHandlerFoundException;import javax.servlet.http.HttpServletRequest;
import java.util.Locale;@RestControllerAdvice
@Log4j2
public class GlobalRestControllerAdvice{private MessageSource messageSource; //国际化资源private LocaleResolver localeResolver;private Object[] EMPTY_ARGS = new Object[0];public GlobalRestControllerAdvice(MessageSource messageSource, LocaleResolver localeResolver){this.messageSource = messageSource;this.localeResolver = localeResolver;}private Result<String> createError(HttpServletRequest request, Exception e,int code, String msgKey, Object[] args){Locale currentLocale = localeResolver.resolveLocale(request);String message = "";try {message = messageSource.getMessage(msgKey, args, currentLocale);}catch (NoSuchMessageException ex){message = e.getMessage();}finally {log.error(message);CcRequestLoggingFilter.pendingLog(); //服务器可以记录出错时的请求啦😂}return Result.error(code, message, msgKey);}@ExceptionHandler(NoHandlerFoundException.class)public Result<?> handlerNoFoundException(HttpServletRequest request, Exception e) {return createError(request, e, HttpStatus.SC_NOT_FOUND, "error.mvc.uriNotFound", EMPTY_ARGS);}@ExceptionHandler(HttpRequestMethodNotSupportedException.class)public Result<?> httpRequestMethodNotSupportedException(HttpServletRequest request, HttpRequestMethodNotSupportedException e){return createError(request,e, HttpStatus.SC_NOT_FOUND,"error.mvc.methodNotSupported",new Object[]{e.getMethod(), StringUtils.join(e.getSupportedMethods(), GlobalEx.DEFAULT_TEXT_SPLIT_CHAR)});}@ExceptionHandler(BusinessException.class)public Result<?> businessException(HttpServletRequest request, BusinessException e){return createError(request,e, HttpStatus.SC_INTERNAL_SERVER_ERROR, e.getMsgKey(), e.getArgs());}@ExceptionHandler(ObjectOptimisticLockingFailureException.class) //乐观锁异常public Result<?> objectOptimisticLockingFailureException(HttpServletRequest request, ObjectOptimisticLockingFailureException e){return createError(request,e, HttpStatus.SC_INTERNAL_SERVER_ERROR, "errors.db.optimisticLock", EMPTY_ARGS);}@ExceptionHandler(MaxUploadSizeExceededException.class) // 文件上传超限,nginx请设置为10Mpublic Result<?> handleMaxUploadSizeExceededException(HttpServletRequest request, MaxUploadSizeExceededException e) {return createError(request, e, HttpStatus.SC_INTERNAL_SERVER_ERROR, "error.mvc.fileTooLarge", EMPTY_ARGS);}@ExceptionHandler(Exception.class)@ResponseBodypublic Result<?> handleException(HttpServletRequest request, Exception e) {log.error(e);return createError(request,e, HttpStatus.SC_INTERNAL_SERVER_ERROR, "message", new Object[]{e.getMessage()});}
}

在Config类初始化该Bean(当然也可以使用@Component支持扫描,随你喜欢)
 

	@Beanpublic GlobalRestControllerAdvice globalRestControllerAdvice(MessageSource messageSource, LocaleResolver localeResolver){return new GlobalRestControllerAdvice(messageSource, localeResolver);}

controller return值的自动包装

网上的例子有很多坑,包括使用HandlerMethodReturnValueHandler,看了源码才发现。还是ResponseBodyAdvice好使。

建立自己的处理Bean

package org.ccframe.commons.mvc;import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import org.apache.http.HttpStatus;
import org.ccframe.commons.util.JsonUtil;
import org.ccframe.subsys.core.dto.Result;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
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;
import springfox.documentation.swagger.web.ApiResourceController;import java.util.regex.Pattern;@ControllerAdvice
public class CcResponseBodyAdvice implements ResponseBodyAdvice<Object> {private static final Pattern CONTROLLER_PATTERN = Pattern.compile("^org\\.ccframe\\.(subsys|sdk)\\.[a-z0-9]+\\.controller\\.");@Overridepublic boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {return // 只有自己的cotroller类才需要进入,否则swagger都会挂了
CONTROLLER_PATTERN.matcher(returnType.getContainingClass().getName()).find();}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {System.out.println(returnType.getContainingClass());Result<Object> result = new Result<>();result.setResult(body);result.setCode(HttpStatus.SC_OK);if(body instanceof String){ //String返回要特殊处理return JSON.toJSONString(result);}else {return result;}}
}

如果你不需要根据正则来指定包,可以直接用RestControllerAdvice的basePackages属性来过滤

注意这里有2个坑

1)String类型的返回被其它的转换接口StringHttpMessageConverter处理,因此返回要进行JSON编码而不能返回其他类型,否则会报cast类型错,因此就有了String部分的特殊处理方法。

2)controller方法签名返回是void时,不会被处理。为什么,有什么办法?得看spring这段源码:

当returnValue==null时,设置为RequestHandled,也就是提前结束了。后面任何返回的处理都不再进行。所以,如果一定要返回null值的话,可以在controller里返回一个
return new ResponseEntity<Void>(HttpStatus.OK);
这样在返回的值里面就有详细的结构了。

最后要生效的话,在Config类初始它:
 

	@Beanpublic CcResponseBodyAdvice ccResponseBodyAdvice() {return new CcResponseBodyAdvice();}

最后。上面两个Bean也可以写在一个,有兴趣的自己尝试。

---------------

null无法被BodyAdvice处理的问题。随着源码跟踪,慢慢知道怎么回事了,我们尝试根本来解决这个问题。从这个图开始:


当返回为null时,mavContainer.isRequestHandled()为true导致了后面的没有处理。

那么想当然的,mavContainer.isRequestHandled()为flase不久解决了吗,向前跟踪,基本到MVC invoke的核心代码里了,发现在invoke前,mavContainer.isRequestHandled()变成了true,再继续跟踪,找到这个方法:

在HandlerMethodArgumentResolverComposite的argumentResolvers看到了上面这个。进行了setRequestHandled。HandlerMethodArgumentResolver是spring controller的参数自动注入机制。看了下源码也没有太多的扩展点,于是只能换个思路。由于是执行方法时是反射Invoke处理的:
return getBridgedMethod().invoke(getBean(), args);
因此void类型也无法接收任何的参数,AOP也不可行。因此除了覆盖改源码没有更好的扩展方法。

最后想了下,还是放弃修改。

如果controller确实要返回void,可以使用

return new ResponseEntity<Void>(HttpStatus.OK);

来替代


 

http://www.hkea.cn/news/805415/

相关文章:

  • 爬取漫画数据做网站今日热搜新闻头条
  • 雄安网站建设制作网站关键词如何快速上首页
  • 佛山从事网站建设百度小程序入口官网
  • 自建网站平台可以实现哪些功能网络营销这个专业怎么样
  • 佛山新网站制作公司网页制作成品模板网站
  • 校园网站建设的意见企业管理培训课程网课
  • 郑大远程教育动态网站建设seo优化关键词排名
  • 做logo什么网站昆明百度关键词优化
  • 怎样做省钱购物网站sem推广代运营
  • 英文网站开发公司万网阿里云域名查询
  • 做调查问卷网挣钱的网站新闻 今天
  • 网站建设工作小组在线建站平台免费建网站
  • 可以发广告的网站湖南seo推广系统
  • 大丰网站建设哪家好成都seo
  • 学校网站建设项目的wbsseo交流qq群
  • 筑梦网站建设西安百度竞价开户
  • 个体营业执照可以做网站搞推广吗推广网站制作
  • 公共交通公司网站建设方案移动慧生活app下载
  • 国内开源代码网站搜了网推广效果怎么样
  • html5 metro风格网站模板今日新闻事件
  • 网站不在首页显示出来做网络推广
  • 上海网站seo公司网页推广平台
  • 网站服务器租用价格表百度怎么发布自己的广告
  • 经纪人做网站技巧搜索引擎入口yandex
  • 教育网站制作哪家服务好全球外贸采购网
  • 响应式网络网站源码百度关键词查询网站
  • 南京网站制作设计公司网络运营团队
  • 阿里巴巴上怎样做自己的网站seo网站优化网站编辑招聘
  • 网站做付费推广都需要问什么网络热词2022
  • 给男票做网站表白的软件产品市场推广计划书