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

成品网站前台源码成品网站源码的优化技巧

成品网站前台源码,成品网站源码的优化技巧,网页游戏排行榜前十名田田田田田田田田田田,找个美工做淘宝网站需要多少钱这里记录回顾一些知识,不然就快忘记啦。 环境:SpringBoot 2.0.4.RELEASE需求:很多Controller方法,刚进来要先获取当前登录用户的信息,以便做后续的用户相关操作。准备工作:前端每次请求都传token&#xff0…

这里记录回顾一些知识,不然就快忘记啦。

  • 环境:SpringBoot 2.0.4.RELEASE
  • 需求:很多Controller方法,刚进来要先获取当前登录用户的信息,以便做后续的用户相关操作。
  • 准备工作:前端每次请求都传token,后端封装一方法tokenUtils.getUserByToken(token),根据token解析得到currentUserInfo。

  这是一个常见的业务需求,为实现这个需求,有以下几种解决方案:

一、最原始直接

  即,每个Controller开始,先调用tokenUtils.getUserByToken(token),不够优雅。

二、AOP

  AOP可以解决很多切面类问题,思路同Spring AOP来自定义注解实现审计或日志记录,将currentUser放到request里;比起拦截器稍重。

三、拦截器+方法参数解析器

  使用mvc拦截器HandlerInterceptor+方法参数解析器HandlerMethodArgumentResolver最合适。

  SpringMVC提供了mvc拦截器HandlerInterceptor,包含以下3个方法:

  • preHandle
  • postHandle
  • afterCompletion

  HandlerInterceptor经常被用来解决拦截事件,如用户鉴权等。另外,Spring也向我们提供了多种解析器Resolver,如用来统一处理异常的HandlerExceptionResolver,以及今天的主角        HandlerMethodArgumentResolverHandlerMethodArgumentResolver是用来处理方法参数的解析器,包含以下2个方法:

  • supportsParameter(满足某种要求,返回true,方可进入resolveArgument做参数处理)
  • resolveArgument

知识储备已到位,接下来着手实现,主要分为三步走:

  1. 自定义权限拦截器AuthenticationInterceptor拦截所有request请求,并将token解析为currentUser,最终放到request中;
  2. 自定义参数注解@CurrentUser,添加至controller的方法参数user之上;
  3. 自定义方法参数解析器CurrentUserMethodArgumentResolver,取出request中的user,并赋值给添加了@CurrentUser注解的参数user。

 

使用方式

要使用 HandlerMethodArgumentResolver,需要遵循以下步骤:

  1. 创建一个自定义的 HandlerMethodArgumentResolver 实现类。
  2. 在该类中实现 supportsParameter() 方法和 resolveArgument() 方法。
  3. 在 Spring Boot 应用程序中注册该类。

创建自定义的 HandlerMethodArgumentResolver 实现类

        为了将 HTTP 请求参数转换为 Java 对象,我们需要创建一个自定义的 HandlerMethodArgumentResolver 实现类。在这个类中,我们需要实现 supportsParameter() 方法和 resolveArgument() 方法。

supportsParameter() 方法

        在 supportsParameter() 方法中,我们需要检查方法参数是否与我们要转换的 Java 类型相同。如果是,返回 true,否则返回 false

resolveArgument() 方法

        在 resolveArgument() 方法中,我们需要将 HTTP 请求参数转换为 Java 对象。为此,我们可以使用 NativeWebRequest 对象来获取请求参数,然后将其转换为 Java 对象。

注册自定义的 HandlerMethodArgumentResolver 实现类

        要在 Spring Boot 应用程序中使用自定义的 HandlerMethodArgumentResolver 实现类,我们需要将其注册到应用程序上下文中。为此,我们可以创建一个 @Configuration 类,并实现 WebMvcConfigurer 接口。在这个类中,我们需要重写 addArgumentResolvers() 方法,并将自定义的 HandlerMethodArgumentResolver 实现类添加到参数解析器列表中。

@Configuration

public class AppConfig implements WebMvcConfigurer {

@Override

public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {

resolvers.add(new CustomHandlerMethodArgumentResolver());

}

}

3.1 自定义权限拦截器

  自定义权限拦截器AuthenticationInterceptor,需实现HandlerInterceptor。在preHandle中调用tokenUtils.getUserByToken(token),获取到当前用户,最后塞进request中,如下:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import edp.core.utils.TokenUtils;
import edp.davinci.core.common.Constants;
import edp.davinci.model.User;public class AuthenticationInterceptor implements HandlerInterceptor {@Autowiredprivate TokenUtils tokenUtils;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token = request.getHeader("Authorization");User user = tokenUtils.getUserByToken(token);request.setAttribute(Constants.CURRENT_USER, user);return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}

3.2 自定义参数注解

  自定义方法参数上使用的注解@CurrentUser,代表被它注解过的参数的值都需要由方法参数解析器CurrentUserMethodArgumentResolver来“注入”,如下:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 自定义 当前用户 注解* 注解 参数* 此注解在验证token通过后,获取当前token包含用户*/
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUser {
}

3.3 自定义方法参数解析器

  自定义方法参数解析器CurrentUserMethodArgumentResolver,需实现HandlerMethodArgumentResolver。

import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;import edp.core.annotation.CurrentUser;
import edp.core.consts.Consts;
import edp.davinci.model.User;/*** @CurrentUser 注解 解析器*/
public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {@Overridepublic boolean supportsParameter(MethodParameter parameter) {return parameter.getParameterType().isAssignableFrom(User.class)&& parameter.hasParameterAnnotation(CurrentUser.class);}@Overridepublic Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {return  (User) webRequest.getAttribute(Consts.CURRENT_USER, RequestAttributes.SCOPE_REQUEST);}
}As we all know,拦截器定义好以后,在SpringMVC项目中,需要去SpringMVC的配置文件springmvc.xml添加该拦截器;但是在SpringBoot中,省去了很多配置文件,取而代之的是被注解@Configuration标识的配置类,SpringMVC配置文件对应的配置类需继承WebMvcConfigurationSupport。同理,解析器定义好以后,也需被添加到SpringMVC的配置文件或配置类中。最后,额外的一步,配置mvc。

3.4 配置MVC

  定义MVC配置类,需继承WebMvcConfigurationSupport。分别在addInterceptors和addArgumentResolvers方法中,添加自定义的拦截器和参数解析器,如下:

import static edp.core.consts.Consts.EMPTY;import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;import edp.davinci.core.common.Constants;
import edp.davinci.core.inteceptor.AuthenticationInterceptor;
import edp.davinci.core.inteceptor.CurrentUserMethodArgumentResolver;@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {@Value("${file.userfiles-path}")private String filePath;/*** 登录校验拦截器** @return*/@Beanpublic AuthenticationInterceptor loginRequiredInterceptor() {return new AuthenticationInterceptor();}/*** CurrentUser 注解参数解析器** @return*/@Beanpublic CurrentUserMethodArgumentResolver currentUserMethodArgumentResolver() {return new CurrentUserMethodArgumentResolver();}/*** 参数解析器** @param argumentResolvers*/@Overrideprotected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {argumentResolvers.add(currentUserMethodArgumentResolver());super.addArgumentResolvers(argumentResolvers);}@Overrideprotected void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginRequiredInterceptor()).addPathPatterns(Constants.BASE_API_PATH + "/**").excludePathPatterns(Constants.BASE_API_PATH + "/login");super.addInterceptors(registry);}@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/").addResourceLocations("classpath:/static/page/").addResourceLocations("classpath:/static/templates/").addResourceLocations("file:" + filePath);}@Overrideprotected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();FastJsonConfig fastJsonConfig = new FastJsonConfig();fastJsonConfig.setSerializerFeatures(SerializerFeature.QuoteFieldNames,SerializerFeature.WriteEnumUsingToString,SerializerFeature.WriteMapNullValue,SerializerFeature.WriteDateUseDateFormat,SerializerFeature.DisableCircularReferenceDetect);fastJsonConfig.setSerializeFilters((ValueFilter) (o, s, source) -> {if (null != source && (source instanceof Long || source instanceof BigInteger) && source.toString().length() > 15) {return source.toString();} else {return null == source ? EMPTY : source;}});//处理中文乱码问题List<MediaType> fastMediaTypes = new ArrayList<>();fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);fastConverter.setSupportedMediaTypes(fastMediaTypes);fastConverter.setFastJsonConfig(fastJsonConfig);converters.add(fastConverter);}
}

多个场景案例

        以下是一些场景案例,演示了如何使用 HandlerMethodArgumentResolver 解析不同类型的请求参数。

将 JSON 请求体转换为 Java 对象

        假设有一个 POST 请求,其中包含以下 JSON 请求体:

{ "name": "John", "age": 30}

        我们可以创建一个自定义的 HandlerMethodArgumentResolver 实现类来将这些参数转换为 Java 对象。

public class JsonHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver 
{
    @Override
    public boolean supportsParameter(MethodParameter parameter) 
    {
        return parameter.hasParameterAnnotation(RequestBody.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception 
    {
        String json = webRequest.getNativeRequest(HttpServletRequest.class).getReader().lines().collect(Collectors.joining(System.lineSeparator()));
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(json, parameter.getParameterType());

    }
}

        在这个示例中,我们创建了一个名为 JsonHandlerMethodArgumentResolver 的自定义 HandlerMethodArgumentResolver 实现类,并在其中解析 JSON 请求体。在 supportsParameter() 方法中,我们检查方法参数是否带有 @RequestBody 注解。在 resolveArgument() 方法中,我们从请求体中读取 JSON 数据,并使用 ObjectMapper 将其转换为 Java 对象。

将 XML 请求体转换为 Java 对象

假设有一个 POST 请求,其中包含以下 XML 请求体:

<user> <name>John</name> <age>30</age></user>

我们可以创建一个自定义的 HandlerMethodArgumentResolver 实现类来将这些参数转换为 Java 对象。

public class XmlHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver 
{

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(RequestBody.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception 
    {
        String xml = webRequest.getNativeRequest(HttpServletRequest.class).getReader().lines().collect(Collectors.joining(System.lineSeparator()));
        JAXBContext jaxbContext = JAXBContext.newInstance(parameter.getParameterType());
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        StringReader reader = new StringReader(xml);
        return unmarshaller.unmarshal(reader);

    }
}

在这个示例中,我们创建了一个名为 XmlHandlerMethodArgumentResolver 的自定义 HandlerMethodArgumentResolver 实现类,并在其中解析 XML 请求体。在 supportsParameter() 方法中,我们检查方法参数是否带有 @RequestBody 注解。在 resolveArgument() 方法中,我们从请求体中读取 XML 数据,并使用 JAXBContext 和 Unmarshaller 将其转换为 Java 对象。

将多个请求参数转换为 Java 对象

假设有一个 GET 请求,其中包含以下请求参数:

name=John&age=30

我们可以创建一个自定义的 HandlerMethodArgumentResolver 实现类来将这些参数转换为 Java 对象。

public class UserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().equals(User.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        String name = webRequest.getParameter("name");
        int age = Integer.parseInt(webRequest.getParameter("age"));

        User user = new User();
        user.setName(name);
        user.setAge(age);
        return user;
    }
}

        在这个示例中,我们创建了一个名为 UserHandlerMethodArgumentResolver 的自定义 HandlerMethodArgumentResolver 实现类,并在其中解析多个请求参数。在 supportsParameter() 方法中,我们检查方法参数是否与 User 类型相同。在 resolveArgument() 方法中,我们从请求参数中获取数据,并将其转换为 User 对象。

注册自定义的 HandlerMethodArgumentResolver 实现类

        要在 Spring Boot 应用程序中使用自定义的 HandlerMethodArgumentResolver 实现类,我们需要将其注册到应用程序上下文中。为此,我们可以创建一个 @Configuration 类,并实现 WebMvcConfigurer 接口。在这个类中,我们需要重写 addArgumentResolvers() 方法,并将自定义的 HandlerMethodArgumentResolver 实现类添加到参数解析器列表中。

@Configuration

public class AppConfig implements WebMvcConfigurer {

@Override

public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {

resolvers.add(new JsonHandlerMethodArgumentResolver());

resolvers.add(new XmlHandlerMethodArgumentResolver());

resolvers.add(new UserHandlerMethodArgumentResolver());

}

}

        现在,我们已经成功地创建了多个自定义的 HandlerMethodArgumentResolver 实现类,并将它们注册到 Spring Boot 应用程序中。这样,我们就能够轻松地处理不同类型的请求参数,并将它们转换为 Java 对象。

自定义注解来简化参数赋值。

例如,假设您有一个 @UserParam 注解,您可以使用以下代码来解析它:

public class UserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

@Override

public boolean supportsParameter(MethodParameter parameter) {

return parameter.getParameterAnnotation(UserParam.class) != null;

}

@Override

public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

UserParam userParam = parameter.getParameterAnnotation(UserParam.class);

String name = webRequest.getParameter(userParam.name());

int age = Integer.parseInt(webRequest.getParameter(userParam.age()));

User user = new User();

user.setName(name);

user.setAge(age);

return user;

}

}

        在这个示例中,我们创建了一个 @UserParam 注解,并将其应用于方法参数上。然后,我们可以在 supportsParameter() 方法中检查方法参数是否带有 @UserParam 注解。在 resolveArgument() 方法中,我们从注解中获取参数名,并从请求参数中获取相应的值,然后将其转换为 User 对象。

        要在 Spring Boot 应用程序中使用自定义注解,您需要将您的注解类添加到 @Configuration 类中,并将其添加到 addArgumentResolvers() 方法中:

@Configuration

public class AppConfig implements WebMvcConfigurer {

@Override

public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {

resolvers.add(new UserHandlerMethodArgumentResolver());

}

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.PARAMETER)

public @interface UserParam {

String name() default "name";

String age() default "age";

}

}

现在,您就可以在 Spring Boot 应用程序中使用 @UserParam 注解来简化

参考

HandlerMethodArgumentResolver用于统一获取当前登录用户_metaobjecthandler获取token-CSDN博客

Spring Boot HandlerMethodArgumentResolver 使用和场景-Spring专区论坛-技术-SpringForAll社区

HandlerMethodArgumentResolver(四):自定参数解析器处理特定应用场景,介绍PropertyNamingStrategy的使用【享学Spring MVC】-腾讯云开发者社区-腾讯云

http://www.dinnco.com/news/41502.html

相关文章:

  • 潮州网站seo推广百度经验首页
  • 建行信用卡网站优化设计电子版在哪找
  • 南京专业网站建设百度网站首页
  • wordpress显示flash logo关键词排名优化官网
  • 网站怎么做跳转安全百度搜一搜
  • 青海住房和城乡建设厅网站首页如何线上推广引流
  • 做商城网站需要什么天津seo培训
  • 十个最好的网站帆软社区app
  • 个人网站备案做论坛怎么做推广和宣传平台
  • 科技 公司 响应式 网站常州百度关键词优化
  • 酷 网站模板江门seo网站推广
  • 微信会员卡小程序济南seo关键词优化方案
  • 网站建设发展站长网站工具
  • 网站搭建和网页设计新闻发布稿
  • 海南营业执照代办qq群排名优化
  • 辽阳网站建设seo培训学院官网
  • 专做定制网站建设成人教育培训机构排名
  • 北京朝阳做网站上海专业网络推广公司
  • 生活服务网站开发怎么让百度快速收录网站
  • 如何借用别人静态网站做模板百度移动点击排名软件
  • wordpress 找回密码邮件错误seo优化网站推广
  • 免费ppt模板下载免费版百度云漯河seo推广
  • 手机平台网站开发百度网站搜索排名
  • 佛山电商网站制作it教育培训机构
  • 花卉网站建设策划书企业官网
  • 电脑可以做网站主机么杭州产品推广服务公司
  • 做网站后台的叫什么恩城seo的网站
  • 浙江住房与城乡建设厅官方网站查询湖南网站seo推广
  • 做外贸的怎么建立自己的网站百度热搜榜怎么打开
  • 阜新市建设学校官方网站html做一个简单的网页