목차
接口Controller
接口幂等性校验
实现类ServiceImpl
第三方调用接口Api实现类
生成签名工具类
HttpCilent工具类
附:分享一个获取IP工具类
Java java지도 시간 제3자가 사용할 수 있는 인터페이스를 Java로 제공하는 방법은 무엇입니까?

제3자가 사용할 수 있는 인터페이스를 Java로 제공하는 방법은 무엇입니까?

Apr 23, 2023 am 09:04 AM
java

接口Controller

在写接口前一定要签名做签名校验,我的签名方式做了特殊处理,因为接口是对外开放的,这个是为了避免恶意调用接口做的处理,叫做签名的混淆值,这个签名混淆值的作用是就算别人知道了接口,并且知道签名方式也不能被攻击,是为了避免被恶意篡改数据,签名混淆值就是一组特定加密后的数据。

	@PostMapping("refundDeductionPoints")
	public Result<SysIntegralStatement> refundDeductionPoints (@RequestParam Map<String,String> params){
		Result<SysIntegralStatement> result = new Result<SysIntegralStatement>();
		try {
			//签名校验
			String msgDigest = params.get("msgDigest");//签名
			String msgData = params.get("msgData");
			String timeStamp = params.get("timeStamp");
			String secret = params.get("secret");//	秘钥
			String sign = SignUtil.sign(msgData+"wf8la1tw7p9o2xz",timeStamp);//wf8la1tw7p9o2xz为签名混淆值
			if (!msgDigest.equals(sign)) {
				return result.setCode(1006).setReason("数字签名无效");
			}
			if (Common.isEmpty(secret)) {//先签名后幂等校验
				return result.setCode(1001).setReason("密钥不能为空");
			}
			/**
			 * 幂等校验
			 * 1.同一个用户操作同一个退货单一分钟内操作该单据视为重复操作(此秘钥已通过特殊处理)
			 */
			String value = redistempalte.opsForValue().get(secret);
			if (Common.isNotEmpty(value)) {	
				logger.error("重复请求 secret={}",value);
				return result.setCode(1007).setReason("重复请求");	
			}
			redistempalte.opsForValue().set(secret, "1",60,TimeUnit.SECONDS);//设置缓存一分钟
			return service.refundDeductionPoints(params);
		} catch (Exception e) {
			logger.error("添加积分流水异常", e);
			return result.setCode(ErrorCodes.BUSINESS_ERROR).setReason("生成积分流水失败");
		}
	}
로그인 후 복사

接口幂等性校验

此接口做幂等性校验,幂等性校验常见解决方案有很多,可以自行根据实际情况选择,

说到幂等首先要先了解什么是幂等

概念:

幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。

在编程中.一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。

这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,“getUsername()和setTrue()”函数就是一个幂等函数.

幂等性, 通俗的说就是一个接口, 多次发起同一个请求, 必须保证操作只能执行一次,比如:

订单接口, 不能多次创建订单

支付接口, 重复支付同一笔订单只能扣一次钱

支付宝回调接口, 可能会多次回调, 必须处理重复回调

普通表单提交接口, 因为网络超时等原因多次点击提交, 只能成功一次

等等

解决方案常见的几种方式

唯一索引 – 防止新增脏数据

token机制 – 防止页面重复提交

悲观锁 – 获取数据的时候加锁(锁表或锁行)

乐观锁 – 基于版本号version实现, 在更新数据那一刻校验数据

分布式锁 – redis(jedis、redisson)或zookeeper实现

状态机 – 状态变更, 更新数据时判断状态

如果有小伙伴不理解什么是幂等可以看看官方是解释

实现类ServiceImpl

	@Transactional
	@Override
	public Result<SysIntegralStatement> refundDeductionPoints(Map<String, String> params) {
		String msgData = params.get("msgData");
		ParamIntegral entity = new Gson().fromJson(msgData, ParamIntegral.class);
		if (Common.isNull(entity)) {
			return new Result<SysIntegralStatement>().setCode(ErrorCodes.INNER_ERROR).setReason("请求参数不能为空");
		}
		if (Common.isEmpty(entity.getBitems())) {
			return new Result<SysIntegralStatement>().setCode(ErrorCodes.INNER_ERROR).setReason("请求参数不能为空");
		}
		int row = 0;
		for (ParamIntegral bitem : entity.getBitems()) {
			if (Common.isEmpty(bitem.getDdh())) {
				return new Result<SysIntegralStatement>().setCode(ErrorCodes.INNER_ERROR).setReason("订单号为必传参数");
			}
			if (null == bitem.getJfz()) {
				return new Result<SysIntegralStatement>().setCode(ErrorCodes.INNER_ERROR).setReason("扣减积分不能为空");
			}
			List<MallOrderInfo> orderInfo = mallOrderInfoMapper.selectByDdh(bitem.getDdh());
			if (orderInfo == null) {
				return new Result<SysIntegralStatement>().setCode(ErrorCodes.INNER_ERROR)
						.setReason("订单号为" + bitem.getDdh() + "没有此订单请联系客服核对信息。");
			}
			if (orderInfo != null && orderInfo.size() > 1) {
				return new Result<SysIntegralStatement>().setCode(ErrorCodes.INNER_ERROR)
						.setReason("订单号为" + bitem.getDdh() + "有多个相同订单请联系客服核对信息。");
			}
			if (!"E".equals(orderInfo.get(0).getDdzt())) {
				return new Result<SysIntegralStatement>().setCode(ErrorCodes.INNER_ERROR)
						.setReason("订单号为" + bitem.getDdh() + "未确认收货还没产生积分不允许退货。");
			}
			SysIntegral integral = Common.first(integralMapper.selectByMdbm(orderInfo.get(0).getMdbm()));
			if (integral == null) {
				return new Result<SysIntegralStatement>().setCode(ErrorCodes.INNER_ERROR)
						.setReason("门店编码为" + orderInfo.get(0).getMdbm() + "积分汇总没有找到此门店,请联系客服核实");
			}
			BigDecimal kyjf = BigDecimal.ZERO;
			if (entity.getReturnGoods() == true) {
				// 可用积分小于扣减积分不够扣ERP使用前抵扣
				if (bitem.getJfz().compareTo(integral.getKyjf()) == 1) {
					kyjf = BigDecimal.ZERO;					
				} else {
					// 可用积分 = 当前可用积分-扣减积分
					kyjf = Common.nvl(integral.getKyjf(), BigDecimal.ZERO).subtract(bitem.getJfz());
				}
			} else {
				// 可用积分 = 当前可用积分+退还积分
				kyjf = Common.nvl(integral.getKyjf(), BigDecimal.ZERO).add(bitem.getJfz());				
			}		
			// 更新积分汇总
			SysIntegral dataMap = new SysIntegral();
			dataMap.setIntegralId(integral.getIntegralId());
			dataMap.setMdbm(integral.getMdbm());
			dataMap.setKyjf(kyjf);
			dataMap.setUpdateTime(new Date());
			dataMap.setUpdateUser(entity.getUserName());
			dataMap.setUpdateUserid(entity.getUserId().intValue());		
			row = integralMapper.updateByPrimaryKeySelective(dataMap);
			if (row == 0) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return new Result<SysIntegralStatement>().setCode(ErrorCodes.INNER_ERROR).setReason("更新积分失败");
			}
			//推送到ERP门店信息
			 BdMdxxH mdxx =new BdMdxxH();
			 mdxx.setMdbm(integral.getMdbm());
			 mdxx.setMdjf(kyjf);
			com.lkfs.cw.common.Result<BdMdxxH> bdMdxxh = dataBaseServiceApi.updateStorePoints(mdxx);
			if (!bdMdxxh.isComplete()) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return new Result<SysIntegralStatement>().setCode(bdMdxxh.getCode()).setReason(bdMdxxh.getReason());
			}		
			SysIntegralStatement statement = new SysIntegralStatement();
			if (entity.getReturnGoods() == true) {
				statement.setJfz(bitem.getJfz().negate());// 消费的积分值
				if (bitem.getJfz().compareTo(integral.getKyjf()) == 1) {// 可用积分小于扣减积分不够扣ERP使用前抵扣
					statement.setTzhjfz(BigDecimal.ZERO);// 调整后积分值
				} else {
					statement.setTzhjfz(Common.nvl(integral.getKyjf(), BigDecimal.ZERO).subtract(bitem.getJfz()));// 调整后积分值
				}
				statement.setJfxflx("E");// 积分支出
				statement.setXxsm("退货扣减积分(订单号为:" + bitem.getDdh() + "," + "退货单号为:" + entity.getDjh() + ")" + "已扣除:"
						+ bitem.getJfz().negate() + ":积分");
			} else {// 取消退货
				statement.setJfxflx("I");// 积分收入
				statement.setJfz(bitem.getJfz());// 取消退货把积分赠送回来
				statement.setTzhjfz(Common.nvl(integral.getKyjf(), BigDecimal.ZERO).add(bitem.getJfz()));// 调整后积分值
				statement.setXxsm("取消退货(订单号为:" + bitem.getDdh() + "," + "退货单号为:" + entity.getDjh() + ")" + "已退还:"
						+ bitem.getJfz() + ":积分");
			}
			statement.setIntegralId(integral.getIntegralId());// 该门店积分编码
			statement.setTzqjfz(integral.getKyjf());// 调整前积分值
			statement.setDdh(entity.getDdh());
			statement.setCreateTime(new Date());// 流水生成时间
			statement.setCreateUser(entity.getUserName());
			statement.setCreateUserid(entity.getUserId().intValue());
			statement.setJftz("T");// 积分扣减为T
			statement.setZt("Y");// 状态 Y:有效
			row = mapper.insert(statement);
			if (row == 0) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return new Result<SysIntegralStatement>().setCode(ErrorCodes.INNER_ERROR).setReason("插入积分流水失败");
			}
		}
		return new Result<SysIntegralStatement>().setCode(ErrorCodes.SUCCESS).setReason("操作成功");
	}
로그인 후 복사

第三方调用接口Api实现类

模拟第三方合作方调用接口

//此方式以上已写了封装信息就不一一展示了,可以根据实际情况自行操作
	private void pushIntegral(Long djlsh) {
		FiSjysjsH fiSjysjsh = mapper.selectByPrimaryKey(djlsh);				
		//订单退货调用某某退货扣减积分接口
		List<FiSjysjsB> sjysjsbList = bmapper.selectByKhddh(djlsh);
		if (sjysjsbList != null && sjysjsbList.size() > 0) {
			List<ParamIntegral> list = new ArrayList<ParamIntegral>();
			for (FiSjysjsB bitem : sjysjsbList) {
				ParamIntegral temp = new ParamIntegral();
				temp.setDdh(bitem.getKhddh());
				temp.setJfz(bitem.getJfz());			
				list.add(temp);
			}
			ParamIntegral param = new ParamIntegral();
			param.setBitems(list);
			param.setDjh(fiSjysjsh.getDjh());
			param.setUserId(AppRealm.getCurrentUser().getUserId());
			param.setUserName(AppRealm.getCurrentUser().getUserName());
			if (new Short("1").equals(fiSjysjsh.getLocked())) {
				param.setReturnGoods(true);
			}else {
				param.setReturnGoods(false);
			}
			String msgData = new Gson().toJson(param).toString();
			Map<String, String> params = new HashMap<String, String>();
			String timeStamp = String.valueOf(System.currentTimeMillis());//时间戳
			params.put("timeStamp", timeStamp);
			params.put("msgData", msgData);	
			params.put("msgDigest", SignUtil.sign(msgData+"wf8la1tw7p9o2xz", timeStamp));//生成签名第二个值暂定(wf8la1tw7p9o2xz签名混淆值)
			params.put("secret",IDEMPOTENT_SECRET_PREFIX + fiSjysjsh.getDjh() + AppRealm.getCurrentUser().getUserId()+param.getReturnGoods() );//自定义密钥 做幂等校验
			String result = HttpCilent.post(B2B_URL, params); //发送http post请求
			B2bIntegralResponse res = new Gson().fromJson(result, B2bIntegralResponse.class);
			if (null == res) {
				throw new RuntimeException("调用积分接口系统异常");
			}
			if (res.getCode() != 0) {//接口返回失败异常代码提示
				throw new RuntimeException("调用积分接口发生异常,异常代码为:"+res.getCode()+"异常信息为:"+res.getReason());	
			}
		}
	}
로그인 후 복사

生成签名工具类

package com.cy.xgsm.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

/**
 * 
 * @author Dylan
 *
 */
public class SignUtil {
	
private static final Logger log = LoggerFactory.getLogger(SignUtil.class);
	
	/**
	 * 
	 */
	public static String sign(String str, String secret) {
		StringBuilder enValue = new StringBuilder();
		enValue.append(secret);
		enValue.append(str);
		enValue.append(secret);
		return encryptByMD5(enValue.toString());
	}

	private static String encryptByMD5(String data) {
		String re_md5 = new String();
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(data.getBytes());
			byte b[] = md.digest();
			int i;
			StringBuffer buf = new StringBuffer();
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					buf.append("0");
				buf.append(Integer.toHexString(i));
			}
			re_md5 = buf.toString();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return re_md5.toUpperCase();
	}

	public static String compare(String jsonStr,String secret ){

		JsonParser jsonParser = new JsonParser();
		JsonObject jsonObject = jsonParser.parse(jsonStr).getAsJsonObject();
		String sign1 = "null";
		JsonElement signElement = jsonObject.remove("sign");
		if( signElement != null ){
			sign1 = signElement.getAsString();
		}
		log.info("sign1: " + sign1);
		StringBuilder enValue = new StringBuilder();
		enValue.append(secret);
		enValue.append(jsonObject.toString());
		enValue.append(secret);
		String sign2 = encryptByMD5(enValue.toString());
		jsonObject.addProperty("sign", sign2);
		return jsonObject.toString();
	}
}
로그인 후 복사

HttpCilent工具类

这个工具类在我之前的文章也有但是没有把这个方式的放上去,如果有需要用到可直接把一下代码复制到这个Http工具类(见文末) 最后即可直接使用。

   /**
     * 发送post请求
     * @param url 目的url
     * @param parameters 参数
     * @return
     */
    public static String post(String url, Map<String, String> parameters) {
    	String result = "";// 返回的结果
    	BufferedReader in = null;// 读取响应输入流
    	PrintWriter out = null;
    	StringBuffer sb = new StringBuffer();// 处理请求参数
    	String params = "";// 编码之后的参数
    	try {
    	// 编码请求参数
    	if (parameters.size() == 1) {
    	for (String name : parameters.keySet()) {
    	sb.append(name)
    	.append("=")
    	.append(java.net.URLEncoder.encode(
    	parameters.get(name), "UTF-8"));
    	}
    	params = sb.toString();
    	} else {
    	for (String name : parameters.keySet()) {
    	sb.append(name)
    	.append("=")
    	.append(java.net.URLEncoder.encode(
    	parameters.get(name), "UTF-8")).append("&");
    	}
    	String temp_params = sb.toString();
    	params = temp_params.substring(0, temp_params.length() - 1);
    	}
    	// 创建URL对象
    	java.net.URL connURL = new java.net.URL(url);
    	// 打开URL连接
    	java.net.HttpURLConnection httpConn = (java.net.HttpURLConnection) connURL
    	.openConnection();
    	// 设置通用属性
    	httpConn.setRequestProperty("Accept", "*/*");
    	httpConn.setRequestProperty("Connection", "Keep-Alive");
    	httpConn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
    	httpConn.setRequestProperty("User-Agent",
    	"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)");
    	// 设置POST方式
    	httpConn.setDoInput(true);
    	httpConn.setDoOutput(true);
    	// 获取HttpURLConnection对象对应的输出流
    	out = new PrintWriter(httpConn.getOutputStream());
    	// 发送请求参数
    	out.write(params);
    	// flush输出流的缓冲
    	out.flush();
    	// 定义BufferedReader输入流来读取URL的响应,设置编码方式
    	in = new BufferedReader(new InputStreamReader(
    	httpConn.getInputStream(), "UTF-8"));
    	String line;
    	// 读取返回的内容
    	while ((line = in.readLine()) != null) {
    	result += line;
    	}
    	} catch (Exception e) {
    	e.printStackTrace();

    	} finally {
    	try {
    	if (out != null) {
    	out.close();
    	}
    	if (in != null) {
    	in.close();
    	}
    	} catch (IOException ex) {
    	ex.printStackTrace();
    	}
    	}
    	return result;
    	}
로그인 후 복사

附:分享一个获取IP工具类

在日常开发中,经常会遇到需要记录IP的需求,接下来分享一个获取IP工具类,希望对小伙伴有帮助

package com.cy.xgsm.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.servlet.http.HttpServletRequest;

/**
 * 获取IP工具类
 * @author Dylan
 *
 */
public class IpUtils {
	
	private static Logger logger = LoggerFactory.getLogger(IpUtils.class);

	/**
	 * 获取IP地址
	 * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
	 * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
	 */
    public static String getIpAddr(HttpServletRequest request)
    {
        if (request == null)
        {
            return "unknown";
        }
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("X-Forwarded-For");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("X-Real-IP");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getRemoteAddr();
        }

        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }

    public static boolean internalIp(String ip)
    {
        byte[] addr = textToNumericFormatV4(ip);
        return internalIp(addr) || "127.0.0.1".equals(ip);
    }

    private static boolean internalIp(byte[] addr)
    {
        if (StringUtils.isNull(addr) || addr.length < 2)
        {
            return true;
        }
        final byte b0 = addr[0];
        final byte b1 = addr[1];
        final byte section1 = 0x0A;
        final byte section2 = (byte) 0xAC;
        final byte section3 = (byte) 0x10;
        final byte section4 = (byte) 0x1F;
        final byte section5 = (byte) 0xC0;
        final byte section6 = (byte) 0xA8;
        switch (b0)
        {
            case section1:
                return true;
            case section2:
                if (b1 >= section3 && b1 <= section4)
                {
                    return true;
                }
            case section5:
                switch (b1)
                {
                    case section6:
                        return true;
                    default:
                        return false;    
                }
            default:
                return false;
        }
    }

    /**
     * 将IPv4地址转换成字节
     * 
     * @param text IPv4地址
     * @return byte 字节
     */
    public static byte[] textToNumericFormatV4(String text)
    {
        if (text.length() == 0)
        {
            return null;
        }

        byte[] bytes = new byte[4];
        String[] elements = text.split("\\.", -1);
        try
        {
            long l;
            int i;
            switch (elements.length)
            {
                case 1:
                    l = Long.parseLong(elements[0]);
                    if ((l < 0L) || (l > 4294967295L)){
                        return null;
                    }
                    bytes[0] = (byte) (int) (l >> 24 & 0xFF);
                    bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
                    bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
                    bytes[3] = (byte) (int) (l & 0xFF);
                    break;
                case 2:
                    l = Integer.parseInt(elements[0]);
                    if ((l < 0L) || (l > 255L)){
                        return null;
                    }
                    bytes[0] = (byte) (int) (l & 0xFF);
                    l = Integer.parseInt(elements[1]);
                    if ((l < 0L) || (l > 16777215L)){
                        return null;
                    }
                    bytes[1] = (byte) (int) (l >> 16 & 0xFF);
                    bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
                    bytes[3] = (byte) (int) (l & 0xFF);
                    break;
                case 3:
                    for (i = 0; i < 2; ++i)
                    {
                        l = Integer.parseInt(elements[i]);
                        if ((l < 0L) || (l > 255L)){
                            return null;
                        }
                        bytes[i] = (byte) (int) (l & 0xFF);
                    }
                    l = Integer.parseInt(elements[2]);
                    if ((l < 0L) || (l > 65535L)){
                        return null;
                    }
                    bytes[2] = (byte) (int) (l >> 8 & 0xFF);
                    bytes[3] = (byte) (int) (l & 0xFF);
                    break;
                case 4:
                    for (i = 0; i < 4; ++i)
                    {
                        l = Integer.parseInt(elements[i]);
                        if ((l < 0L) || (l > 255L)){
                            return null;
                        }
                        bytes[i] = (byte) (int) (l & 0xFF);
                    }
                    break;
                default:
                    return null;
            }
        }
        catch (NumberFormatException e)
        {
            return null;
        }
        return bytes;
    }

    public static String getHostIp()
    {
        try
        {
            return InetAddress.getLocalHost().getHostAddress();
        }
        catch (UnknownHostException e)
        {
        }
        return "127.0.0.1";
    }

    public static String getHostName()
    {
        try
        {
            return InetAddress.getLocalHost().getHostName();
        }
        catch (UnknownHostException e)
        {
        }
        return "未知";
    }
}
로그인 후 복사

위 내용은 제3자가 사용할 수 있는 인터페이스를 Java로 제공하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 채팅 명령 및 사용 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

자바의 완전수 자바의 완전수 Aug 30, 2024 pm 04:28 PM

Java의 완전수 가이드. 여기서는 정의, Java에서 완전 숫자를 확인하는 방법, 코드 구현 예제에 대해 논의합니다.

Java의 난수 생성기 Java의 난수 생성기 Aug 30, 2024 pm 04:27 PM

Java의 난수 생성기 안내. 여기서는 예제를 통해 Java의 함수와 예제를 통해 두 가지 다른 생성기에 대해 설명합니다.

자바의 웨카 자바의 웨카 Aug 30, 2024 pm 04:28 PM

Java의 Weka 가이드. 여기에서는 소개, weka java 사용 방법, 플랫폼 유형 및 장점을 예제와 함께 설명합니다.

Java의 스미스 번호 Java의 스미스 번호 Aug 30, 2024 pm 04:28 PM

Java의 Smith Number 가이드. 여기서는 정의, Java에서 스미스 번호를 확인하는 방법에 대해 논의합니다. 코드 구현의 예.

Java Spring 인터뷰 질문 Java Spring 인터뷰 질문 Aug 30, 2024 pm 04:29 PM

이 기사에서는 가장 많이 묻는 Java Spring 면접 질문과 자세한 답변을 보관했습니다. 그래야 면접에 합격할 수 있습니다.

Java 8 Stream foreach에서 나누거나 돌아 오시겠습니까? Java 8 Stream foreach에서 나누거나 돌아 오시겠습니까? Feb 07, 2025 pm 12:09 PM

Java 8은 스트림 API를 소개하여 데이터 컬렉션을 처리하는 강력하고 표현적인 방법을 제공합니다. 그러나 스트림을 사용할 때 일반적인 질문은 다음과 같은 것입니다. 기존 루프는 조기 중단 또는 반환을 허용하지만 스트림의 Foreach 메소드는이 방법을 직접 지원하지 않습니다. 이 기사는 이유를 설명하고 스트림 처리 시스템에서 조기 종료를 구현하기위한 대체 방법을 탐색합니다. 추가 읽기 : Java Stream API 개선 스트림 foreach를 이해하십시오 Foreach 메소드는 스트림의 각 요소에서 하나의 작업을 수행하는 터미널 작동입니다. 디자인 의도입니다

Java의 날짜까지의 타임스탬프 Java의 날짜까지의 타임스탬프 Aug 30, 2024 pm 04:28 PM

Java의 TimeStamp to Date 안내. 여기서는 소개와 예제와 함께 Java에서 타임스탬프를 날짜로 변환하는 방법에 대해서도 설명합니다.

캡슐의 양을 찾기위한 Java 프로그램 캡슐의 양을 찾기위한 Java 프로그램 Feb 07, 2025 am 11:37 AM

캡슐은 3 차원 기하학적 그림이며, 양쪽 끝에 실린더와 반구로 구성됩니다. 캡슐의 부피는 실린더의 부피와 양쪽 끝에 반구의 부피를 첨가하여 계산할 수 있습니다. 이 튜토리얼은 다른 방법을 사용하여 Java에서 주어진 캡슐의 부피를 계산하는 방법에 대해 논의합니다. 캡슐 볼륨 공식 캡슐 볼륨에 대한 공식은 다음과 같습니다. 캡슐 부피 = 원통형 볼륨 2 반구 볼륨 안에, R : 반구의 반경. H : 실린더의 높이 (반구 제외). 예 1 입력하다 반경 = 5 단위 높이 = 10 단위 산출 볼륨 = 1570.8 입방 단위 설명하다 공식을 사용하여 볼륨 계산 : 부피 = π × r2 × h (4

See all articles