@data注解_springboot2.1+shiro权限注解、统一异常处理

springboot + shiro 权限注解、请求乱码解决、统一异常处理

springboot 2.1 后台角色权限管理系统,相关文章:

springboot 2.1+shiro+redis+layUI后台权限管理系统

springboot 2.1 + shiro之登录限制、登录重定向、cookie时间设置

基于前篇,新增功能:

  1. 新增shiro权限注解;
  2. 请求乱码问题解决;
  3. 统一异常处理。

源码地址

  • github源码:

https://github.com/wyait/admin.git

  • 码云:

https://gitee.com/wyait/wyait-admin.git

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的认证注解处理是有内定的处理顺序的,如果有多个注解的话,前面的通过了会继续检查后面的,若不通过则直接返回,处理顺序依次为(与实际声明顺序无关):

RequiresRolesRequiresPermissionsRequiresAuthenticationRequiresUserRequiresGuest

以上注解既可以用在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 * @return */@Beanpublic DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();advisorAutoProxyCreator.setProxyTargetClass(true);return advisorAutoProxyCreator;}@Beanpublic 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 */@RequestMapping("getError")public void toError(){System.out.println(1/0);}/** *  * @描述:异步异常 * @创建人:wyait */@RequestMapping("ajaxError")@ResponseBodypublic String ajaxError(){System.out.println(1/0);return "异步请求成功!";}

异常效果

  • 普通异常:
    console错误信息:
[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 causejava.lang.ArithmeticException: / by zeroat com.wyait.manage.web.error.IndexErrorController.toError(IndexErrorController.java:18) ~[classes/:?]...at java.lang.Thread.run(Thread.java:748) [?:1.8.0_131]...

通过日志可知,springboot返回的错误页面,是通过:org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml处理返回ModelAndView

  • 异步异常:
    console日志信息:
[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 causejava.lang.ArithmeticException: / by zeroat com.wyait.manage.web.error.IndexErrorController.ajaxError(IndexErrorController.java:29) ~[classes/:?]...at java.lang.Thread.run(Thread.java:748) [?:1.8.0_131]...[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)][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)][http-nio-8077-exec-6][DEBUG][org.springframework.beans.factory.support.AbstractBeanFactory][251]:Returning cached instance of singleton bean 'basicErrorController'[http-nio-8077-exec-6][DEBUG][org.springframework.beans.factory.support.AbstractBeanFactory][251]:Returning cached instance of singleton bean 'basicErrorController'...[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][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][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的类

@data注解_springboot2.1+shiro权限注解、统一异常处理_第1张图片

ErrorMvcAutoConfiguration类

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);}@Beanpublic ErrorPageCustomizer errorPageCustomizer() {return new ErrorPageCustomizer(this.serverProperties);}@Beanpublic static PreserveErrorControllerTargetClassPostProcessor preserveErrorControllerTargetClassPostProcessor() {return new PreserveErrorControllerTargetClassPostProcessor();}
  1. DefaultErrorAttributes类
@Order(Ordered.HIGHEST_PRECEDENCE)public class DefaultErrorAttributesimplements 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中取到错误信息。
  1. 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@ResponseBodypublic 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页面实现自定义错误页面。

  1. 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;}@Overridepublic void registerErrorPages(ErrorPageRegistry errorPageRegistry) {ErrorPage errorPage = new ErrorPage(this.properties.getServletPrefix()+ this.properties.getError().getPath());errorPageRegistry.addErrorPages(errorPage);}@Overridepublic int getOrder() {return 0;}}

将错误页面注册到内嵌的tomcat的servlet容器中。

  1. PreserveErrorControllerTargetClassPostProcessor实现BeanFactoryPostProcessor接口,可以修改BEAN的配置信息

ErrorAutoConfiguration内的两个配置

//2个config配置@Configurationstatic 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)@ConditionalOnMissingBeanpublic 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;}}
  1. DefaultErrorViewResolverConfiguration:默认的error视图解析配置;
  2. 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页面+错误提示信息进行处理。

根据自己的需求自定义异常处理机制;具体可实施的操作如下:

  1. 可以通过配置error/HttpStatus(错误状态码)页面实现自定义错误页面【底层实现,详见:BasicErrorController源码】;
  2. 可以实现BasicErrorController,自定义普通请求的异常页面响应信息和异步请求的响应信息,统一使用/error页面进行错误响应提示;【推荐】
  3. 自定义实现ErrorAttributes接口,覆盖DefaultErrorAttributes实现,或是继承DefaultErrorAttributes类,重写里面的方法【TODO,不推荐】。

1和2的方法可单独使用,也可以结合使用。

自定义异常页面

可以根据不同的错误状态码,在前端细分不同的响应界面给用户进行提示;资源路径必须是:静态资源路径下/error/HttpStats(比如:/error/404等)

  1. 自定义异常页面
    404友情提示

访问的资源未找到(404)

404.html
500.html等,这里只演示404。

统一异常处理

普通请求,前端使用error页面+自定义错误响应信息;
其他请求(异步),统一自定义错误响应信息,规范处理异步响应的错误判断和处理。

在springboot的高版本中(1.5.12及以上),error页面命名不可取名为error.html,否则报错!

实现springboot的AbstractErrorController

自定义实现AbstractErrorController,添加响应的错误提示信息。

@RequestMapping(produces = "text/html")public ModelAndView errorHtml(HttpServletRequest request,HttpServletResponse response) {logger.debug("统一异常处理【" + getClass().getName()+ ".errorHtml】text/html=普通请求:request=" + request);ModelAndView mv = new ModelAndView(ERROR_PATH);// Collections.unmodifiableMap生成一个不可变的map集合,key不可修改,value对象内的数据可更新;Map中的大小、对象地址不可修改// [官方翻译]该方法返回了一个map的不可修改的视图umap, 为用户提供了一种生成只读容器的方法。如果尝试修改该容器umap,// 将会抛出UnsupportedOperationException异常/** model对象包含了异常信息 */Map model = getErrorAttributes(request,isIncludeStackTrace(request, MediaType.TEXT_HTML));logger.info("统一异常处理【" + getClass().getName()+ ".errorHtml】统一异常处理:model=" + model);// 1 获取错误状态码(也可以根据异常对象返回对应的错误信息)HttpStatus httpStatus = getStatus(request);logger.debug("统一异常处理【" + getClass().getName()+ ".errorHtml】统一异常处理!错误状态码httpStatus:" + httpStatus);// 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) {logger.info("统一异常处理【" + getClass().getName()+ ".error】text/html=普通请求:request=" + request );/** model对象包含了异常信息 */Map model = getErrorAttributes(request,isIncludeStackTrace(request, MediaType.TEXT_HTML));logger.info("统一异常处理【" + getClass().getName()+ ".error】统一异常处理:model=" + model);// 1 获取错误状态码(也可以根据异常对象返回对应的错误信息)HttpStatus httpStatus = getStatus(request);logger.debug("统一异常处理【" + getClass().getName()+ ".error】统一异常处理!错误状态码httpStatus:" + httpStatus);// 2 返回错误提示ExceptionEnum ee = getMessage(httpStatus);Result result = new Result(String.valueOf(ee.getType()), ee.getCode(), ee.getMsg());// 3 将错误信息返回//ResponseEntitylogger.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);}},...

自定义serverError.html页面:

    

出错了

()

测试效果

普通请求:

8b20aaea7ff6d123238ee45a14994d4f.png

错误提示页面效果


异步请求:

89d93a0db3fbe8c2ad56ce7faeda1acf.png

异步请求error提示

线上get请求乱码

问题描述

前台通过html页面,发送请求到后台查询数据,在日志中打印的sql语句显示传入的参数乱码:

 SELECT ... [http-bio-8280-exec-2][DEBUG][org.apache.ibatis.logging.jdbc.BaseJdbcLogger][159]:==> Parameters: 1(Integer), çè´º(String)[http-bio-8280-exec-2][DEBUG][org.apache.ibatis.logging.jdbc.BaseJdbcLogger][159]:<==      Total: 1...

本地windows开发环境测试没有乱码问题;

请求信息

@data注解_springboot2.1+shiro权限注解、统一异常处理_第2张图片

get请求


前端页面发送get请求,浏览器默认对get请求路径进行URL编码处理。

后台Controller打印的日志

分页查询用户列表!搜索条件:userSearch:UserSearchDTO{page=1, limit=10, uname='çç', umobile='', insertTimeStart='', insertTimeEnd=''},page:1,每页记录数量limit:10,请求编码:UTF-8

Controller层在接收到这个uname参数时,已经是乱码,ISO-8859-1解码后的结果。

请求参数编码流程

  1. 前端页面发送get请求,浏览器默认在中文的UTF-8后加上上%得到URL编码,比如:%e8%b4%b9%e7...;
  2. get请求到tomcat应用服务器后,会以默认的ISO-8859-1进行解码;
  3. 在controller中,接收到的是经过URL编码和iso-8859-1解码后的参数值。

具体编码细节:可google、百度了解。

解决方案

项目编码配置【可以不配置】

开发前,默认必须统一编码环境;正常都是设置为utf-8。

spring boot 与spring mvc不同,在web应用中,spring boot默认的编码格式为UTF-8,而spring mvc的默认编码格式为iso-8859-1。

spring boot项目中如果没有特殊需求,该编码不需要修改。如果要强制其他编码格式,spring boot提供了设置方式:

  1. 通过application.properties配置文件设置:
# 默认utf-8配置spring.http.encoding.force=truespring.http.encoding.charset=UTF-8spring.http.encoding.enabled=trueserver.tomcat.uri-encoding=UTF-8

此时拦截器中返回的中文已经不乱码了,但是controller中返回的数据可能会依旧乱码。

  1. 参考spring MVC的方式,自定义实现WebMvcConfigurerAdapter类,处理响应数据乱码问题:
@Beanpublic HttpMessageConverter responseBodyConverter() {    StringHttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8"));    return converter;}@Overridepublic void configureMessageConverters(List> converters) {    super.configureMessageConverters(converters);    converters.add(responseBodyConverter());}

也可以在controller方法@RequestMapping上添加:

produces="text/plain;charset=UTF-8"

这种方法的弊端是限定了数据类型。

乱码解决方案

表单get方式提交,中文乱码解决方案:

  1. 改为post请求;
  2. 手动编解码:
//get请求乱码问题解决//如果是iso8859-1编码if (param.equals(new String(param.getBytes("iso8859-1"),"iso8859-1"))) {param=new String(param.getBytes("iso8859-1"), "utf-8");}
  1. 修改tomcat配置server.xml文件: 找到如下代码:

在这里添加一个属性:URIEncoding,将该属性值设置为UTF-8,即可让Tomcat(默认ISO-8859-1编码)以UTF-8的编码处理get请求。

修改完成后:

  1. 发送get请求前,浏览器中两次URL编码:
    两次编码两次解码的过程为:UTF-8编码->UTF-8(iso-8859-1)编码->iso-8859-1解码->UTF-8解码,编码和解码的过程是对称的,所以不会出现乱码。
    //js代码    param = encodeURI(param);    // alert("第一次URL编码:" + param);    param = encodeURI(param);    // alert("第二次URL编码:" + param);

后台代码:

//两次解码URLDecoder.decode(URLDecoder.decode(param,"utf-8"),"utf-8");

总结

以上四种解决方案,可结合具体情况进行使用。

源码

源码地址

  • github源码:

https://github.com/wyait/admin.git

  • 码云:

https://gitee.com/wyait/wyait-admin.git

springboot 2.1 后台系统相关文章

springboot 2.1+shiro+redis+layUI后台权限管理系统

springboot 2.1 + shiro之登录限制、登录重定向、cookie时间设置

你可能感兴趣的:(@data注解,@data注解不生效,apache,shiro原理)