工作小结(持续更新中)

文件操作

页面上传文件到Controller

在后台系统中,上传文件功能非常常见,这是每个后台系统都应该实现的功能。在我们的魔方后台系统中。其中有个功能是需要导入卡号密码。实现方式如下:

上传文件
<input type="file" @change="importExcel" id="toImportExcel" style="display: none;"/>
调用方法,通过form表单的形式上传文件
importExcel: function (e) {
			var file = e.target.files[0];
			confirm('请确认导入模板类型?', function() {
				var formData = new FormData();
				$("#toImportExcel").val("");
				formData.append('file', file);
				formData.append('type', vm.type);
				formData.append('productId', vm.product.productId);
				$.ajax({
					type: "POST",
					async: false,
					url: baseURL + "magic/product/import/excel",
					data: formData,
					cache: false,
					contentType: false,    //不可缺
					processData: false,    //不可缺
					dataType: "json",
					success: function (r) {
						alert(r.msg);
					},
					error: function (XMLHttpRequest, textStatus, errorThrown) {
						alert("上传失败,请检查网络后重试");
					}
				});
			})
		},
通过MutipartFil接收传递过来的文件信息
@RequestMapping("import/excel")
	public R importExcel(@RequestParam(value = "file",required = false)MultipartFile file,
						 @RequestParam(value = "type",required = false)Integer type,
						 @RequestParam(value = "productId",required = false)Long productId,
						 HttpServletRequest request){
		... ...
	}

在操作文件时包含了文件下载到本地、上传ftp、删除本地文件的过程。那么我们在下面具体分析下这几步

文件下载到本地

try {
			//获取文件名称
			String fileName = file.getOriginalFilename();
			//校验文件名是csv格式
			if (!fileName.matches("^.+\\.(?i)(csv)$")) {
				String msg = "上传文件格式不正确,请输入csv格式!";
				logger.error(msg);
				return R.error(msg);
			}
			//获取扩展名
			String ext = fileName.substring(fileName.lastIndexOf(".")+1);
			//生成名称
			String newFileName = UtilTools.getname();//自己写的一个获取字符串的方法作为图片名称
			//生成放在服务器的路径
			newFileName = newFileName + "." + ext;
			//获取文件的上下文路径
			String filePath = request.getServletContext().getRealPath("/WEB-INF/classes/upload/");
			//创建一个文件
			File newFile = new File(filePath + "/" + newFileName);
			//将从前端上传的文件转移到这个新文件里
			file.transferTo(newFile);
			
			String paths = "/mofang/excel/" + DateUtil.getCurrentTime() + "/";
			//文件上传到sftp
			uploadSftp(newFileName,filePath,paths);
			//调用activeMq
			String msg = magicProductService.importSub(paths,"subpro_" + newFileName, type, productId);
			//判断文件是否存在
			if (newFile.exists()){
				// 删除文件
				if (newFile.delete()){
					logger.info("删除本地文件:{}",newFile);
				}
			}
			return R.ok(msg);
		} catch (Exception e) {
			logger.error("",e);
			return R.error();
		}
#UtilTools 这个写的真的辣鸡
public class UtilTools {
	public static String getname(){
		//年月日
		//时分秒
		Calendar now = Calendar.getInstance();
		String str = "";
		str += now.get(Calendar.YEAR);
		if ((now.get(Calendar.MONTH) + 1)>=10){
			str += (now.get(Calendar.MONTH) + 1);
		}else {
			str += "0" + (now.get(Calendar.MONTH) + 1);
		}
		if (now.get(Calendar.DAY_OF_MONTH)>=10){
			str += now.get(Calendar.DAY_OF_MONTH);
		}else {
			str += "0" + now.get(Calendar.DAY_OF_MONTH);
		}
		if (now.get(Calendar.HOUR_OF_DAY)>=10){
			str += now.get(Calendar.HOUR_OF_DAY);
		}else {
			str += "0" + now.get(Calendar.HOUR_OF_DAY);
		}
		if (now.get(Calendar.MINUTE)>=10){
			str += now.get(Calendar.MINUTE);
		}else {
			str += "0" + now.get(Calendar.MINUTE);
		}
		if (now.get(Calendar.SECOND)>=10){
			str += now.get(Calendar.SECOND);
		}else {
			str += "0" + now.get(Calendar.SECOND);
		}
		return str;
	}
}

文件于sftp操作

sftp依赖
<dependency>
	<groupId>com.jcraft</groupId>
	<artifactId>jsch</artifactId>
	<version>0.1.54</version>
</dependency>
#SftpUtil.java

public class SftpUtil {
    private static final String CLZ_NAME = SftpUtil.class.getSimpleName() + ".";
    
    static Logger logger= LoggerFactory.getLogger(SftpUtil.class);
    
    private ChannelSftp sftp;
 
    private Session session;
    /**
     * SFTP 登录用户名
     */
    private String username;
    /**
     * SFTP 登录密码
     */
    private String password;
    /**
     * 私钥
     */
    private String privateKey;
    /**
     * SFTP 服务器地址IP地址
     */
    private String host;
    /**
     * SFTP 端口
     */
    private int port;
 
 
    /**
     * 构造基于密码认证的sftp对象
     */
    public SftpUtil(String username, String password, String host, int port) {
        this.username = username;
        this.password = password;
        this.host = host;
        this.port = port;
    }
 
    /**
     * 构造基于秘钥认证的sftp对象
     */
    public SftpUtil(String username, String host, int port, String privateKey) {
        this.username = username;
        this.host = host;
        this.port = port;
        this.privateKey = privateKey;
    }
 
    public SftpUtil() {
    }
 
 
    /**
     * 连接sftp服务器
     */
    public void login() throws Exception {
        JSch jsch = new JSch();
        if (privateKey != null) {
            jsch.addIdentity(privateKey);// 设置私钥
        }
 
        session = jsch.getSession(username, host, port);
 
        if (password != null) {
            session.setPassword(password);
        }
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        //TODO 移除kerberos验证方法
        config.put("PreferredAuthentications", "publickey,keyboard-interactive,password");
 
        session.setConfig(config);
        session.connect();
 
        Channel channel = session.openChannel("sftp");
        channel.connect();
 
        sftp = (ChannelSftp) channel;
 
    }
 
    /**
     * 关闭连接 server
     */
    public void logout() {
        if (sftp != null) {
            if (sftp.isConnected()) {
                sftp.disconnect();
            }
        }
        if (session != null) {
            if (session.isConnected()) {
                session.disconnect();
            }
        }
    }
 
 
    /**
     * 将输入流的数据上传到sftp作为文件。文件完整路径=basePath+directory
     *
     * @param path     上传到该目录
     * @param fileName sftp端文件名
     * @param input    输入流
     */
    public void upload(String path, String fileName, InputStream input) throws SftpException {
        try {
            sftp.cd(path);
        } catch (SftpException e) {
            //目录不存在,则创建文件夹
            String[] dirs = path.split("/");
            for (String dir : dirs) {
                if (null == dir || "".equals(dir)) continue;
                try {
                    sftp.cd(dir);
                } catch (SftpException ex) {
                    sftp.mkdir(dir);
                    sftp.cd(dir);
                }
            }
        }
        sftp.put(input, fileName);  //上传文件
    }
 
 
    /**
     * 下载文件。
     *
     * @param directory    下载目录
     * @param downloadFile 下载的文件
     * @param saveFile     存在本地的路径
     */
    public void download(String directory, String downloadFile, String saveFile) throws SftpException, FileNotFoundException {
        if (directory != null && !"".equals(directory)) {
            sftp.cd(directory);
        }
        File file = new File(saveFile);
        sftp.get(downloadFile, new FileOutputStream(file));
    }
 
 
    /**
     * 删除文件
     *
     * @param directory  要删除文件所在目录
     * @param deleteFile 要删除的文件
     */
    public void delete(String directory, String deleteFile) throws SftpException {
        sftp.cd(directory);
        sftp.rm(deleteFile);
    }
 
 
    /**
     * 列出目录下的文件
     *
     * @param directory 要列出的目录
     * @param
     */
    public Vector<?> listFiles(String directory) throws SftpException {
        return sftp.ls(directory);
    }
 
  
}

上传文件到sftp
public void uploadSftp(String newFileName,String filePath,String paths){
		// 创建sftp连接
		SftpUtil sftp = new SftpUtil(sUsername, sPassword, sHost, Integer.parseInt(sPort));
		// 输入流
		InputStream is = null;
		try {
			// 获取文件输入流
			is = new FileInputStream(filePath + newFileName);
			// sftp登录
			sftp.login();
			// sftp下载文件
			sftp.upload(paths, "subpro_" + newFileName, is);
		} catch (Exception e) {
			logger.error("",e);
		} finally {
			if (is != null){
				try {
					is.close();
					sftp.logout();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
sftp下载文件到本地
public void sftpTestDownload() {
		logger.info("begin");
		// 测试上传
		try {
			// 创建sftp连接			
			SftpUtil sftp = new SftpUtil(sUsername, sPassword, sHost, Integer.parseInt(sPort));
			// 登录
			sftp.login();
			String pathName="/mofang/excel/20190701/";
			String fileName="subpro_1561967527887.csv";
			// 下载
			sftp.download(pathName, fileName, "D:\\test\\"+fileName);
			// 登出
			sftp.logout();
			logger.info("ends");
		} catch (Exception e) {
			logger.error("", e);
		}
	}

获取上下文路径

通过request获取

HttpServletRequest request
request.getServletContext().getRealPath("/WEB-INF/classes/upload/");

springboot获取上下文路径

ResourceUtils.getURL("classpath:").getPath()
spring-core ResourceUtils 常用url
public static final String CLASSPATH_URL_PREFIX = "classpath:";
public static final String FILE_URL_PREFIX = "file:";
public static final String JAR_URL_PREFIX = "jar:";
public static final String WAR_URL_PREFIX = "war:";
public static final String URL_PROTOCOL_FILE = "file";
public static final String URL_PROTOCOL_JAR = "jar";
public static final String URL_PROTOCOL_WAR = "war";
public static final String URL_PROTOCOL_ZIP = "zip";
public static final String URL_PROTOCOL_WSJAR = "wsjar";
public static final String URL_PROTOCOL_VFSZIP = "vfszip";
public static final String URL_PROTOCOL_VFSFILE = "vfsfile";
public static final String URL_PROTOCOL_VFS = "vfs";
public static final String JAR_FILE_EXTENSION = ".jar";
public static final String JAR_URL_SEPARATOR = "!/";
public static final String WAR_URL_SEPARATOR = "*/";

Shiro出现的问题

用户用chrom登录shiro抛出异常

这个其实就是记住我的功能,因为第一次登录没有任何信息,所以就会抛出异常。将这个功能置为null就可以

2019-07-11 20:29:22.288  WARN 314244 --- [nio-8088-exec-6] o.a.shiro.mgt.AbstractRememberMeManager  : There was a failure while trying to retrieve remembered principals.  This could be due to a configuration problem or corrupted principals.  This could also be due to a recently changed encryption key, if you are using a shiro.ini file, this property would be 'securityManager.rememberMeManager.cipherKey' see: http://shiro.apache.org/web.html#Web-RememberMeServices. The remembered identity will be forgotten and not used for this request.
2019-07-11 20:29:22.290  WARN 314244 --- [nio-8088-exec-6] o.a.shiro.mgt.DefaultSecurityManager     : Delegate RememberMeManager instance of type [org.apache.shiro.web.mgt.CookieRememberMeManager] threw an exception during getRememberedPrincipals().

org.apache.shiro.crypto.CryptoException: Unable to execute 'doFinal' with cipher instance [javax.crypto.Cipher@3b8690dc].
	at org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:462)
	at org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:445)
	at org.apache.shiro.crypto.JcaCipherService.decrypt(JcaCipherService.java:390)
	at org.apache.shiro.crypto.JcaCipherService.decrypt(JcaCipherService.java:382)
	at org.apache.shiro.mgt.AbstractRememberMeManager.decrypt(AbstractRememberMeManager.java:482)
	at org.apache.shiro.mgt.AbstractRememberMeManager.convertBytesToPrincipals(AbstractRememberMeManager.java:419)
	at org.apache.shiro.mgt.AbstractRememberMeManager.getRememberedPrincipals(AbstractRememberMeManager.java:386)
	at org.apache.shiro.mgt.DefaultSecurityManager.getRememberedIdentity(DefaultSecurityManager.java:612)
	at org.apache.shiro.mgt.DefaultSecurityManager.resolvePrincipals(DefaultSecurityManager.java:500)
	at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:346)
	at org.apache.shiro.subject.Subject$Builder.buildSubject(Subject.java:845)
	at org.apache.shiro.web.subject.WebSubject$Builder.buildWebSubject(WebSubject.java:148)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.createSubject(AbstractShiroFilter.java:292)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:359)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
	at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
	at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
	at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:130)
	at org.springframework.boot.web.servlet.support.ErrorPageFilter.access$000(ErrorPageFilter.java:66)
	at org.springframework.boot.web.servlet.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:105)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:123)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1502)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1458)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
	at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:991)
	at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:847)
	at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
	at javax.crypto.Cipher.doFinal(Cipher.java:2164)
	at org.apache.shiro.crypto.JcaCipherService.crypt(JcaCipherService.java:459)
	... 57 common frames omitted
  • 解决方法
    将rememberMeManager置为null,就不报异常信息了。
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRememberMeManager(null);

maven的profile切换环境的参数

下图是项目的文件结构
在这里插入图片描述

<profiles>
		<profile>
			<id>dev</id>
			<properties>
				<profileActive>dev</profileActive>
			</properties>
			<activation>
				<activeByDefault>true</activeByDefault>
			</activation>
		</profile>
		<profile>
			<id>uat</id>
			<properties>
				<profileActive>uat</profileActive>
			</properties>
		</profile>
		<profile>
			<id>prod</id>
			<properties>
				<profileActive>prod</profileActive>
			</properties>
		</profile>
		<profile>
			<id>test</id>
			<properties>
				<profileActive>test</profileActive>
			</properties>
		</profile>
	</profiles>

activeByDefault标签的值为true,表示默认的profile,使用mvn install就会打成dev的包

resources标签定义要包含的资源,在下面的配置下package阶段会把resouces文件里的 $application-${profileActive}.properties 文件打包
这里的${profileActive}由命令maven的-P选项指定,例:mvn install -Ptest 就是打包
即application-${profileActive}.properties、application.properties、**/*.xml文件

	<build>
        <resources>
			<resource>
				<directory>src/main/webapp</directory>
			</resource>
			<resource>
				<directory>src/main/resources</directory>
				<includes>
					<include>application-${profileActive}.properties</include>
					<include>application.properties</include>
					<include>**/*.xml</include>
				</includes>
				<filtering>true</filtering>
			</resource>
			<resource>
				<directory>src/main/java</directory>
				<includes>
					<include>**/*.xml</include>
				</includes>
			</resource>
		</resources>
	</build>
#application.properties
server.port=10027

#profileActive就是上面resource中的profileActive
spring.profiles.active=@profileActive@

JSONArray数据转换成Java List

后台接收json数组转成封装实体类的List

import java.util.List;

import net.sf.json.JSONArray;
import net.sf.json.JsonConfig;

public class JsonTest {

    /**
     * @param args
     */
    public static void main(String[] args) {

        // 转换方法1
        JSONArray array = JSONArray.fromObject("[{'name':'hehe','age':22}]");
        List<Person> list = JSONArray.toList(array, Person.class);// 过时方法
        System.out.println(list.get(0).getName());

        // 转换方法2
        List<?> list2 = JSONArray.toList(array, new Person(), new JsonConfig());//参数1为要转换的JSONArray数据,参数2为要转换的目标数据,即List盛装的数据
        Person person = (Person) list2.get(0);
        System.out.println(person.getAge());
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值