• springMvc改造springboot2.0踩坑


    1. 支持jsp

    applicaiton.proerties添加配置

    #指定视图解析路径前缀
    spring.mvc.view.prefix=/WEB-INF/jsp/
    #指定视图解析后缀
    spring.mvc.view.suffix=.jsp
    #jsp修改不需要重启
    server.servlet.jsp.init-parameters.development=true

    pom.xml

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.2</version>
            <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
        <!--如果通过Application的方式启动,不可以加scope,如果通过springBoot:run的方式启动,需要加上-->
        <!--<scope>provided</scope>-->
    </dependency>    

    2.Redis配置

    package com.xx.config;
    
    import com.xx.common.DefaultKeyGenerator;
    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cache.CacheManager;
    import org.springframework.cache.annotation.CachingConfigurerSupport;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.cache.interceptor.KeyGenerator;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.cache.RedisCacheConfiguration;
    import org.springframework.data.redis.cache.RedisCacheManager;
    import org.springframework.data.redis.cache.RedisCacheWriter;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    import org.springframework.lang.Nullable;
    import redis.clients.jedis.JedisPoolConfig;
    
    import java.time.Duration;
    
    @Configuration
    @EnableCaching
    public class RedisConfig extends CachingConfigurerSupport {
    
        @Value("${spring.redis.host}")
        private String host;
    
        @Value("${spring.redis.port}")
        private int port;
    
        /**
         * 配置RedisTemplate
         * 设置添加序列化器
         * key 使用string序列化器
         * value 使用Json序列化器
         * 还有一种简答的设置方式,改变defaultSerializer对象的实现。
         * @return
         */
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
            //StringRedisTemplate的构造方法中默认设置了stringSerializer
            RedisTemplate<String, Object> template = new RedisTemplate<>();
            //set key serializer
            StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
            template.setKeySerializer(stringRedisSerializer);
            template.setConnectionFactory(redisConnectionFactory);
            template.afterPropertiesSet();
            return template;
        }
    
        @Bean
        public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory){
            RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                    .entryTtl(Duration.ofHours(1)); // 设置缓存有效期一小时
            return RedisCacheManager
                    .builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
                    .cacheDefaults(redisCacheConfiguration).build();
        }
    
        @Override
        public KeyGenerator keyGenerator() {
            return new DefaultKeyGenerator();
        }
    }

    3.上传文件配置

    @Bean
        //bean的name必须是multipartResolver,否则会出现 xxRequestxx cannot be cast to org.springframework.web.multipart.MultipartHttpServletRequest问题,同时注意common-fileupload,common-io jar包不要缺失冲突
        public CommonsMultipartResolver multipartResolver(){
            CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
            commonsMultipartResolver.setMaxUploadSize(Long.valueOf(upload_maxSize));
            commonsMultipartResolver.setDefaultEncoding("utf-8");
            return commonsMultipartResolver;
        }

    4.shiro配置

    //放在WebConfig里面
    @Bean
    //@Primary相同类型bean,按type注入时优先注入
    //shiroFilter放前面,否则其他的filter获取的request不是shiro代理对象,(在tokenFilter里,无法获取session的保存的值)
    //DelegatingFilterProxy默认实例名为delegatingFilterProxy 的bean,可通过构造参数设置bean实例名
    public FilterRegistrationBean<Filter> delegatingFilter(){
    DelegatingFilterProxy shiroFilter = new DelegatingFilterProxy("shiroFilter");
    shiroFilter.setTargetFilterLifecycle(true);
    FilterRegistrationBean<Filter> delegatingFilter = new FilterRegistrationBean<>(shiroFilter);
    return delegatingFilter;
    }
    
    

    配置shiroFilter

    @Bean
        public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager")SecurityManager securityManager){
      //SysFormAuthenticationFilter和sysLogoutFilter不可以交给spring管理,否则spring会将Filter的类,自动包装为FilterRegistrationBean变为过滤器
      SysFormAuthenticationFilter sysFormAuthenticationFilter = new SysFormAuthenticationFilter(); 
    SysLogoutFilter sysLogoutFilter = new SysLogoutFilter();
    ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    shiroFilterFactoryBean.setSecurityManager(securityManager); Map map = new HashMap();
    map.put("login",sysFormAuthenticationFilter);
    map.put("logout",sysLogoutFilter);
    shiroFilterFactoryBean.setFilters(map);
    shiroFilterFactoryBean.setLoginUrl("/login.shtml");
    shiroFilterFactoryBean.setFilterChainDefinitions("/login.shtml = login " + " /logout.shtml = logout " + " /auth/** = authc " + " /wap/auth/** = authc");
    return shiroFilterFactoryBean;
    }

      

     5.国际化配置

    properties里添加

    #国际化文件路径
    #basename为包名+配置文件名前缀 spring.messages.basename
    =i18n/messages spring.messages.use-code-as-default-message=true

    同时需要注意的是,国际化配置里,必须有 包名/配置文件名前缀.properties作为默认配置,否则不会生效

    6.序列化

    原代码
    public String toString() {
            return new GsonBuilder().serializeNulls().setDateFormat("yyyy-MM-dd HH:mm:ss:SSS").create().toJson(this);
    
    之后报错Attempted to serialize java.lang.Class: java.lang.String. Forgot to register a type adapter?
    
    改为
    public String toString() {
            return new GsonBuilder()
                    .registerTypeAdapterFactory(new ClassTypeAdapterFactory())
                    .registerTypeAdapter(Class.class, new ClassTypeAdapter())
                    .serializeNulls().setDateFormat("yyyy-MM-dd HH:mm:ss:SSS").create().toJson(this);
    public class ClassTypeAdapter extends TypeAdapter<Class<?>> {
    
        @Override
        public void write(JsonWriter jsonWriter, Class<?> clazz) throws IOException {
            if(clazz == null){
                jsonWriter.nullValue();
                return;
            }
            jsonWriter.value(clazz.getName());
        }
    
        @Override
        public Class<?> read(JsonReader jsonReader) throws IOException {
            if (jsonReader.peek() == JsonToken.NULL) {
                jsonReader.nextNull();
                return null;
            }
            Class<?> clazz = null;
            try {
                clazz = Class.forName(jsonReader.nextString());
            } catch (ClassNotFoundException exception) {
                throw new IOException(exception);
            }
            return clazz;
        }
    }
    public class ClassTypeAdapterFactory implements TypeAdapterFactory {
        @Override
        public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
            if(!Class.class.isAssignableFrom(typeToken.getRawType())) {
                return null;
            }
            return (TypeAdapter<T>) new ClassTypeAdapter();
        }
    }
  • 相关阅读:
    Python Requests-学习笔记(9)-错误与异常
    .NET C# 创建WebService服务简单的例子
    10个免费开源的JS音乐播放器插件
    7款高颜值HTML5播放器:让你的音乐有声有色
    Asp.net基于session实现购物车的方法
    ASP.NET用GridView控件实现购物车功能
    jquery鼠标跟随流体吸引特效
    jquery鼠标跟随特效
    JQUERY互动星空粒子背景效果
    jQuery插件库常用前端库引用地址
  • 原文地址:https://www.cnblogs.com/jaxlove-it/p/10489986.html
Copyright © 2020-2023  润新知