`

WebUtil --- LogUtil--ByteUtil

 
阅读更多
package com.etnetchina.servlet.util;

import com.etnetchina.id.IdGenerate;
import com.etnetchina.log.LogUtil;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.LogFactory;

/**
 * WEB相关的工具方法。
 */
public class WebUtil {

    private static final LogUtil logger = new LogUtil(LogFactory.getLog(
            WebUtil.class));

    private WebUtil() {
    }

    /**
     * 取实际用户的访问地址。
     * @param request 当前请求。
     * @return 客户端IP地址。
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ips = request.getHeader("x-forwarded-for");
        if (ips == null || ips.length() == 0 || "unknown".equalsIgnoreCase(ips)) {
            ips = request.getHeader("Proxy-Client-IP");
        }
        if (ips == null || ips.length() == 0 || "unknown".equalsIgnoreCase(ips)) {
            ips = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ips == null || ips.length() == 0 || "unknown".equalsIgnoreCase(ips)) {
            ips = request.getRemoteAddr();
        }

        String[] ipArray = ips.split(",");
        String clientIP = null;
        for (String ip : ipArray) {
            if (!("unknown".equalsIgnoreCase(ip))) {
                clientIP = ip;
                break;
            }
        }
        return clientIP;
    }

    /**
     * 查找指定请求中的指定名称的Cookie。
     * @param request 请求。
     * @param name cookie名称。
     * @return 如果有相应名称的Cookie,则返回相应Cookie实例。没有返回null。
     */
    public static Cookie findCookie(HttpServletRequest request, String name) {
        if (request != null) {
            Cookie[] cookies = request.getCookies();
            if (cookies != null && cookies.length > 0) {
                for (Cookie cookie : cookies) {
                    if (cookie.getName().equals(name)) {
                        return cookie;
                    }
                }
            }
        }

        return null;
    }

    /**
     * 查找指定请求中的指定名称Cookie的值,如果不存在将返回null。
     * @param request 请求。
     * @param name Cookie名称。
     * @return cookie的值。
     */
    public static String findCookieValue(HttpServletRequest request, String name) {
        Cookie cookie = findCookie(request, name);
        return cookie != null ? cookie.getValue() : null;
    }

    /**
     * 增加一个Cookie,使用默认域名。
     * @param request 请求。
     * @param response 响应。
     * @param name Cookie名称 。
     * @param value Cookie的值。
     * @param maxAge 生命周期。
     */
    public static void addCookie(
            HttpServletRequest request,
            HttpServletResponse response,
            String name,
            String value,
            int maxAge) {
        addCookie(request, response, name, value, null, maxAge);
    }

    /**
     * 增加一个Cookie,使用指定域名。
     * @param request 请求。
     * @param response 响应。
     * @param name Cookie名称 。
     * @param value Cookie的值。
     * @param maxAge 生命周期。
     */
    public static void addCookie(
            HttpServletRequest request,
            HttpServletResponse response,
            String name,
            String value,
            String domain,
            int maxAge) {
        String contextPath = request.getContextPath();
        if (contextPath == null || contextPath.isEmpty()) {
            contextPath = "/";
        }
        addCookie(request, response, name, value, domain, contextPath, maxAge);
    }

    /**
     * 增加一个Cookie.ContextPath如果为空或者长度为0,将使用"/".
     * @param request 当前请求。
     * @param response 当前响应。
     * @param name cookie名称
     * @param value cookie值
     * @param domain cookie域名
     * @param contextPath cookie路径。
     * @param maxAge 有效时间。
     */
    public static void addCookie(
            HttpServletRequest request,
            HttpServletResponse response,
            String name,
            String value,
            String domain,
            String contextPath,
            int maxAge) {
        if (request != null && response != null) {
            Cookie cookie = new Cookie(name, value);
            cookie.setMaxAge(maxAge);
            cookie.setSecure(request.isSecure());

            if (contextPath == null || contextPath.isEmpty()) {
                cookie.setPath("/");
            } else {
                cookie.setPath(contextPath);
            }

            if (domain != null && !domain.isEmpty()) {
                cookie.setDomain(domain);
            }

            response.addCookie(cookie);

            logger.debugLog(
                    "Cookie update the sessionID.[name={0},value={1},maxAge={2},secure={3},path={4},domain={5}]",
                    cookie.getName(),
                    cookie.getValue(),
                    String.valueOf(cookie.getMaxAge()),
                    String.valueOf(cookie.getSecure()),
                    cookie.getPath(),
                    cookie.getDomain());
        }
    }

    /**
     * 失效一个Cookie.
     * @param request 当前请求。
     * @param response 当前响应。
     * @param name Cookie名称。
     * @param domain Cookie域名。
     * @param contextPath 有效路径。
     */
    public static void failureCookie(
            HttpServletRequest request,
            HttpServletResponse response,
            String name,
            String domain,
            String contextPath) {
        if (request != null && response != null) {
            addCookie(request, response, name, null, domain, contextPath, 0);
        }
    }

    /**
     * 将指定的Cookie失效掉。
     * @param request 请求
     * @param response 响应。
     * @param name cookie名称。
     * @param domain cookie的域名。
     */
    public static void failureCookie(HttpServletRequest request,
            HttpServletResponse response, String name, String domain) {
        String contextPath = request.getContextPath();
        if (contextPath == null || contextPath.isEmpty()) {
            contextPath = "/";
        }
        failureCookie(request, response, name, domain, contextPath);
    }

    /**
     * 将指定的Cookie失效掉。
     * @param request 请求
     * @param response 响应。
     * @param name cookie名称。
     */
    public static void failureCookie(HttpServletRequest request,
            HttpServletResponse response, String name) {
        failureCookie(request, response, name, null);
    }

    /**
     * 获取请求的完整地址。
     * @param request 请求。
     * @return 完整地址。
     */
    public static String completeTheRequestAddress(HttpServletRequest request) {
        StringBuilder buff = new StringBuilder(
                request.getRequestURL().toString());
        String queryString = request.getQueryString();
        if (queryString != null) {
            buff.append("?").append(queryString);
        }

        return buff.toString();
    }

    /**
     * 将换行符替换成html页面使用的换行元素。
     * @param source 原始字符串。
     * @return 替换后的字符串。
     */
    public static String enterToHtmlWrap(String source) {
        if (source == null || source.trim().isEmpty()) {
            return source;
        } else {
            return source.replaceAll("\r\n", "<br />");
        }
    }

    /**
     * 一个客户端转向的方便工具方法.可以选择使用301或者302方式进行跳转.
     * @param response 当前响应.
     * @param url 需要转向的地址.
     * @param movePermanently true表示进行301永久跳转,false表示302临时跳转.
     * @throws IOException I/O异常.
     */
    public static void redirect(
            HttpServletResponse response,
            String url,
            boolean movePermanently) throws IOException {
        if (!movePermanently) {
            response.sendRedirect(url);
        } else {
            response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
            response.setHeader("Location", url);
        }
    }
    /**
     * 代理的名称,也代理了判断的顺序..
     */
    private static final String[] AGENT_INDEX = {
        "MSIE", "Firefox", "Chrome", "Opera", "Safari"
    };
    /**
     * 存放用户代理解析的正则容器.
     */
    private static final Map<String, Pattern> AGENT_PATTERNS =
            new HashMap<String, Pattern>(AGENT_INDEX.length);

    static {
        AGENT_PATTERNS.put(AGENT_INDEX[0], Pattern.compile("MSIE ([\\d.]+)"));
        AGENT_PATTERNS.put(AGENT_INDEX[1], Pattern.compile("Firefox/(\\d.+)"));
        AGENT_PATTERNS.put(AGENT_INDEX[2], Pattern.compile("Chrome/([\\d.]+)"));
        AGENT_PATTERNS.put(AGENT_INDEX[3], Pattern.compile("Opera[/\\s]([\\d.]+)"));
        AGENT_PATTERNS.put(AGENT_INDEX[4], Pattern.compile("Version/([\\d.]+)"));
    }

    /**
     * 获取用户代理信息.
     * @param userAgent 用户代理信息字符串.
     * @return 用户代理信息.
     */
    public static UserAgent checkUserAgent(String userAgent) {
        if (userAgent == null || userAgent.isEmpty()) {
            return null;
        }

        Pattern pattern = null;
        Matcher matcher = null;
        for (int point = 0; point < AGENT_INDEX.length; point++) {
            pattern = AGENT_PATTERNS.get(AGENT_INDEX[point]);
            matcher = pattern.matcher(userAgent);
            if (matcher.find()) {
                return new UserAgent(AGENT_INDEX[point], matcher.group(1));
            } else {
                continue;
            }
        }
        return null;
    }

    /**
     * 获取指定请求中的用户代理.
     * @param request 请求.
     * @return 用户代理信息.
     */
    public static UserAgent checkUserAgent(HttpServletRequest request) {
        if (request == null) {
            return null;
        }
        String userAgentHead = request.getHeader("User-Agent");
        return checkUserAgent(userAgentHead);
    }

    /**
     * 表示一个用户代理的信息.
     */
    public static class UserAgent {

        private String name = "";
        private String version = "";

        /**
         * 构造一个用户代理信息.
         * @param name 代理名称.
         * @param version 代理版本号.
         */
        public UserAgent(String name, String version) {
            this.name = name;
            this.version = version;
        }

        /**
         * 获取代理名称.
         * @return 代理名称.
         */
        public String getName() {
            return name;
        }

        /**
         * 获取版本号.
         * @return 版本号.
         */
        public String getVersion() {
            return version;
        }
    }
    /**
     * 票据名称
     */
    public static final String TICKET_NAME = "ticket";

    /**
     * 创建票据.
     * @param request 当前请求
     */
    public static String createTicket(HttpServletRequest request) {
        HttpSession session = request.getSession();
        String ticket = IdGenerate.getUUIDString();
        session.setAttribute(TICKET_NAME, ticket);

        return ticket;
    }

    /**
     * 验证票据.
     * 请求中必须带有票据数据.
     * @param request 当前请求.
     * @return true验证通过,false验证不通过.
     */
    public static boolean testTicket(HttpServletRequest request) {

        HttpSession session = request.getSession();
        String serverTicket = (String) session.getAttribute(TICKET_NAME);
        String clientTicket = request.getParameter(TICKET_NAME);

        try {
            if (serverTicket == null) {
                return true;
            } else {
                if (serverTicket.equals(clientTicket)) {
                    return true;
                } else {
                    return false;
                }
            }
        } finally {
            session.removeAttribute(TICKET_NAME);
        }
    }
}

 

 

package com.etnetchina.log;

import com.etnetchina.util.CheckUtil;
import org.apache.commons.logging.Log;

/**
 * 一个日志记录的帮助对象。
 * 记录消息时消息中可以使用{0}之类的来表示一个占位符,此占位符会在写入日志后被指定的数据替换。
 *
 * 例如:写入一下DEBUG消息。LogUtil.debugLog("当前时间是{0}.","12:00");
 * 那么最终写入日志的将是这样一条语句,"当前时间是12:00."。
 * 其中占位符中的数字代表是需要使用第几个参数来替换。
 * 参考"com.etnetchina.util.CheckUtil"中的"replaceArgs"方法。
 *
 * @see com.etnetchina.util.CheckUtil
 */
public class LogUtil {

    private Log logger;//日志记录器。
    private static Object[] empty = null;

    /**
     * 构造一个新的日志帮助实例。
     * @param logger 使用的日志记录器。
     */
    public LogUtil(final Log logger) {
        this.logger = logger;
    }

    /**
     * 记录一个无参数的消息。
     * @param message 消息。
     */
    public void infoLog(String message) {
        infoLog(message, empty);
    }

    /**
     * 记录一个消息,消息中的参数将替换成params指定的值。
     * @param message 消息。
     * @param params 消息中的替换值。
     */
    public void infoLog(String message, Object... params) {
        if (message == null || message.isEmpty()) {
            throw new IllegalArgumentException(
                    "Can not record the message blank.");
        }

        if (logger != null) {
            if (logger.isInfoEnabled()) {
                logger.info(
                        CheckUtil.replaceArgs(message, params));
            }
        }

    }

    /**
     * 记录一个DEBUG消息。
     * @param message 消息。
     */
    public void debugLog(String message) {
        debugLog(message, empty);
    }

    /**
     * 记录一个DEBUG消息,消息中的参数将替换成params指定的值。
     * @param message DEBUG消息。
     * @param params 消息中的替换值。
     */
    public void debugLog(String message, Object... params) {
        if (message == null || message.isEmpty()) {
            throw new IllegalArgumentException(
                    "Can not record the message blank.");
        }
        if (logger != null) {
            if (logger.isDebugEnabled()) {
                logger.debug(
                        CheckUtil.replaceArgs(message, params));
            }
        }
    }

    /**
     * 记录一个警告消息。
     * @param message 警告消息。
     */
    public void warnLog(String message) {
        warnLog(message, empty);
    }

    /**
     * 记录一个警告消息,消息中的参数将替换成params指定的值。
     * @param message 警告消息。
     * @param params 消息中的替换值。
     */
    public void warnLog(String message, Object... params) {
        if (message == null || message.isEmpty()) {
            throw new IllegalArgumentException(
                    "Can not record the message blank.");
        }
        if (logger != null) {
            if (logger.isWarnEnabled()) {
                logger.warn(
                        CheckUtil.replaceArgs(message, params));
            }
        }
    }

    /**
     * 记录一个错误消息。
     * @param ex 错误消息。
     */
    public void errorLog(Exception ex) {
        errorLog(ex, ex.getMessage() == null ? "" : ex.getMessage(), empty);
    }

    /**
     * 往日志中输出一个错误。错误和错误消息必须设置。
     * @param ex 错误实例。
     * @param message 错误消息。
     * @param params 消息中的替换值。
     */
    public void errorLog(Exception ex, String message, Object... params) {
        if (ex == null) {
            throw new IllegalArgumentException(
                    "Can not record the error message empty.");
        }

        if (message == null) {
            throw new IllegalArgumentException(
                    "Can not record the message blank.");
        }

        if (logger != null) {
            if (logger.isErrorEnabled()) {
                String nowMessage = CheckUtil.replaceArgs(message, params);
                logger.error(nowMessage, ex);
            }
        }
    }

    /**
     * 是否打开了警告日志缓别.
     * @return true打开,false没有打开.
     */
    public boolean isWarnEnabled() {
        return logger.isWarnEnabled();
    }

    /**
     * 是否打开了DEBUG日志缓别.
     * @return true打开,false没有打开.
     */
    public boolean isDebugEnabled() {
        return logger.isDebugEnabled();
    }

    /**
     * 是否打开了信息日志缓别.
     * @return true打开,false没有打开.
     */
    public boolean isInfoEnabled() {
        return logger.isInfoEnabled();
    }

    /**
     * 是否打开了错误日志缓别.
     * @return true打开,false没有打开.
     */
    public boolean isErrorEnabled() {
        return logger.isErrorEnabled();
    }
}

 

 

package com.etnetchina.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.charset.Charset;
import java.util.Arrays;

/**
 * 一些字节处理的方便方法。
 */
public class ByteUtil {

    /**
     * 构造新字节时需要与的值表
     */
    private static final byte[] BUILD_BYTE_TABLE = new byte[]{
        (byte) 128,
        (byte) 64,
        (byte) 32,
        (byte) 16,
        (byte) 8,
        (byte) 4,
        (byte) 2,
        (byte) 1
    };

    private ByteUtil() {
    }

    /**
     * short转换到字节数组
     * @param number 需要转换的数据。
     * @return 转换后的字节数组。
     */
    public static byte[] shortToByte(short number) {
        byte[] b = new byte[2];
        for (int i = 1; i >= 0; i--) {
            b[i] = (byte) (number % 256);
            number >>= 8;
        }
        return b;
    }

    /**
     * 字节到short转换
     * @param b short的字节数组
     * @return short数值。
     */
    public static short byteToShort(byte[] b) {
        return (short) ((((b[0] & 0xff) << 8) | b[1] & 0xff));
    }

    /**
     * 整型转换到字节数组
     * @param number 整形数据。
     * @return 整形数据的字节数组。
     */
    public static byte[] intToByte(int number) {
        byte[] b = new byte[4];
        for (int i = 3; i >= 0; i--) {
            b[i] = (byte) (number % 256);
            number >>= 8;
        }
        return b;
    }

    /**
     * 字节数组到整型转换
     * @param b 整形数据的字节数组。
     * @return 字节数组转换成的整形数据。
     */
    public static int byteToInt(byte[] b) {
        return ((((b[0] & 0xff) << 24)
                | ((b[1] & 0xff) << 16)
                | ((b[2] & 0xff) << 8)
                | (b[3] & 0xff)));
    }

    /**
     * long转换到字节数组
     * @param number 长整形数据。
     * @return 长整形转换成的字节数组。
     */
    public static byte[] longToByte(long number) {
        byte[] b = new byte[8];
        for (int i = 7; i >= 0; i--) {
            b[i] = (byte) (number % 256);
            number >>= 8;
        }
        return b;
    }

    /**
     * 字节数组到整型的转换
     * @param b 长整形字节数组。
     * @return 长整形数据。
     */
    public static long byteToLong(byte[] b) {
        return ((((long) b[0] & 0xff) << 56)
                | (((long) b[1] & 0xff) << 48)
                | (((long) b[2] & 0xff) << 40)
                | (((long) b[3] & 0xff) << 32)
                | (((long) b[4] & 0xff) << 24)
                | (((long) b[5] & 0xff) << 16)
                | (((long) b[6] & 0xff) << 8)
                | ((long) b[7] & 0xff));
    }

    /**
     * double转换到字节数组
     * @param d 双精度浮点。
     * @return 双精度浮点的字节数组。
     */
    public static byte[] doubleToByte(double d) {
        byte[] bytes = new byte[8];
        long l = Double.doubleToLongBits(d);
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = Long.valueOf(l).byteValue();
            l = l >> 8;
        }
        return bytes;
    }

    /**
     * 字节数组到double转换
     * @param b 双精度浮点字节数组。
     * @return 双精度浮点数据。
     */
    public static double byteToDouble(byte[] b) {
        long l;
        l = b[0];
        l &= 0xff;
        l |= ((long) b[1] << 8);
        l &= 0xffff;
        l |= ((long) b[2] << 16);
        l &= 0xffffff;
        l |= ((long) b[3] << 24);
        l &= 0xffffffffl;
        l |= ((long) b[4] << 32);
        l &= 0xffffffffffl;

        l |= ((long) b[5] << 40);
        l &= 0xffffffffffffl;
        l |= ((long) b[6] << 48);
        l &= 0xffffffffffffffl;

        l |= ((long) b[7] << 56);

        return Double.longBitsToDouble(l);
    }

    /**
     * float转换到字节数组
     * @param d 浮点型数据。
     * @return 浮点型数据转换后的字节数组。
     */
    public static byte[] floatToByte(float d) {
        byte[] bytes = new byte[4];
        int l = Float.floatToIntBits(d);
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = Integer.valueOf(l).byteValue();
            l = l >> 8;
        }
        return bytes;
    }

    /**
     * 字节数组到float的转换
     * @param b 浮点型数据字节数组。
     * @return 浮点型数据。
     */
    public static float byteToFloat(byte[] b) {
        int l;
        l = b[0];
        l &= 0xff;
        l |= ((long) b[1] << 8);
        l &= 0xffff;
        l |= ((long) b[2] << 16);
        l &= 0xffffff;
        l |= ((long) b[3] << 24);
        l &= 0xffffffffl;

        return Float.intBitsToFloat(l);
    }

    /**
     * 字符串到字节数组转换
     * @param s 字符串。
     * @param charset 字符编码
     * @return 字符串按相应字符编码编码后的字节数组。
     */
    public static byte[] stringToByte(String s, Charset charset) {
        return s.getBytes(charset);
    }

    /**
     * 字节数组带字符串的转换
     * @param b 字符串按指定编码转换的字节数组。
     * @param charset 字符编码。
     * @return 字符串。
     */
    public static String byteToString(byte[] b, Charset charset) {
        return new String(b, charset);
    }

    /**
     * 对象转换成字节数组。
     * @param obj 字节数组。
     * @return 对象实例相应的序列化后的字节数组。
     * @throws IOException
     */
    public static byte[] objectToByte(Object obj) throws IOException {
        ByteArrayOutputStream buff = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(buff);
        out.writeObject(obj);
        try {
            return buff.toByteArray();
        } finally {
            out.close();
        }
    }

    /**
     * 序死化字节数组转换成实际对象。
     * @param b 字节数组。
     * @return 对象。
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static Object byteToObject(byte[] b)
            throws IOException, ClassNotFoundException {
        ByteArrayInputStream buff = new ByteArrayInputStream(b);
        ObjectInputStream in = new ObjectInputStream(buff);
        Object obj = in.readObject();
        try {
            return obj;
        } finally {
            in.close();
        }
    }

    /**
     * 比较两个字节的每一个bit位是否相等.
     * @param a 比较的字节.
     * @param b 比较的字节
     * @return ture 两个字节每一位都相等,false有至少一位不相等.
     */
    public static boolean equalsBit(byte a, byte b) {
        return Arrays.equals(byteToBitArray(a), byteToBitArray(b));
    }

    /**
     * 比较两个数组中的每一个字节,两个字节必须二进制字节码每一位都相同才表示两个
     * byte相同.
     * @param a 比较的字节数组.
     * @param b 被比较的字节数.
     * @return ture每一个元素的每一位两个数组都是相等的,false至少有一位不相等.
     */
    public static boolean equalsBit(byte[] a, byte[] b) {
        if (a == b) {
            return true;
        }
        if (a == null || b == null) {
            return false;
        }

        int length = a.length;
        if (b.length != length) {
            return false;
        }

        for (int count = 0; count < a.length; count++) {
            if (!equalsBit(a[count], b[count])) {
                return false;
            }
        }
        return true;
    }

    /**
     * 返回某个字节的bit组成的字符串.
     * @param b 字节.
     * @return Bit位组成的字符串.
     */
    public static String bitString(byte b) {
        StringBuilder buff = new StringBuilder();
        boolean[] array = byteToBitArray(b);
        for (int i = 0; i < array.length; i++) {
            buff.append(array[i] ? 1 : 0);
        }
        return buff.toString();
    }

    /**
     * 计算出给定byte中的每一位,并以一个布尔数组返回.
     * true表示为1,false表示为0.
     * @param b 字节.
     * @return 指定字节的每一位bit组成的数组.
     */
    public static boolean[] byteToBitArray(byte b) {
        boolean[] buff = new boolean[8];
        int index = 0;
        for (int i = 7; i >= 0; i--) {
            buff[index++] = ((b >>> i) & 1) == 1;
        }
        return buff;
    }

    /**
     * 返回指定字节中指定bit位,true为1,false为0.
     * 指定的位从0-7,超出将抛出数据越界异常.
     *
     * @param b 需要判断的字节.
     * @param index 字节中指定位.
     * @return 指定位的值.
     */
    public static boolean byteBitValue(byte b, int index) {
        return byteToBitArray(b)[index];
    }

    /**
     * 根据布尔数组表示的二进制构造一个新的字节.
     * @param values 布尔数组,其中true表示为1,false表示为0.
     * @return 构造的新字节.
     */
    public static byte buildNewByte(boolean[] values) {
        byte b = 0;
        for (int i = 0; i < 8; i++) {
            if (values[i]) {
                b |= BUILD_BYTE_TABLE[i];
            }
        }
        return b;
    }

    /**
     * 将指定字节中的某个bit位替换成指定的值,true代表1,false代表0.
     * @param b 需要被替换的字节.
     * @param index 位的序号,从0开始.超过7将抛出越界异常.
     * @param newValue 新的值.
     * @return 替换好某个位值的新字节.
     */
    public static byte changeByteBitValue(byte b, int index, boolean newValue) {
        boolean[] bitValues = byteToBitArray(b);
        bitValues[index] = newValue;
        return buildNewByte(bitValues);
    }

    /**
     * 将指定的IP地址转换成字节表示方式.
     * IP数组的每一个数字都不能大于255,否则将抛出IllegalArgumentException异常.
     *
     * @param ipNums IP地址数组.
     * @return IP地址字节表示方式.
     */
    public static byte[] ipAddressBytes(String address) {
        if (address == null || address.length() < 0 || address.length() > 15) {
            throw new IllegalArgumentException("Invalid IP address.");
        }

        final int ipSize = 4;//最大IP位数
        final char ipSpace = '.';//IP数字的分隔符
        int[] ipNums = new int[ipSize];
        StringBuilder number = new StringBuilder();//当前操作的数字
        StringBuilder buff = new StringBuilder(address);
        int point = 0;//当前操作的数字下标,最大到3.
        char currentChar;
        for (int i = 0; i < buff.length(); i++) {
            currentChar = buff.charAt(i);
            if (ipSpace == currentChar) {
                //当前位置等于最大于序号后,还有字符没有处理表示这是一个错误的IP.
                if (point == ipSize - 1 && buff.length() - (i + 1) > 0) {
                    throw new IllegalArgumentException("Invalid IP address.");
                }
                ipNums[point++] = Integer.parseInt(number.toString());
                number.delete(0, number.length());
            } else {
                number.append(currentChar);
            }
        }
        ipNums[point] = Integer.parseInt(number.toString());

        byte[] ipBuff = new byte[ipSize];
        int pointNum = 0;
        for (int i = 0; i < 4; i++) {
            pointNum = Math.abs(ipNums[i]);
            if (pointNum > 255) {
                throw new IllegalArgumentException("Invalid IP address.");
            }
            ipBuff[i] = (byte) (pointNum & 0xff);
        }

        return ipBuff;
    }
}

 

分享到:
评论

相关推荐

    级联H桥SVG无功补偿系统在不平衡电网中的三层控制策略:电压电流双闭环PI控制、相间与相内电压均衡管理,级联H桥SVG无功补偿系统在不平衡电网中的三层控制策略:电压电流双闭环PI控制、相间与相内电压均

    级联H桥SVG无功补偿系统在不平衡电网中的三层控制策略:电压电流双闭环PI控制、相间与相内电压均衡管理,级联H桥SVG无功补偿系统在不平衡电网中的三层控制策略:电压电流双闭环PI控制、相间与相内电压均衡管理,不平衡电网下的svg无功补偿,级联H桥svg无功补偿statcom,采用三层控制策略。 (1)第一层采用电压电流双闭环pi控制,电压电流正负序分离,电压外环通过产生基波正序有功电流三相所有H桥模块直流侧平均电压恒定,电流内环采用前馈解耦控制; (2)第二层相间电压均衡控制,注入零序电压,控制通过注入零序电压维持相间电压平衡; (3)第三层相内电压均衡控制,使其所有子模块吸收的有功功率与其损耗补,从而保证所有H桥子模块直流侧电压值等于给定值。 有参考资料。 639,核心关键词: 1. 不平衡电网下的SVG无功补偿 2. 级联H桥SVG无功补偿STATCOM 3. 三层控制策略 4. 电压电流双闭环PI控制 5. 电压电流正负序分离 6. 直流侧平均电压恒定 7. 前馈解耦控制 8. 相间电压均衡控制 9. 零序电压注入 10. 相内电压均衡控制 以上十个关键词用分号分隔的格式为:不

    GTX 1080 PCB图纸

    GTX 1080 PCB图纸,内含图纸查看软件

    深度优化与应用:提升DeepSeek润色指令的有效性和灵活性指南

    内容概要:本文档详细介绍了利用 DeepSeek 进行文本润色和问答交互时提高效果的方法和技巧,涵盖了从明确需求、提供适当上下文到尝试开放式问题以及多轮对话的十个要点。每一部分内容都提供了具体的示范案例,如指定回答格式、分步骤提问等具体实例,旨在指导用户更好地理解和运用 DeepSeek 提升工作效率和交流质量。同时文中还强调了根据不同应用场景调整提示词语气和风格的重要性和方法。 适用人群:适用于希望通过优化提问技巧以获得高质量反馈的企业员工、科研人员以及一般公众。 使用场景及目标:本文针对所有期望提高 DeepSeek 使用效率的人群,帮助他们在日常工作中快速获取精准的答案或信息,特别是在撰写报告、研究材料准备和技术咨询等方面。此外还鼓励用户通过不断尝试不同形式的问题表述来进行有效沟通。 其他说明:该文档不仅关注实际操作指引,同样重视用户思维模式转变——由简单索取答案向引导 AI 辅助创造性解决问题的方向发展。

    基于FPGA与W5500实现的TCP网络通信测试平台开发-Zynq扩展口Verilog编程实践,基于FPGA与W5500芯片的TCP网络通信测试及多路Socket实现基于zynq开发平台和Vivad

    基于FPGA与W5500实现的TCP网络通信测试平台开发——Zynq扩展口Verilog编程实践,基于FPGA与W5500芯片的TCP网络通信测试及多路Socket实现基于zynq开发平台和Vivado 2019软件的扩展开发,基于FPGA和W5500的TCP网络通信 测试平台 zynq扩展口开发 软件平台 vivado2019.2,纯Verilog可移植 测试环境 压力测试 cmd命令下ping电脑ip,同时采用上位机进行10ms发包回环测试,不丢包(内部数据回环,需要时间处理) 目前实现单socket功能,多路可支持 ,基于FPGA; W5500; TCP网络通信; Zynq扩展口开发; 纯Verilog可移植; 测试平台; 压力测试; 10ms发包回环测试; 单socket功能; 多路支持。,基于FPGA与W5500的Zynq扩展口TCP通信测试:可移植Verilog实现的高效网络通信

    Labview液压比例阀伺服阀试验台多功能程序:PLC通讯、液压动画模拟、手动控制与调试、传感器标定、报警及记录、自动实验、数据处理与查询存储,报表生成与打印一体化解决方案 ,Labview液压比例阀

    Labview液压比例阀伺服阀试验台多功能程序:PLC通讯、液压动画模拟、手动控制与调试、传感器标定、报警及记录、自动实验、数据处理与查询存储,报表生成与打印一体化解决方案。,Labview液压比例阀伺服阀试验台多功能程序:PLC通讯、液压动画模拟、手动控制与调试、传感器标定、报警管理及实验自动化,labview液压比例阀伺服阀试验台程序:功能包括,同PLC通讯程序,液压动画,手动控制及调试,传感器标定,报警设置及报警记录,自动实验,数据处理曲线处理,数据库存储及查询,报表自动生成及打印,扫码枪扫码及信号录入等~ ,核心关键词:PLC通讯; 液压动画; 手动控制及调试; 传感器标定; 报警设置及记录; 自动实验; 数据处理及曲线处理; 数据库存储及查询; 报表生成及打印; 扫码枪扫码。,Labview驱动的智能液压阀测试系统:多功能控制与数据处理

    华为、腾讯、万科员工职业发展体系建设与实践.pptx

    华为、腾讯、万科员工职业发展体系建设与实践.pptx

    基于遗传算法的柔性车间调度优化 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    电网不对称故障下VSG峰值电流限制的柔性控制策略:实现电流平衡与功率容量的优化利用,电网不对称故障下VSG峰值电流限制的柔性控制策略:兼顾平衡电流与功率控制切换的动态管理,电网不对称故障下VSG峰值电

    电网不对称故障下VSG峰值电流限制的柔性控制策略:实现电流平衡与功率容量的优化利用,电网不对称故障下VSG峰值电流限制的柔性控制策略:兼顾平衡电流与功率控制切换的动态管理,电网不对称故障下VSG峰值电流限制的柔性不平衡控制(文章完全复现)。 提出一种在不平衡运行条件下具有峰值电流限制的可变不平衡电流控制方法,可灵活地满足不同操作需求,包括电流平衡、有功或无功恒定运行(即电流控制、有功控制或无功控制之间的相互切),注入电流保持在安全值内,以更好的利用VSG功率容量。 关键词:VSG、平衡电流控制、有功功率控制、无功功率控制。 ,VSG; 峰值电流限制; 柔性不平衡控制; 电流平衡控制; 有功功率控制; 无功功率控制。,VSG柔性控制:在电网不对称故障下的峰值电流限制与平衡管理

    libpinyin-tools-0.9.93-4.el7.x64-86.rpm.tar.gz

    1、文件内容:libpinyin-tools-0.9.93-4.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/libpinyin-tools-0.9.93-4.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊

    机器学习(预测模型):动漫《龙珠》相关的数据集

    数据集是一个以经典动漫《龙珠》为主题的多维度数据集,广泛应用于数据分析、机器学习和图像识别等领域。该数据集由多个来源整合而成,涵盖了角色信息、战斗力、剧情片段、台词以及角色图像等多个方面。数据集的核心内容包括: 角色信息:包含《龙珠》系列中的主要角色及其属性,如名称、种族、所属系列(如《龙珠》《龙珠Z》《龙珠超》等)、战斗力等级等。 图像数据:提供角色的图像资源,可用于图像分类和角色识别任务。这些图像来自动画剧集、漫画和相关衍生作品。 剧情与台词:部分数据集还包含角色在不同故事中的台词和剧情片段,可用于文本分析和自然语言处理任务。 战斗数据:记录角色在不同剧情中的战斗力变化和战斗历史,为研究角色成长和剧情发展提供支持。 数据集特点 多样性:数据集整合了角色、图像、文本等多种类型的数据,适用于多种研究场景。 深度:不仅包含角色的基本信息,还涵盖了角色的成长历程、技能描述和与其他角色的互动关系。 实用性:支持多种编程语言(如Python、R)的数据处理和分析,提供了详细的文档和示例代码。

    基于protues仿真的多功公交站播报系统设计(仿真图、源代码)

    基于protues仿真的多功公交站播报系统设计(仿真图、源代码) 该设计为基于protues仿真的多功公交站播报系统,实现温度显示、时间显示、和系统公交站播报功能; 具体功能如下: 1、系统使用51单片机为核心设计; 2、时钟芯片进行时间和日期显示; 3、温度传感器进行温度读取; 4、LCD12864液晶屏进行相关显示; 5、按键设置调节时间; 6、按键设置报站; 7、仿真图、源代码; 操作说明: 1、下行控制报站:首先按下(下行设置按键),(下行指示灯)亮,然后按下(手动播报)按键控制播报下一站; 2、上行控制报站:首先按上(上行设置按键),(上行指示灯)亮,然后按下(手动播报)按键控制播报下一站; 3、按下关闭播报按键,则关闭播报功能和清除显示

    基于微信小程序的琴房管理系统的设计与实现.zip

    采用Java后台技术和MySQL数据库,在前台界面为提升用户体验,使用Jquery、Ajax、CSS等技术进行布局。 系统包括两类用户:学生、管理员。 学生用户 学生用户只要实现了前台信息的查看,打开首页,查看网站介绍、琴房信息、在线留言、轮播图信息公告等,通过点击首页的菜单跳转到对应的功能页面菜单,包括网站首页、琴房信息、注册登录、个人中心、后台登录。 学生用户通过账户账号登录,登录后具有所有的操作权限,如果没有登录,不能在线预约。学生用户退出系统将注销个人的登录信息。 管理员通过后台的登录页面,选择管理员权限后进行登录,管理员的权限包括轮播公告管理、老师学生信息管理和信息审核管理,管理员管理后点击退出,注销登录信息。 管理员用户具有在线交流的管理,琴房信息管理、琴房预约管理。 在线交流是对前台用户留言内容进行管理,删除留言信息,查看留言信息。

    界面GUI设计MATLAB教室人数统计.zip

    MATLAB可以用于开发人脸识别考勤系统。下面是一个简单的示例流程: 1. 数据采集:首先收集员工的人脸图像作为训练数据集。可以要求员工提供多张照片以获得更好的训练效果。 2. 图像预处理:使用MATLAB的图像处理工具对采集到的人脸图像进行预处理,例如灰度化、裁剪、缩放等操作。 3. 特征提取:利用MATLAB的人脸识别工具包,如Face Recognition Toolbox,对处理后的图像提取人脸特征,常用的方法包括主成分分析(PCA)和线性判别分析(LDA)等。 4. 训练模型:使用已提取的人脸特征数据集训练人脸识别模型,可以选择支持向量机(SVM)、卷积神经网络(CNN)等算法。 5. 考勤系统:在员工打卡时,将摄像头捕获的人脸图像输入到训练好的模型中进行识别,匹配员工信息并记录考勤数据。 6. 结果反馈:根据识别结果,可以自动生成考勤报表或者实时显示员工打卡情况。 以上只是一个简单的步骤,实际开发过程中需根据具体需求和系统规模进行定制和优化。MATLAB提供了丰富的图像处理和机器学习工具,是开发人脸识别考勤系统的一个很好选择。

    hjbvbnvhjhjg

    hjbvbnvhjhjg

    HCIP、软考相关学习PPT

    HCIP、软考相关学习PPT提供下载

    绿豆BOX UI8版:反编译版六个全新UI+最新后台直播管理源码

    绿豆BOX UI8版:反编译版六个全新UI+最新后台直播管理源码 最新绿豆BOX反编译版六个UI全新绿豆盒子UI8版本 最新后台支持直播管理 作为UI6的升级版,UI8不仅修复了前一版本中存在的一些BUG,还提供了6套不同的UI界面供用户选择,该版本有以下特色功能: 在线管理TVBOX解析 在线自定义TVBOX 首页布局批量添加会员信息 并支持导出批量生成卡密 并支持导出直播列表管理功能

    vue3的一些语法以及知识点

    vue3的一些语法以及知识点

    西门子大型Fanuc机器人汽车焊装自动生产线程序经典解析:PLC博图编程与MES系统通讯实战指南,西门子PLC博图汽车焊装自动生产线FANUC机器人程序经典结构解析与MES系统通讯,西门子1500 大

    西门子大型Fanuc机器人汽车焊装自动生产线程序经典解析:PLC博图编程与MES系统通讯实战指南,西门子PLC博图汽车焊装自动生产线FANUC机器人程序经典结构解析与MES系统通讯,西门子1500 大型程序fanuc 机器人汽车焊装自动生产线程序 MES 系统通讯 大型程序fanuc机器人汽车焊装自动生产线程序程序经典结构清晰,SCL算法堆栈,梯形图和 SCL混编使用博图 V14以上版本打开 包括: 1、 PLC 博图程序 2 触摸屏程序 ,西门子1500; 大型程序; fanuc机器人; 汽车焊装自动生产线; MES系统通讯; SCL算法; 梯形图; SCL混编; 博图V14以上版本。,西门子博图大型程序:汽车焊装自动生产线MES系统通讯与机器人控制

    DeepSeek:从入门到精通

    DeepSeek:从入门到精通

    计及信息间隙决策与多能转换的综合能源系统优化调度模型:实现碳经济最大化与源荷不确定性考量,基于信息间隙决策与多能转换的综合能源系统优化调度模型:源荷不确定性下的高效碳经济调度策略,计及信息间隙决策及多

    计及信息间隙决策与多能转换的综合能源系统优化调度模型:实现碳经济最大化与源荷不确定性考量,基于信息间隙决策与多能转换的综合能源系统优化调度模型:源荷不确定性下的高效碳经济调度策略,计及信息间隙决策及多能转的综合能源系统优化调度 本代码构建了含风电、光伏、光热发电系统、燃气轮机、燃气锅炉、电锅炉、储气、储电、储碳、碳捕集装置的综合能源系统优化调度模型,并考虑P2G装置与碳捕集装置联合运行,从而实现碳经济的最大化,最重要的是本文引入了信息间隙决策理论考虑了源荷的不确定性(本代码的重点)与店铺的47代码形成鲜明的对比,注意擦亮眼睛,认准原创,该代码非常适合修改创新,,提供相关的模型资料 ,计及信息间隙决策; 综合能源系统; 优化调度; 多能转换; 碳经济最大化; 风电; 光伏; 燃气轮机; 储气; 储电; 储碳; 碳捕集装置; P2G装置联合运行; 模型资料,综合能源系统优化调度模型:基于信息间隙决策和多能转换的原创方案

Global site tag (gtag.js) - Google Analytics