目录
yaml配置含端口配置, 上下文配置, thymeleaf快速配置
yaml配置含端口配置, 上下文配置, thymeleaf快速配置
spring:
http:
encoding:
charset: UTF-8
enabled: true
force: true
thymeleaf:
prefix: 'classpath:/templates/'
suffix: '.html'
mode: HTML5
servlet:
content-type: text/html
cache: false
encoding: utf-8
mvc:
static-path-pattern: /static/**
resources:
static-locations: classpath:/static
server:
port: 8081
servlet:
context-path: /mail-web
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.nega.commons.model*
configuration:
map-underscore-to-camel-case: true
jdbc-type-for-null: NULL
lazy-loading-enabled: false
aggressive-lazy-loading: true
pagehelper:
helper-dialect: mysql
reasonable: false
support-methods-arguments: true
params: count=countSql
page-size-zero: true
offset-as-page-num: true
row-bounds-with-count: true
文件 上传代码:
@PostMapping("upload")
@ResponseBody
public Message upload(@RequestParam("file") MultipartFile file) {
String fileName = DataUtil.getRandomData(5) +"-"+ DateUtils.date2String(new Date(), DateUtils.YYYYMMDDHHMMSS)+".jpg";
String destFileName = null;
String os = System.getProperties().getProperty("os.name");
if (os.startsWith("win") || os.startsWith("Win")) {
destFileName = "D:\\image\\uploaded";
} else {
destFileName = "/opt/image/" + "uploaded";
}
File patht = new File(destFileName);
if (!patht.exists()) {
patht.mkdirs();
}
destFileName = destFileName + File.separator + fileName;
FileInputStream fileInputStream = null;
BufferedOutputStream bos = null;
try {
fileInputStream = (FileInputStream) file.getInputStream();
bos = new BufferedOutputStream(new FileOutputStream(destFileName));
byte[] bs = new byte[1024];
int len;
while ((len = fileInputStream.read(bs)) != -1) {
bos.write(bs, 0, len);
}
return Message.success(fileName);
} catch (IOException e) {
log.error("上传异常",e);
}finally {
try {
if (bos!=null){
bos.flush();
}
} catch (IOException e) {
log.error("上传异常",e);
}
try {
if (bos!=null){
bos.close();
}
} catch (IOException e) {
log.error("上传异常",e);
}
}
return Message.error("删除异常");
}
dubbo配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://dubbo.apache.org/schema/dubbo
http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- dubbo默认配置,不可删除 -->
<dubbo:application name="${dubbo.application.name}">
<dubbo:parameter key="qos.enable" value="true" />
<dubbo:parameter key="qos.accept.foreign.ip" value="false" />
<dubbo:parameter key="qos.port" value="33333" />
</dubbo:application>
<dubbo:registry id="hg" address="${dubbo.registry.address}" group="dubbo-hg" default="true"/>
<dubbo:protocol port="50188" threadpool="cached" threads="1000" accepts="500"/>
<dubbo:consumer timeout="${dubbo.consumer.timeout}" retries="0"/>
</beans>
redisson 配置
clusterServersConfig:
idleConnectionTimeout: 10000
pingTimeout: 1000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
reconnectionTimeout: 3000
failedAttempts: 3
subscriptionsPerConnection: 5
clientName: null
loadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> {}
slaveSubscriptionConnectionMinimumIdleSize: 1
slaveSubscriptionConnectionPoolSize: 50
slaveConnectionMinimumIdleSize: 32
slaveConnectionPoolSize: 64
masterConnectionMinimumIdleSize: 32
masterConnectionPoolSize: 64
readMode: "SLAVE"
nodeAddresses:
- "redis://redis1:7000"
- "redis://redis2:7001"
- "redis://redis3:7002"
- "redis://redis3:7003"
- "redis://redis3:7004"
- "redis://redis3:7005"
scanInterval: 1000
threads: 0
nettyThreads: 0
codec: !<org.redisson.codec.JsonJacksonCodec> {}
transportMode: NIO
shiro代码配置:
package com.nega.commons.config;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.nega.commons.filter.ShiroUrlPermissionsFilter;
import com.nega.commons.shiro.UserAuthorizingRealm;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.BufferedImageHttpMessageConverter;
import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Shiro配置类
* @author Garc
*
*/
@Configuration
public class ShiroConfiguration {
/**
* 配置shiro过滤器
*/
@Bean("shiroFilter")
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map<String,String> filterChainMap = new LinkedHashMap<>();
filterChainMap.put("/index**","anon");
filterChainMap.put("/video/login**","anon");
filterChainMap.put("/video/logout**","anon");
filterChainMap.put("/video/image/**","anon");
filterChainMap.put("/static/**","anon");
// filterChainMap.put("/**","authc,perms");
filterChainMap.put("/video/**","authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainMap);
shiroFilterFactoryBean.setLoginUrl("/video/index");
shiroFilterFactoryBean.setSuccessUrl("/video/index");
shiroFilterFactoryBean.setUnauthorizedUrl("/video/index");
//自定义鉴权方式(动态URL鉴权)
Map<String, Filter> filter = new HashMap<>();
filter.put("perms",new ShiroUrlPermissionsFilter());
shiroFilterFactoryBean.setFilters(filter);
return shiroFilterFactoryBean;
}
@Bean
public UserAuthorizingRealm userAuthorizingRealm(){
return new UserAuthorizingRealm();
}
/**
* 配置安全管理器
*/
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userAuthorizingRealm());
return securityManager;
}
@Bean
public ShiroDialect shiroDialect(){
return new ShiroDialect();
}
@Bean
public BufferedImageHttpMessageConverter bufferedImageHttpMessageConverter(){
return new BufferedImageHttpMessageConverter();
}
}
package com.nega.commons.filter;
import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @Author: Garcia
* @CreateDate: 2019/5/18 19:27
* @Description: shiro 自定义鉴权,使用URL动态鉴权
*/
public class ShiroUrlPermissionsFilter extends PermissionsAuthorizationFilter {
public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
return super.isAccessAllowed(request, response, buildPermissions(request));
}
/**
* 根据请求URL产生权限字符串,这里只产生,而比对的事交给Realm
* @param request
* @return
*/
private String[] buildPermissions(ServletRequest request) {
String[] perms = new String[1];
HttpServletRequest req = (HttpServletRequest) request;
String path = req.getServletPath();
perms[0] = path;
return perms;
}
}
package com.nega.commons.shiro;
import com.nega.commons.model.User;
import com.nega.modules.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.util.DigestUtils;
import javax.annotation.Resource;
import java.util.HashSet;
import java.util.Set;
/**
* @author Garc
*
*/
@Slf4j
public class UserAuthorizingRealm extends AuthorizingRealm {
@Resource
private UserService userService;
private String mg = "qazwsxedc123!";
/**
* 鉴权
* @param principals
* @return AuthorizationInfo
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
if (principals == null) {
throw new AuthorizationException("PrincipalCollection method argument cannot be null.");
}
User user = (User) getAvailablePrincipal(principals);
Set<String> permissions = new HashSet<>();
// 权限
permissions.add("/mem/index");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setStringPermissions(permissions);
return info;
}
/**
* 认证
* @param token
* @return AuthenticationInfo
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken uToken = (UsernamePasswordToken) token;
String userName = uToken.getUsername();
String password = DigestUtils.md5DigestAsHex(new String(uToken.getPassword()).getBytes());
if ("garc".equals(userName)&&"59e6ac59ecc41986d38065b8e242b0f0".equals(password)){
User garc = new User();
garc.setPassword(password);
garc.setName(userName);
return new SimpleAuthenticationInfo(garc, garc.getPassword(), this.getName());
}
User user = userService.getUserByName(userName);
if (user == null) {
throw new UnknownAccountException("ER-99");
}
if (!user.getPassword().equals(password)){
throw new IncorrectCredentialsException("ER-02");
}
if (!user.getStatus()){
throw new DisabledAccountException("ER-03");
}
return new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
}
@Override
public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
HashedCredentialsMatcher credentialsMatche = new HashedCredentialsMatcher();
credentialsMatche.setHashAlgorithmName("MD5");
credentialsMatche.setHashIterations(1);
super.setCredentialsMatcher(credentialsMatche);
}
}
mybatis Xml配置方式
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- 下划线字段名转换骆驼属性名 -->
<setting name="mapUnderscoreToCamelCase" value="true" />
<!-- 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAROTHER。 -->
<setting name="jdbcTypeForNull" value="NULL" />
<!--<setting name="logImpl" value="STDOUT_LOGGING" />-->
<setting name="lazyLoadingEnabled" value="false"/>
<setting name="aggressiveLazyLoading" value="true"/>
</settings>
<!-- 自定义类型配置 -->
<typeHandlers>
<typeHandler javaType="com.hpay.commons.config.datasource.CryptoString" handler="com.hpay.common.orm.mybatis.type.CryptoTypeHandler" />
<!-- 使用方法 -->
<!-- 插入sql: #{bankCardNo,jdbcType=VARCHAR,javaType=com.hpay.admin.dal.customType.CryptoString}
在插入元素里,跟上javaType自定义类型的CryptoString和jdbcType即可
查询sql: 对需要使用自定义类型的字段使用resultMap
<resultMap id="BaseResultMap" type="com.hanyin.Object">
<result column="user_id" property="userId" javaType="com.hpay.admin.dal.customType.CryptoString" jdbcType="VARCHAR"/>
</resultMap> -->
</typeHandlers>
<!-- plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下: properties?, settings?, typeAliases?, typeHandlers?, objectFactory?,objectWrapperFactory?, plugins?, environments?, databaseIdProvider?, mappers? -->
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 4.0.0以后版本可以不设置该参数 -->
<!--<property name="dialect" value="oracle" />-->
<!-- 该参数默认为false -->
<!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->
<!-- 和startPage中的pageNum效果一样 -->
<property name="offsetAsPageNum" value="true" />
<!-- 该参数默认为false -->
<!-- 设置为true时,使用RowBounds分页会进行count查询 -->
<property name="rowBoundsWithCount" value="true" />
<!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
<!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型) -->
<property name="pageSizeZero" value="true" />
<!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->
<!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
<!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
<property name="reasonable" value="false" />
<!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->
<!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->
<!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,orderBy,不配置映射的用默认值 -->
<!-- 不理解该含义的前提下,不要随便复制该配置 -->
<property name="params" value="pageNum=pageHelperStart;pageSize=pageHelperRows;" />
<!-- 支持通过Mapper接口参数来传递分页参数 -->
<property name="supportMethodsArguments" value="false" />
<!-- always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page -->
<property name="returnPageInfo" value="none" />
</plugin>
</plugins>
</configuration>