Java开发问题和使用笔记

来源:互联网 发布:floyd算法 matlab 编辑:程序博客网 时间:2024/05/21 06:31

1.HashMap的存储不是按照插入顺序排列的

今天碰到了调用接口必须按照插入的顺序,原来用HashMap结果因为顺序不对,将HashMap改为LinkedHashMap就可以了

2.Date类型插到map中,转换为json字符时,会将日期转换成为一个Map值为{"date":7,"day":3,"hours":16,"minutes":14,"month":11,"nanos":0,"seconds":9,"time":1481098449000,"timezoneOffset":-480,"year":116}所以在取日期的时候需要注意,我现在的做法是取出map中的time字符串,new Date(时间戳)转换为日期


3.Mac下执行mvn clean package docker:build报错

Failed to execute goal com.spotify:docker-maven-plugin:0.2.9:build (default-cli) on project sample-config: Exception caught: java.util.concurrent.ExecutionException: com.spotify.docker.client.shaded.javax.ws.rs.ProcessingException: org.apache.http.conn.HttpHostConnectException: Connect to localhost:2375 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused -> [Help 1]

解决方法:

1).将Spotify plugin升级到0.4.13

<plugin>    <groupId>com.spotify</groupId>    <artifactId>docker-maven-plugin</artifactId>    <version>0.4.13</version>    <configuration>        <skipDockerBuild>true</skipDockerBuild>    </configuration></plugin>

2).在执行mvn命令前先执行命令export DOCKER_HOST=unix:///var/run/docker.sock


4.Quarz多个定时调度实现,只要传入不同的schedulerName就可以创建多个定时任务工厂,每个调度各自启动自己的定时任务sf.getScheduler().start(),互不影响

import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.SchedulerFactory;import org.quartz.impl.StdSchedulerFactory;import java.util.Properties;/** * @描述:    创建多个定时任务调度 */public class MySchedulerUtil {    private static Logger logger = LogManager.getLogger(MySchedulerUtil.class);    public static SchedulerFactory getSchedulerFactory(String schedulerName){        SchedulerFactory sf=null;        Properties props = new Properties();        props.put("org.quartz.scheduler.instanceName", schedulerName);        props.put("org.quartz.threadPool.threadCount", "10");        props.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");        try {            sf = new StdSchedulerFactory(props);        } catch (SchedulerException e) {            logger.info(e);        }        return sf;    }    public static SchedulerFactory getSchedulerFactory(){        return new StdSchedulerFactory();    }    public static Scheduler getDefaultScheduler(){        Scheduler s=null;        try {            s=StdSchedulerFactory.getDefaultScheduler();        } catch (SchedulerException e) {            e.printStackTrace();        }        return s;    }}

5.Spring Boot中aop注解无效

各种尝试感觉aop都无效,最后通过修改了切面处理类的类名问题得以解决,最后得出结论可能是函数名和类名相同让切面类注解@Aspect失效了,我原来类名叫做MergeUser,类中有一个函数mergeUser(),后来将类名修改为MergeUserAspect才让AOP切面生效。

我现在的应用场景是,sql查询经常要用到用户的用户ID,用户身份授权框架使用的是Spring Security

可以直接采用(Map<String,Object> map,@AuthenticationPrincipal MyUser user)这种方法,但是我还是要把user中的USER_ID封装到map中去,大多数函数都需要干这件事,太麻烦了,所以打算使用

自定义注解

@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface MergeUser {}
aspect类

import org.MyUser;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.springframework.security.core.context.SecurityContextImpl;import org.springframework.stereotype.Component;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import java.util.Map;@Component@Aspectpublic class MergeUserAspect {    @Pointcut("@annotation(org.MergeUser)")    public void mergeUser(){}    @Before(value="mergeUser() && args(map)")    public void invokeBefore(Map<String, Object> map){        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();        HttpServletRequest request = attributes.getRequest();        HttpSession session = request.getSession();        SecurityContextImpl securityContext=(SecurityContextImpl)session.getAttribute("SPRING_SECURITY_CONTEXT");        if (securityContext!= null) {            MyUser user=(MyUser) securityContext.getAuthentication().getPrincipal();            map.put("USER_ID",user.getUserId());        }    }}
在Service中使用,也可以在Controller中使用

@MergeUser

public void doSometing(Map<String,Object> map){

//map中已经有了USER_ID用户ID了

}
其中通过HttpServlet获取用户的登录信息也可以使用下面的方法

UsernamePasswordAuthenticationToken userPrincipal=(UsernamePasswordAuthenticationToken)request.getUserPrincipal();

或者Authentication userPrincipal=(Authentication)request.getUserPrincipal();
MyUser user=(MyUser)userPrincipal.getPrincipal();


6.Maven打包时会对resource文件夹中的文件编码,会损坏掉一些文件,我用过的有Excel模板文件,font-awesome字体文件,需要在pom中添加过滤

<resources>    <resource>        <directory>src/main/java</directory>        <includes>            <include>**/*.properties</include>            <include>**/*.xml</include>        </includes>        <filtering>true</filtering>    </resource>    <resource>        <directory>src/main/resources</directory>        <filtering>true</filtering>        <excludes>            <exclude>**/*.xls</exclude>        </excludes>    </resource>    <resource>        <directory>src/main/resources</directory>        <filtering>false</filtering>        <includes>            <include>**/*.xls</include>        </includes>    </resource></resources>

7.bean转map方法,下面的方法要求bean中list是同一种类型,否则会出现部分属性丢失,bean中有map也没有考虑到,暂时用不到就不完善了

import java.beans.BeanInfo;import java.beans.Introspector;import java.beans.PropertyDescriptor;import java.lang.reflect.Method;import java.util.*;

public static Map<String, Object> transBean2Map(Object obj) {    if (obj == null) {        return null;    }    Map<String, Object> map = new HashMap<String, Object>();    try {        BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();        for (PropertyDescriptor property : propertyDescriptors) {            String key = property.getName();            // 过滤class属性            if (!key.equals("class")) {                // 得到property对应的getter方法                Method getter = property.getReadMethod();                Object value = getter.invoke(obj);                if(value instanceof List){                    List<Map<String, Object>> subList = new ArrayList<>();                    for(Object obj1:(List)value)                    {                        if(obj1 instanceof Map) {                            subList.add((Map)obj1);                        }else if(isJavaBean(obj1)){                            subList.add(transBean2Map(obj1));                        }                    }                    map.put(key, subList.isEmpty()?value:subList);                }else {                    map.put(key, value);                }            }        }    } catch (Exception e) {        System.out.println("transBean2Map Error " + e);    }    return map;}//简单的认为只要对象中不只包含get和set方法就是一个beanpublic static Boolean isJavaBean(Object o){    boolean flag = false;    Method[] methods = o.getClass().getDeclaredMethods();    for (Method m : methods)    {        String name = m.getName();        //判断javabean中是否只有set/get方法        if (!name.startsWith("set") && !name.startsWith("get")) {            flag = true;            break;        }    }    return flag;}

8.null+""="null",我们经常在字符串比较的时候"name".equals(null+"")采用这种写法,结果是正确的,但是判断空字符串如果使用StringUtils.isBlank(null+"")结果永远是true,这种写法是错误的,建议用Spring自带的StringUtils.isEmpty(字符串)

9.Integer不能转换为String,如年龄转换为字符串,(String)map.get("age")会报转换错误,但是如果为null1)采用map.get("age").toString()也会报没有该方法的错误2)map.get("age")+""="null",所以在转换的时候需要注意











0 0
原创粉丝点击