springboot + shiro 权限注解、统一异常处理、请求乱码解决 |
您所在的位置:网站首页 › shiro拦截器中获取请求参数 › springboot + shiro 权限注解、统一异常处理、请求乱码解决 |
前篇 后台权限管理系统 相关: 基于前篇,新增功能: 新增shiro权限注解; 请求乱码问题解决; 统一异常处理。源码已集成到项目中: github源码: 码云: github对应项目源码目录:wyait-manage-1.2.0 码云对应项目源码目录:wyait-manage-1.2.0 shiro注解的使用shiro权限注解 Shiro 提供了相应的注解用于权限控制,如果使用这些注解就需要使用AOP 的功能来进行判断,如Spring AOP;Shiro 提供了Spring AOP 集成用于权限注解的解析和验证。 @RequiresAuthentication 表示当前Subject已经通过login 进行了身份验证;即Subject.isAuthenticated()返回true。 @RequiresUser 表示当前Subject已经身份验证或者通过记住我登录的。 @RequiresGuest 表示当前Subject没有身份验证或通过记住我登录过,即是游客身份。 @RequiresRoles(value={“admin”, “user”}, logical= Logical.AND) @RequiresRoles(value={“admin”}) @RequiresRoles({“admin“}) 表示当前Subject需要角色admin 和user。 @RequiresPermissions (value={“user:a”, “user:b”}, logical= Logical.OR) 表示当前Subject需要权限user:a或user:b。Shiro的认证注解处理是有内定的处理顺序的,如果有多个注解的话,前面的通过了会继续检查后面的,若不通过则直接返回,处理顺序依次为(与实际声明顺序无关): RequiresRoles RequiresPermissions RequiresAuthentication RequiresUser RequiresGuest以上注解既可以用在controller中,也可以用在service中使用; 建议将shiro注解放在controller中,因为如果service层使用了spring的事物注解,那么shiro注解将无效。 shiro权限注解springAOP配置shiro权限注解要生效,必须配置springAOP通过设置shiro的SecurityManager进行权限验证。 /** * * @描述:开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证 * 配置以下两个bean(DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor)即可实现此功能 * Enable Shiro Annotations for Spring-configured beans. Only run after the lifecycleBeanProcessor(保证实现了Shiro内部lifecycle函数的bean执行) has run * 不使用注解的话,可以注释掉这两个配置 * @创建人:wyait * @创建时间:2018年5月21日 下午6:07:56 * @return */ @Bean public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); advisorAutoProxyCreator.setProxyTargetClass(true); return advisorAutoProxyCreator; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager()); return authorizationAttributeSourceAdvisor; } springboot异常处理原理场景:当用户正常访问网站时,因为某种原因后端出现exception的时候,直接暴露异常信息或页面显示给用户; 这种操作体验不是我们想要的。所以要对异常进行统一管理,能提高用户体验的同时,后台能详细定位到异常的问题点。 springboot异常概况 Spring boot 提供了默认的统一错误页面,这是Spring MVC没有提供的。在理解了Spring Boot提供的错误处理相关内容之后,我们可以方便的定义自己的错误返回的格式和内容。 编写by zero异常 在home页面,手动创建两个异常:普通异常和异步异常! 前端页面:普通请求异常: 点击 ajax 异步请求异常: 点击 ... //js代码 function ajaxError(){ $.get("/error/ajaxError",function(data){ layer.alert(data); }); } 后端代码: /** * * @描述:普通请求异常 * @创建人:wyait * @创建时间:2018年5月24日 下午5:30:50 */@RequestMapping("getError") public void toError(){ System.out.println(1/0); } /** * * @描述:异步异常 * @创建人:wyait * @创建时间:2018年5月24日 下午5:30:39 */@RequestMapping("ajaxError") @ResponseBody public String ajaxError(){ System.out.println(1/0); return "异步请求成功!"; }异常效果 普通异常:console错误信息: [2018-05-25 09:30:04.669][http-nio-8077-exec-8][ERROR][org. apache .juli.logging.DirectJDKLog][181]: servlet .service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ArithmeticException: / by zero] with root cause java.lang.ArithmeticException: / by zero at com.wyait.manage.web.error.IndexErrorController.toError(IndexErrorController.java:18) ~[classes/:?] ... at java.lang.Thread.run(Thread.java:748) [?:1.8.0_131] ... [2018-05-25 09:30:04.676][http-nio-8077-exec-8][DEBUG][org.springframework.web.servlet.handler.AbstractHandlerMethodMapping][317]:Returning handler method [public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.error html (javax.servlet.http.HttpServlet request ,javax.servlet.http.HttpServletResponse)] [2018-05-25 09:30:04.676][http-nio-8077-exec-8][DEBUG][org.springframework.web.servlet.handler.AbstractHandlerMethodMapping][317]:Returning handler method [public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)] [2018-05-25 09:30:04.676][http-nio-8077-exec-8][DEBUG][org.springframework.beans. factory .support.AbstractBeanFactory][251]:Returning cached instance of singleton bean 'basicErrorController' [2018-05-25 09:30:04.676][http-nio-8077-exec-8][DEBUG][org.springframework.beans.factory.support.AbstractBeanFactory][251]:Returning cached instance of singleton bean 'basicErrorController' ... [2018-05-25 09:30:04.686][http-nio-8077-exec-8][DEBUG][org.springframework.web.servlet.view.ContentNegotiatingViewResolver][263]:Requested media types are [text/html, text/html;q=0.8] based on Accept header types and producible media types [text/html]) [2018-05-25 09:30:04.686][http-nio-8077-exec-8][DEBUG][org.springframework.web.servlet.view.ContentNegotiatingViewResolver][263]:Requested media types are [text/html, text/html;q=0.8] based on Accept header types and producible media types [text/html]) [2018-05-25 09:30:04.686][http-nio-8077-exec-8][DEBUG][org.springframework.beans.factory.support.AbstractBeanFactory][251]:Returning cached instance of singleton bean 'error' [2018-05-25 09:30:04.686][http-nio-8077-exec-8][DEBUG][org.springframework.beans.factory.support.AbstractBeanFactory][251]:Returning cached instance of singleton bean 'error' [2018-05-25 09:30:04.686][http-nio-8077-exec-8][DEBUG][org.springframework.web.servlet.view.ContentNegotiatingViewResolver][338]:Returning [org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView@6ffd99fb] based on requested media type 'text/html' [2018-05-25 09:30:04.686][http-nio-8077-exec-8][DEBUG][org.springframework.web.servlet.view.ContentNegotiatingViewResolver][338]:Returning [org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView@6ffd99fb] based on requested media type 'text/html' ...通过日志可知,springboot返回的错误页面,是通过:org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml处理返回ModelAndView。 异步异常: console日志信息: [2018-05-25 09:31:19.958][http-nio-8077-exec-6][ERROR][org.apache.juli.logging.DirectJDKLog][181]:Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ArithmeticException: / by zero] with root cause java.lang.ArithmeticException: / by zero at com.wyait.manage.web.error.IndexErrorController.ajaxError(IndexErrorController.java:29) ~[classes/:?] ... at java.lang.Thread.run(Thread.java:748) [?:1.8.0_131] ... [2018-05-25 09:31:19.960][http-nio-8077-exec-6][DEBUG][org.springframework.web.servlet.handler.AbstractHandlerMethodMapping][317]:Returning handler method [public org.springframework.http.ResponseEntity org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)] [2018-05-25 09:31:19.960][http-nio-8077-exec-6][DEBUG][org.springframework.web.servlet.handler.AbstractHandlerMethodMapping][317]:Returning handler method [public org.springframework.http.ResponseEntity org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)] [2018-05-25 09:31:19.960][http-nio-8077-exec-6][DEBUG][org.springframework.beans.factory.support.AbstractBeanFactory][251]:Returning cached instance of singleton bean 'basicErrorController' [2018-05-25 09:31:19.960][http-nio-8077-exec-6][DEBUG][org.springframework.beans.factory.support.AbstractBeanFactory][251]:Returning cached instance of singleton bean 'basicErrorController' ... [2018-05-25 09:31:19.961][http-nio-8077-exec-6][DEBUG][org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor][234]:Written [{timestamp=Fri May 25 09:31:19 CST 2018, status=500, error=Internal Server Error, exception=java.lang.ArithmeticException, message=/ by zero, path=/error/ajaxError}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@2729eae5] [2018-05-25 09:31:19.961][http-nio-8077-exec-6][DEBUG][org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor][234]:Written [{timestamp=Fri May 25 09:31:19 CST 2018, status=500, error=Internal Server Error, exception=java.lang.ArithmeticException, message=/ by zero, path=/error/ajaxError}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@2729eae5] [2018-05-25 09:31:19.961][http-nio-8077-exec-6][DEBUG][org.springframework.web.servlet.DispatcherServlet][1048]:Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling ...通过日志可知,springboot返回的错误信息,是通过:org.springframework.boot.autoconfigure.web.BasicErrorController.error处理返回ResponseEntity。 异常都是通过org.springframework.boot.autoconfigure.web.BasicErrorController控制处理的。springboot异常处理解析 查看org.springframework.boot.autoconfigure.web包下面的类,跟踪springboot对error异常处理机制。自动配置通过一个MVC error控制器处理错误 通过spring-boot-autoconfigure引入 查看springboot 处理error的类 springboot的自动配置,在web中处理error相关的自动配置类:ErrorMvcAutoConfiguration。查看与处理error相关的类: ErrorMvcAutoConfiguration.class ErrorAttibutes.class ErrorController.class ErrorProperties.class ErrorViewResolver.class …ErrorAutoConfiguration类源码//TODO ErrorAutoConfiguration注册的bean //4个BEAN @Bean @ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT) public DefaultErrorAttributes errorAttributes() { return new DefaultErrorAttributes(); } @Bean @ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT) public BasicErrorController basicErrorController(ErrorAttributes errorAttributes) { return new BasicErrorController(errorAttributes, this.serverProperties.getError(), this.errorViewResolvers); } @Bean public ErrorPageCustomizer errorPageCustomizer() { return new ErrorPageCustomizer(this.serverProperties); } @Bean public static PreserveErrorControllerTargetClassPostProcessor preserveErrorControllerTargetClassPostProcessor() { return new PreserveErrorControllerTargetClassPostProcessor(); } DefaultErrorAttributes类 @Order(Ordered.HIGHEST_PRECEDENCE) public class DefaultErrorAttributes implements ErrorAttributes, HandlerExceptionResolver, Ordered { ... }ErrorAttributes: public interface ErrorAttributes { Map getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace); Throwable getError(RequestAttributes requestAttributes); }HandlerExceptionResolver: public interface HandlerExceptionResolver { /** * Try to resolve the given exception that got thrown during handler execution, * returning a {@link ModelAndView} that represents a specific error page if appropriate. */ ModelAndView resolveException( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex); }DefaultErrorAttributes类: 实现了ErrorAttributes接口,当处理/error错误页面时,可以在该bean中读取错误信息响应返回; 实现了HandlerExceptionResolver接口。debug跟踪源码:即DispatcherServlet在doDispatch过程中有异常抛出时: 一. 先由HandlerExceptionResolver.resolveException解析异常并保存在request中; 二. 再DefaultErrorAttributes.getErrorAttributes处理;DefaultErrorAttributes在处理过程中,从request中获取错误信息,将错误信息保存到RequestAttributes中; 三. 最后在获取错误信息getError(RequestAttributes)时,从RequestAttributes中取到错误信息。 BasicErrorController类 @Controller @RequestMapping("${server.error.path:${error.path:/error}}") public class BasicErrorController extends AbstractErrorController { private final ErrorProperties errorProperties; ... @RequestMapping(produces = "text/html") public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) { HttpStatus status = getStatus(request); Map model = Collections.unmodifiableMap(getErrorAttributes( request, isIncludeStackTrace(request, MediaType.TEXT_HTML))); response.setStatus(status.value()); ModelAndView modelAndView = resolveErrorView(request, response, status, model); return (modelAndView == null ? new ModelAndView("error", model) : modelAndView); } @RequestMapping @ResponseBody public ResponseEntity error(HttpServletRequest request) { Map body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL)); HttpStatus status = getStatus(request); return new ResponseEntity(body, status); } ... }resolveErrorView方法(查找=error/“错误状态码”;的资源): 如果不是异常请求,会执行resolveErrorView方法;该方法会先在默认或配置的静态资源路径下查找error/HttpStatus(错误状态码)的资源文件,如果没有;使用默认的error页面。 public class DefaultErrorViewResolver implements ErrorViewResolver, Ordered { ... @Override public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map model) { //status:异常错误状态码 ModelAndView modelAndView = resolve(String.valueOf(status), model); if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) { modelAndView = resolve(SERIES_VIEWS.get(status.series()), model); } return modelAndView; } private ModelAndView resolve(String viewName, Map model) { //视图名称,默认是error/+“status”错误状态码;比如:error/500、error/404 String errorViewName = "error/" + viewName; TemplateAvailabilityProvider provider = this.templateAvailabilityProviders .getProvider(errorViewName, this.applicationContext); if (provider != null) { return new ModelAndView(errorViewName, model); } return resolveResource(errorViewName, model); } //在资源文件中查找error/500或error/404等页面 private ModelAndView resolveResource(String viewName, Map model) { for (String location : this.resourceProperties.getStaticLocations()) { try { Resource resource = this.applicationContext.getResource(location); resource = resource.createRelative(viewName + ".html"); if (resource.exists()) { return new ModelAndView(new HtmlResourceView(resource), model); } } catch (Exception ex) { } } return null; } ... }BasicErrorController根据Accept头的内容,输出不同格式的错误响应。比如针对浏览器的请求生成html页面,针对其它请求生成json格式的返回。 可以通过配置error/HttpStatus页面实现自定义错误页面。 ErrorPageCustomizer类 /** * {@link EmbeddedServletContainerCustomizer} that configures the container's error * pages. */private static class ErrorPageCustomizer implements ErrorPageRegistrar, Ordered { private final ServerProperties properties; protected ErrorPageCustomizer(ServerProperties properties) { this.properties = properties; } @Override public void registerErrorPages(ErrorPageRegistry errorPageRegistry) { ErrorPage errorPage = new ErrorPage(this.properties.getServletPrefix() + this.properties.getError().getPath()); errorPageRegistry.addErrorPages(errorPage); } @Override public int getOrder() { return 0; } }将错误页面注册到内嵌的tomcat的servlet容器中。 PreserveErrorControllerTargetClassPostProcessor实现BeanFactoryPostProcessor接口,可以修改BEAN的配置信息ErrorAutoConfiguration内的两个配置 //2个config配置 @Configuration static class DefaultErrorViewResolverConfiguration { private final ApplicationContext applicationContext; private final ResourceProperties resourceProperties; DefaultErrorViewResolverConfiguration(ApplicationContext applicationContext, ResourceProperties resourceProperties) { this.applicationContext = applicationContext; this.resourceProperties = resourceProperties; } @Bean @ConditionalOnBean(DispatcherServlet.class) @ConditionalOnMissingBean public DefaultErrorViewResolver conventionErrorViewResolver() { return new DefaultErrorViewResolver(this.applicationContext, this.resourceProperties); } } @Configuration @ConditionalOnProperty(prefix = "server.error.whitelabel", name = "enabled", matchIfMissing = true) @Conditional(ErrorTemplateMissingCondition.class) protected static class WhitelabelErrorViewConfiguration { private final SpelView defaultErrorView = new SpelView( "Whitelabel Error Page" + "This application has no explicit mapping for /error, so you are seeing this as a fallback. " + "${timestamp}" + "There was an unexpected error (type=${error}, status=${status})." + "${message}"); @Bean(name = "error") @ConditionalOnMissingBean(name = "error") public View defaultErrorView() { return this.defaultErrorView; } // If the user adds @EnableWebMvc then the bean name view resolver from // WebMvcAutoConfiguration disappears, so add it back in to avoid disappointment. @Bean @ConditionalOnMissingBean(BeanNameViewResolver.class) public BeanNameViewResolver beanNameViewResolver() { BeanNameViewResolver resolver = new BeanNameViewResolver(); resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 10); return resolver; } } DefaultErrorViewResolverConfiguration:默认的error视图解析配置; WhitelabelErrorViewConfiguration:默认设置了/error的页面,和 Whitelabel Error Page 页面响应内容。如果Spring MVC在处理业务的过程中抛出异常,会被 Servlet 容器捕捉到,Servlet 容器再将请求转发给注册好的异常处理映射 /error 做响应处理。 springboot配置文件默认error相关配置 springboot配置文件application.properties中关于error默认配置: server.error.include-stacktrace=never # When to include a "stacktrace" attribute. server.error.path=/error # Path of the error controller. server.error.whitelabel.enabled=true # Enable the default error page displayed in browsers in case of a server error.springboot 自定义异常处理 通过跟踪springboot对异常处理得源码跟踪,根据业务需要,可以细分前端响应的错误页面,也可以统一使用/error页面+错误提示信息进行处理。 根据自己的需求自定义异常处理机制;具体可实施的操作如下: 可以通过配置error/HttpStatus(错误状态码)页面实现自定义错误页面【底层实现,详见:BasicErrorController源码】; 可以实现BasicErrorController,自定义普通请求的异常页面响应信息和异步请求的响应信息,统一使用/error页面进行错误响应提示; 自定义实现ErrorAttributes接口,覆盖DefaultErrorAttributes实现,或是继承DefaultErrorAttributes类,重写里面的方法【TODO,不推荐】。1和2的方法可单独使用,也可以结合使用。 自定义异常页面 可以根据不同的错误状态码,在前端细分不同的响应界面给用户进行提示;资源路径必须是:静态资源路径下/error/HttpStats(比如:/error/404等) 自定义异常页面 404友情提示 访问的资源未找到(404)404.html 500.html等,这里只演示404。 统一异常处理 普通请求,前端使用error页面+自定义错误响应信息; 其他请求(异步),统一自定义错误响应信息,规范处理异步响应的错误判断和处理。 使用springMVC注解ControllerAdvice /** * * @项目名称:wyait-manage * @类名称:GlobalExceptionHandler * @类描述:统一异常处理,包括【普通调用和ajax调用】 * ControllerAdvice来做controller内部的全局异常处理,但对于未进入controller前的异常,该处理方法是无法进行捕获处理的,SpringBoot提供了ErrorController的处理类来处理所有的异常(TODO)。 * 1.当普通调用时,跳转到自定义的错误页面;2.当ajax调用时,可返回约定的json数据对象,方便页面统一处理。 * @创建人:wyait * @创建时间:2018年5月22日 上午11:44:55 * @version: */@ControllerAdvice public class GlobalExceptionHandler { private static final Logger logger = LoggerFactory .getLogger(GlobalExceptionHandler.class); public static final String DEFAULT_ERROR_VIEW = "error"; /** * * @描述:针对普通请求和ajax异步请求的异常进行处理 * @创建人:wyait * @创建时间:2018年5月22日 下午4:48:58 * @param req * @param e * @return * @throws Exception */ @ExceptionHandler(value = Exception.class) @ResponseBody public ModelAndView errorHandler(HttpServletRequest request, HttpServletResponse response, Exception e) { logger.debug(getClass().getName() + ".errorHandler】统一异常处理:request="+request); ModelAndView mv=new ModelAndView(); logger.info(getClass().getName() + ".errorHandler】统一异常处理:"+e.getMessage()); //1 获取错误状态码 HttpStatus httpStatus=getStatus(request); logger.info(getClass().getName() + ".errorHandler】统一异常处理!错误状态码httpStatus:"+httpStatus); //2 返回错误提示 ExceptionEnum ee=getMessage(httpStatus); //3 将错误信息放入mv中 mv.addObject("type", ee.getType()); mv.addObject("code", ee.getCode()); mv.addObject("msg", ee.getMsg()); if(!ShiroFilterUtils.isAjax(request)){ //不是异步请求 mv.setViewName(DEFAULT_ERROR_VIEW); logger.debug(getClass().getName() + ".errorHandler】统一异常处理:普通请求。"); } logger.debug(getClass().getName() + ".errorHandler】统一异常处理响应结果:MV="+mv); return mv; } ... }运行测试:先走GlobalExceptionHandler(使用注解@ControllerAdvice)类里面的方法,而后又执行了BasicErrorController方法;被springboot自带的BasicErrorController覆盖。 实现springboot的AbstractErrorController 自定义实现AbstractErrorController,添加响应的错误提示信息。 @RequestMapping(produces = "text/html") public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) { ModelAndView mv = new ModelAndView(ERROR_PATH); /** model对象包含了异常信息 */ Map model = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)); // 1 获取错误状态码(也可以根据异常对象返回对应的错误信息) HttpStatus httpStatus = getStatus(request); // 2 返回错误提示 ExceptionEnum ee = getMessage(httpStatus); Result result = new Result( String.valueOf(ee.getType()), ee.getCode(), ee.getMsg()); // 3 将错误信息放入mv中 mv.addObject("result", result); logger.info("统一异常处理【" + getClass().getName() + ".errorHtml】统一异常处理!错误信息mv:" + mv); return mv; } @RequestMapping @ResponseBody //设置响应状态码为:200,结合前端约定的规范处理。也可不设置状态码,前端ajax调用使用error函数进行控制处理 @ResponseStatus(value=HttpStatus.OK) public Result error(HttpServletRequest request, Exception e) { /** model对象包含了异常信息 */ Map model = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)); // 1 获取错误状态码(也可以根据异常对象返回对应的错误信息) HttpStatus httpStatus = getStatus(request); // 2 返回错误提示 ExceptionEnum ee = getMessage(httpStatus); Result result = new Result( String.valueOf(ee.getType()), ee.getCode(), ee.getMsg()); // 3 将错误信息返回 // ResponseEntity logger.info("统一异常处理【" + getClass().getName() + ".error】统一异常处理!错误信息result:" + result); return result; }针对异步请求,统一指定响应状态码:200;也可以不指定,前端在处理异步请求的时候,可以通过ajax的error函数进行控制。 这里是继承的AbstractErrorController类,自定义实现统一异常处理,也可以直接实现ErrorController接口。 前端ajax异步统一处理: 通过约定,前端ajax异步请求,进行统一的错误处理。 /** * 针对不同的错误可结合业务自定义处理方式 * @param result * @returns {Boolean} */function isError(result){ var flag=true; if(result && result.status){ flag=false; if(result.status == '-1' || result.status=='-101' || result.status=='400' || result.status=='404' || result.status=='500'){ layer.alert(result.data); }else if(result.status=='403'){ layer.alert(result.data,function(){ //跳转到未授权界面 window.location.href="/403"; }); } } return flag;//返回true }使用方式: ... success:function(data){ //异常过滤处理 if(isError(data)){ alert(data); } }, ...error.html页面: 出错了() 测试效果 普通请求: 异步请求: 线上get请求乱码 问题描述 前台通过html页面,发送请求到后台查询数据,在日志中打印的sql语句显示传入的参数乱码: SELECT ... [2018-05-11 09:15:00.582][http-bio-8280-exec-2][DEBUG][org.apache.ibatis.logging.jdbc.BaseJdbcLogger][159]:==> Parameters: 1(Integer), çè´º(String) [2018-05-11 09:15:00.585][http-bio-8280-exec-2][DEBUG][org.apache.ibatis.logging.jdbc.BaseJdbcLogger][159]: |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |