96.【SpringBoot接入支付宝-thymeleaf-springBoot】

news2024/12/27 5:31:30

SpringBoot接入支付宝

  • (一)、前提工作:
    • 1、进入支付宝开发平台—沙箱环境
        • 1.1、进入个人沙箱环境
        • 1.2、接下来进行几个密钥的生成
        • 1.3、拿到两个密钥后,进行自定义密钥配置
        • 1.4、至此,我们沙箱环境的配置和基本参数都已经获取到。
  • (二)、Java代码-thymeleaf
    • 1.导入两个包
    • 2.编写两个代码
    • 3.控制层代码优化

(一)、前提工作:

1、进入支付宝开发平台—沙箱环境

沙箱环境-支付宝文档中心

1.1、进入个人沙箱环境

参考文档
点击进入沙箱环境并用支付宝登陆
在这里插入图片描述

沙箱管理界面如图所示

appid,支付宝网关,自定义密钥等
在这里插入图片描述

这里是沙箱支付宝(虚拟)的账号和密码,可以用来支付
在这里插入图片描述

1.2、接下来进行几个密钥的生成

点击进入密钥工具
点击生成

在这里插入图片描述

这时我们拿到两个密钥,将它们保存,这两个密钥很重要

应用私钥
应用公钥

1.3、拿到两个密钥后,进行自定义密钥配置

进入最开始的沙箱管理界面,点击自定义密钥,点击设置(查看),我们选择的是RSA2密钥
在这里插入图片描述

选择“公钥”这一选项

在这里插入图片描述

将上一步骤生成的应用公钥填进来,会得到支付宝公钥这另一个密钥,记住并保存这个支付宝公钥
在这里插入图片描述

1.4、至此,我们沙箱环境的配置和基本参数都已经获取到。

在这里插入图片描述

(二)、Java代码-thymeleaf

1.导入两个包

导入一个包
我用的开发语言是JAVA,工具为IDEA,一个简单的springboot工程
1.构建一个普通的springboot工程,引入支付宝SDK的maven依赖:

<!--支付宝支付接口-->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>3.0.0</version>
        </dependency>
<!--      thymeleaf  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>2.7.7</version>
        </dependency>

2.编写两个代码

新建一个AlipayConfig类,用于配置支付的相关配置:
里面的配置信息,标记是你的就写你的。没标记就照搬

package com.jsxs.config;

import java.io.FileWriter;
import java.io.IOException;

public class AlipayConfig {

    // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号,开发时使用沙箱提供的APPID,生产环境改成自己的APPID
    public static String APP_ID = "122620920";

    // 商户私钥,您的PKCS8格式RSA2私钥
    public static String APP_PRIVATE_KEY = "MIIEvwIBADANBgkqhkiG9w0BAQEF+Qs2Yi1jB9htWFJOmGJALU8vo7Qy9evJoW97J4sie+5lYviaawuGBF0pGukmiByk4e3gFsMkh4y73zMYnqbpoZGKLSlHBABmeq6ladIEf5A/xUTHcV6Un0c5B4YZH8d0t4voKYhnf0B51l51C17+oOHqyiVJHpl58vwbCIiirqTKTR8SqwoPPBpodoOC2F/IqanlXq4823nTodVEXCYOhAgMBAAECggEBAI2MtR4jyI+3UB+GPH+XIULH1p6xEw9sxwkLHeQNEGNzaSTASDbNhhsduo2L9Kx/z3qInOSJCccckSEkkrIWiC6UP5e1UqeXQ7zR86Cvwe3yFeQCBpeXDoQiEnhlh68bdrXSY6TZRR55n29ADh9FG8IP3WFdWe8IIgxriS5eQz2XzYOmSJAQsW69LreD+q5Lp97VPEjLAfPOaeMfsNSoaP40pZ+2/uQYsaaPcq0aIVO1idgxqzsJcSdtncbbYGBSYH8b248zjhqMX/PwgK/0jQBsvXJAG8IJLW9E7i5skFbQzqtxFCk4onfg8u00pWopMkEugUlQcBROh3f/ZZ0/mtECgYEA4W2nhxrc+VqsLl6/LwsCplyLlq6W26ihEePCYgcYcJHEmBDkRnBbmWyclsIDIJ+VEqaZ9VRwMfUeJf+IkxsWgxUEfApPHyzU+AVgpD6yZUEQog/Yql3m0A+KVBbyXGzrrd3gixQeSNV9FAvOZnPhcosot6Ao+O/BmcV89cL/+fcCgYEAt4vM+X8tyAnzTOmFYR95BVY7XooBNKWFInEJ2ykbmiD+8AOOo3wRwEQJpLp2RbtHKwvUGw7eNSAd8sddUwk751HQ3h0fiJQ2UUXpak3lGoKWWEY2ofHTeB+WTKOcIjk0WbX1GRuNnAJssrK2wkUlHpwz4h3o2GAPgw/07JGVSScCgYAvEou5/ZUJCLMNl8FKXH04KfkIBPsBcUv5BVtQxvSGhRnNOzG/t7SY7AIixO6MQGaLl3hsry4icHHUM3DcbvqbcqcWE70D4IO0KsNMaL8tv5FuleqDYMpSxfv3pTcEr8Xi74L058WPJe1RY0m9QRNhrMda2LnViZMevgti8k4rbwKBgQCs2EYKni1qt5Qa1b35HD5HPFFkUemYvlaFfJWfgTKxDmmFdJQaeHfu6yN5sO439IisjNMNOA8hUEFjo0LLM2LqDy32PM65O3l7R67roLcjI96Y+mXwU16lPHm5aklaISyfXq6VGlFcnRvnnExm3d562PYy9Z+UQ8HX1mr7bI18+QKBgQDO2bDicEShwtWcnT1Nooa4J0v/LILC1exBSX12OdjVCPkn52x/RmI7nQu/nzfwJB8/Spw5Kh93BGZr4qDMFSfE81L9ApWAtvQpbZ8oz22SRrCxno2rKHO4I2Bh50BtXjtTfO4u9TBIXdV1lr9+ivQCsup6KeslS9+xWsP92n58IQ==\n";

    // 支付宝公钥,您的 查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
    public static String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx0R/5SJaYXD9uBTfzbQJvYIh07GHVoeppfndAaoy/HNJrlotxAclJPwLEudVWF3hSXqf1kafXTGfKBCRYTYCoGywm0fQNXH7fZuqYpOu7duKkQJDB+RNxOMWRmU4cemdwIDAQAB\n";

    // 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    public static String notify_url = "https://www.baidu.com";

    // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问(其实就是支付成功后返回的页面)
    public static String return_url = "https://www.baidu.com";

    // 签名方式
    public static String sign_type = "RSA2";

    // 字符编码格式
    public static String CHARSET = "utf-8";

    // 支付宝网关,这是沙箱的网关(你自己的)
    public static String gatewayUrl = "https://openapi.alipaydev.cay.do";

    // 支付宝网关
    public static String log_path = "C:\\";


//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

    /**
     * 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
     * @param sWord 要写入日志里的文本内容
     */
    public static void logResult(String sWord) {
        FileWriter writer = null;
        try {
            writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis()+".txt");
            writer.write(sWord);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

新建一个controller包,用于存放Action,新建一个PayController类,编写一个用于支付的接口/pay

package com.jsxs.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.jsxs.config.AlipayConfig;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Controller
public class PayController {


    @RequestMapping("/pay")
    public void payController(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.sign_type);

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

        //商户订单号,商户网站订单系统中唯一订单号,必填
        String out_trade_no = new String(request.getParameter("WIDout_trade_no").getBytes("ISO-8859-1"), "UTF-8");
        //付款金额,必填
        String total_amount = new String(request.getParameter("WIDtotal_amount").getBytes("ISO-8859-1"), "UTF-8");
        //订单名称,必填
        String subject = new String(request.getParameter("WIDsubject").getBytes("ISO-8859-1"), "UTF-8");
        //商品描述,可空
        String body = new String(request.getParameter("WIDbody").getBytes("ISO-8859-1"), "UTF-8");

        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                + "\"total_amount\":\"" + total_amount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"body\":\"" + body + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        //若想给BizContent增加其他可选请求参数,以增加自定义超时时间参数timeout_express来举例说明
        //alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
        //		+ "\"total_amount\":\""+ total_amount +"\","
        //		+ "\"subject\":\""+ subject +"\","
        //		+ "\"body\":\""+ body +"\","
        //		+ "\"timeout_express\":\"10m\","
        //		+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        //请求参数可查阅【电脑网站支付的API文档-alipay.trade.page.pay-请求参数】章节

        //请求
        String form = "";
        try {
            form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        response.setContentType("text/html;charset=" + AlipayConfig.CHARSET);
        response.getWriter().write(form);//直接将完整的表单html输出到页面
        response.getWriter().flush();
        response.getWriter().close();
    }

    @RequestMapping("/")
    public String toTest(){
        return "index";
    }
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>

<form action="/pay" method="post">
    订单号:<input type="text" name="WIDout_trade_no" required><br/>
    订单名称:<input type="text" name="WIDsubject" required><br/>
    付款金额:<input type="text" name="WIDtotal_amount" required><br/>
    WIDbody:<input type="text" name="WIDbody"><br/>
    <input type="submit" value="下单"> <input type="reset" value="重置">
</form>

required保证提交的时候这两项内容非空
5. controller类添加跳转html页面的映射:

    @RequestMapping("/")
    public String toTest(){
        return "index";
    }

6.测试运行,启动项目,在浏览器输入:http://localhost:8080/

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.控制层代码优化

package com.jsxs.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.jsxs.config.AlipayConfig;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@Controller
public class PayController {


    @RequestMapping("/pay")
    public void payController(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.sign_type);

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

        //商户订单号,商户网站订单系统中唯一订单号,必填

        //   订单号   order
        String order = UUID.randomUUID().toString().replaceAll("-", "");
        // 付款金额  money
        String payMoney="100";
        //订单名称
        String orderName="江道远火锅店";
        String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S").format(new Date());
        //商品描述
        String orderDescription=format+"  "+"消费了蔬菜类";


        //
        String out_trade_no = new String(order.getBytes("ISO-8859-1"), "UTF-8");
        //付款金额,必填
        String total_amount = new String(payMoney.getBytes("ISO-8859-1"), "UTF-8");
        //订单名称,必填
        String subject = new String(orderName.getBytes("ISO-8859-1"), "gbk");
        //商品描述,可空
        String body = new String(orderDescription.getBytes("ISO-8859-1"), "gbk");

        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                + "\"total_amount\":\"" + total_amount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"body\":\"" + body + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        //若想给BizContent增加其他可选请求参数,以增加自定义超时时间参数timeout_express来举例说明
        //alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
        //		+ "\"total_amount\":\""+ total_amount +"\","
        //		+ "\"subject\":\""+ subject +"\","
        //		+ "\"body\":\""+ body +"\","
        //		+ "\"timeout_express\":\"10m\","
        //		+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        //请求参数可查阅【电脑网站支付的API文档-alipay.trade.page.pay-请求参数】章节

        //请求
        String form = "";
        try {
            form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        response.setContentType("text/html;charset=" + AlipayConfig.CHARSET);
        response.getWriter().write(form);//直接将完整的表单html输出到页面
        response.getWriter().flush();
        response.getWriter().close();
    }
    @RequestMapping("/")
    public String toTest(){

        return "index";
    }
}

前端优化

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <title>阿里云支付操作</title>
</head>
<body>
<form th:action="@{/pay}" method="post">
    <input type="submit" value="下单"> <input type="reset" value="重置">
</form>
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/386332.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝桥杯-超级质数

蓝桥杯-超级质数1、问题描述2、解题思路3、代码实现1、问题描述 如果一个质数 P 的每位数字都是质数, 而且每两个相邻的数字组成的两位 数是质数, 而且每三位相邻的数字组成的三位数是质数, 依次类推, 如果每相邻的 k 位数字组成的 k 位数都是质数, 则 P 称为超级质数。 如果把…

重型工业机械设备远程监控解决方案

随着企业的发展&#xff0c;各类机械设备日益增多&#xff0c;为了实现高效的管理和使用&#xff0c;保障安全生产&#xff0c;建立智能化、信息化的工业制造系统成为了必然趋势。 传统的机械设备管理大多采用人工方式&#xff0c;现场作业人员需要每天通过电话、或者E-mail等方…

利用反射实现通过读取配置文件对类进行实例化-课后程序(JAVA基础案例教程-黑马程序员编著-第十二章-课后作业)

【案例12-3】&#xff1a;利用反射实现通过读取配置文件对类进行实例化 【案例介绍】 1.案例描述 现在有一个项目&#xff0c;项目中创建了一个Person类&#xff0c;在Person类中定义了一个sleep()方法。在工程中还定义了一个Student类继承Person类&#xff0c;在Student类中…

项目管理PMP证书的含金量真的高吗?

含金量当然高的&#xff0c;特别是在项目管理这个领域&#xff0c;绝对是知名度最高的&#xff0c;行业内最受认可的相关证书&#xff0c;含金量等同于于MBA&#xff0c;那么&#xff0c;除去它本身专业知识价值&#xff0c;它的含金量高在哪里呢&#xff1f; &#xff08;含资…

linux离线状态下将视频mp4格式转换m3u8

因为业务需求&#xff0c;python文件生成的视频为MP4格式&#xff0c;无法在前端浏览器正常播放&#xff0c;需切换m3u8格式&#xff0c;但因为服务器是没有网络的&#xff0c;因袭需要在离线状态下进行完成。 1.离线安装ffmpeg 看网上许多教程&#xff0c;ffmpeg可完成视频格…

【工具】笔记软件测评(简单)

介绍 笔记软件测评 印象笔记 ── ❌开源、❌markdown&#xff08;不好用&#xff09;、❌本地存储 臭名昭著&#xff0c;被资本搞烂的理想。 notion ── ❌开源、❌本地存储、✔️数据导出&#xff1a;PDF、HTML、Markdown & CSV &#xff08;include subpages&#xf…

重回利润增长,涪陵榨菜为何能跑赢周期?

2022年消费市场持续低迷&#xff0c;疫情寒冬之下&#xff0c;不少食品快消企业均遭遇严重的业绩下滑&#xff0c;但一年里不断遭遇利空打击的“榨菜茅”涪陵榨菜&#xff0c;不仅安然躲过“酸菜劫”、走出“钠”争议&#xff0c;而且顺利将产品价格提起来&#xff0c;并在寒冬…

C++基础篇(一)-- 简单入门

C 语言是在优化 C 语言的基础上为支持面向对象的程序设计而研制的一个通用目的的程序设计语言。在后来的持续研究中&#xff0c;C 增加了许多新概念&#xff0c;例如虚函数、重载、继承、标准模板库、异常处理、命名空间等。 C 语言的特点主要表现在两个方面&#xff1a;全面兼…

CSS的背景版块知识

&#x1f60a;博主页面&#xff1a;鱿年年 &#x1f449;博主推荐专栏&#xff1a;《WEB前端》&#x1f448; ​&#x1f493;博主格言&#xff1a;追风赶月莫停留&#xff0c;平芜尽处是春山❤️ 目录 前言 一、背景颜色 二、背景图片 三、背景平铺 四、背景图片位置…

ATTCK v10版本战术介绍—持久化(二)

一、引言在前几期文章中我们介绍了ATT&CK中侦察、资源开发、初始访问、执行战术、持久化战术&#xff08;一&#xff09;知识&#xff0c;本期我们为大家介绍ATT&CK 14项战术中持久化战术&#xff08;二&#xff09;涉及的6项子技术&#xff0c;后续会陆续介绍其他战术…

魔兽世界335 自动加入公会教程

最近遇到新人进游戏不能自动加入公会的问题&#xff0c;论坛找了好久也没有找到解决办法。自己摸索后发现是核心的问题&#xff0c;下面教程开始1.利用GM账号进游戏&#xff0c;分别创建LM、BL角色&#xff0c;利用GM命令创建公会举例 LM角色名字&#xff1a;暴风 BL角色名字&a…

开发手册——一、编程规约_4.OOP规约

这篇文章主要梳理了在java的实际开发过程中的编程规范问题。本篇文章主要借鉴于《阿里巴巴java开发手册终极版》 下面我们一起来看一下吧。 1. 【强制】避免通过一个类的对象引用访问此类的静态变量或静态方法&#xff0c;无谓增加编译器解析成 本&#xff0c;直接用类名来访…

聚观早报 |支付宝与阿里合作推出支付芯;多多视频DAU峰值破1.5亿

今日要闻&#xff1a;支付宝与阿里合作推出支付芯&#xff1b;保时捷中国召回Panamera系列汽车&#xff1b;「多多视频」DAU峰值破1.5亿&#xff1b;苏州立法禁止大数据“杀熟”&#xff1b;特斯拉投资者日首次开幕支付宝与阿里合作推出支付芯 3 月 2 日消息&#xff0c;支付宝…

taobao.item.sku.update( 更新SKU信息 )

&#xffe5;开放平台免费API必须用户授权 *更新一个sku的数据 *需要更新的sku通过属性properties进行匹配查找 *商品的数量和价格必须大于等于0 *sku记录会更新到指定的num_iid对应的商品中 *num_iid对应的商品必须属于当前的会话用户 公共参数 请求地址: HTTP地址 http://gw.…

【C++修炼之路】23.哈希封装unordered系列

每一个不曾起舞的日子都是对生命的辜负 哈希封装unordered系列前言一.封装的迭代器二.改良后的HashTable.h三.封装的UnorderedSet.h四.封装的UnorderedMap.h五.Test.cpp及测试结果前言 unordered_map、unordered_set与map、set的区别是unoedered系列无序&#xff0c;除此之外功…

MD(消息摘要)、MAC(消息认证码)、数字签名的区别

MD(消息摘要&#xff09;、MAC(消息认证码&#xff09;、数字签名的区别 1.MD(消息摘要&#xff09;-散列算法 摘要是哈希值&#xff0c;我们通过散列算法⽐如MD5算法就可以得到这个哈希值。摘要只是⽤于验证数据完整性和唯⼀性的哈希值&#xff0c;不管原始数据是什么样的&a…

【json代码diff效果展示】vue项目 手动实现高仿github的内容diff效果

文章目录1-1 vue-code-diff业务需求 &#xff1a; 思考&#xff1a; 对比两个json字符串&#xff0c;维护增删改的三个数组 遍历&#xff0c;进行三四五次if判断进入不同数组&#xff0c;渲染页面不对呀&#xff0c;数据展示&#xff0c;怎么根据json对应键展示字段呢&#xf…

Linux基础命令-gdisk使用GPT类型创建分区

文章目录 一 命令介绍 二 MBR和GPT的区别 MBR GPT 三 命令语法 四 基本参数 1 常用参数 2 操作菜单说明 五 参考实例 1 对磁盘设备进行分区 2 查看磁盘的所有分区表 命令总结 一 命令介绍 NAME gdisk - Interactive GUID partition table (GPT) manipulato…

VAE--part1

Variational Auto-Encoder, VAE__part1分布变换VAE慢谈VAE 初现分布标准化重参数技巧VAE的本质是什么&#xff1f;VAE的本质结构正态分布&#xff1f;变分在哪里参考博客仅做学习记录&#xff0c;侵删分布变换 VAE和GAN都是生成式模型&#xff0c;它们俩的目标基本一致&#x…

如何在 3dMax 中制作游戏中的战斧模型?

继续给大家分享3dMax教程&#xff1a;如何在3dsMax中制作战斧教程。 介绍 大家好&#xff01;今天想和大家分享的是用3ds Max制作一把战斧&#xff0c;分享一下制作过程中用到的一些技巧和技巧。这是一个比较基础的教程&#xff0c;包括建模、雕刻、pbr贴图。 概念 这把战斧…