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();
    }
}
原文地址:https://www.cnblogs.com/jaxlove-it/p/10489986.html