springMvc改造springboot2.0踩坑

1. 支持jsphtml

applicaiton.proerties添加配置java

#指定視圖解析路徑前綴
spring.mvc.view.prefix=/WEB-INF/jsp/
#指定視圖解析後綴
spring.mvc.view.suffix=.jsp
#jsp修改不須要重啓
server.servlet.jsp.init-parameters.development=true

pom.xmlweb

<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配置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.上傳文件配置spring

@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配置apache

 

//放在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;
}
 

 

配置shiroFilterjson

@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\n\t" + " /logout.shtml = logout\n\t" + " /auth/** = authc\n\t" + " /wap/auth/** = authc");
return shiroFilterFactoryBean;
}

  

 5.國際化配置api

properties裏添加緩存

#國際化文件路徑
#basename爲包名+配置文件名前綴 spring.messages.basename
=i18n/messages spring.messages.use-code-as-default-message=true

同時須要注意的是,國際化配置裏,必須有 包名/配置文件名前綴.properties做爲默認配置,不然不會生效tomcat

 

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();
    }
}
相關文章
相關標籤/搜索