springboot+vue项目接入文心一言API

springboot+vue项目接入文心一言API

    正在检查是否收录...

参考文心一言ERNIE-Bot 4.0模型流式和非流式API调用(SpringBoot+OkHttp3+SSE+WebSocket) - autunomy - 博客园 (cnblogs.com)

后端

引入依赖
<dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>4.9.3</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.79</version> </dependency>
配置okHttp,创建OkHttpConfiguration.java
import okhttp3.ConnectionPool; import okhttp3.OkHttpClient; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.net.ssl.*; import java.security.*; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.concurrent.TimeUnit; @Configuration public class OkHttpConfiguration { @Value("${ok.http.connect-timeout}") private Integer connectTimeout; @Value("${ok.http.read-timeout}") private Integer readTimeout; @Value("${ok.http.write-timeout}") private Integer writeTimeout; @Value("${ok.http.max-idle-connections}") private Integer maxIdleConnections; @Value("${ok.http.keep-alive-duration}") private Long keepAliveDuration; @Bean public OkHttpClient okHttpClient() { return new OkHttpClient.Builder() .sslSocketFactory(sslSocketFactory(), x509TrustManager()) // 是否开启缓存 .retryOnConnectionFailure(false) .connectionPool(pool()) .connectTimeout(connectTimeout, TimeUnit.SECONDS) .readTimeout(readTimeout, TimeUnit.SECONDS) .writeTimeout(writeTimeout,TimeUnit.SECONDS) .hostnameVerifier((hostname, session) -> true) // 设置代理 // .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8888))) // 拦截器 // .addInterceptor() .build(); } @Bean public X509TrustManager x509TrustManager() { return new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }; } @Bean public SSLSocketFactory sslSocketFactory() { try { // 信任任何链接 SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom()); return sslContext.getSocketFactory(); } catch (NoSuchAlgorithmException | KeyManagementException e) { e.printStackTrace(); } return null; } @Bean public ConnectionPool pool() { return new ConnectionPool(maxIdleConnections, keepAliveDuration, TimeUnit.SECONDS); } }
配置全局变量,创建WenXinConfig.java
package com.pet.common; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import okhttp3.*; import okhttp3.MediaType; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import java.io.IOException; import java.util.Date; @Configuration @Slf4j public class WenXinConfig { @Value("${wenxin.apiKey}") public String API_KEY; @Value("${wenxin.secretKey}") public String SECRET_KEY; @Value("${wenxin.accessTokenUrl}") public String ACCESS_TOKEN_URL; @Value("${wenxin.ERNIE_Bot.URL}") public String ERNIE_Bot_4_0_URL; //过期时间为30天 public String ACCESS_TOKEN = null; public String REFRESH_TOKEN = null; public Date CREATE_TIME = null;//accessToken创建时间 public Date EXPIRATION_TIME = null;//accessToken到期时间 /** * 获取accessToken * @return true表示成功 false表示失败 */ public synchronized String flushAccessToken(){ //判断当前AccessToken是否为空且判断是否过期 if(ACCESS_TOKEN != null && EXPIRATION_TIME.getTime() > CREATE_TIME.getTime()) return ACCESS_TOKEN; //构造请求体 包含请求参数和请求头等信息 RequestBody body = RequestBody.create(MediaType.parse("application/json"),""); Request request = new Request.Builder() .url(ACCESS_TOKEN_URL+"?client_id="+API_KEY+"&client_secret="+SECRET_KEY+"&grant_type=client_credentials") .method("POST", body) .addHeader("Content-Type", "application/json") .addHeader("Accept", "application/json") .build(); OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build(); String response = null; try { //请求 response = HTTP_CLIENT.newCall(request).execute().body().string(); } catch (IOException e) { log.error("ACCESS_TOKEN获取失败"); return null; } //刷新令牌以及更新令牌创建时间和过期时间 JSONObject jsonObject = JSON.parseObject(response); ACCESS_TOKEN = jsonObject.getString("access_token"); REFRESH_TOKEN = jsonObject.getString("refresh_token"); CREATE_TIME = new Date(); EXPIRATION_TIME = new Date(Long.parseLong(jsonObject.getString("expires_in")) + CREATE_TIME.getTime()); return ACCESS_TOKEN; } } 
配置application.yml
okhttp: connect-timeout: 30 # 连接超时时间,单位通常为秒 read-timeout: 30 # 读取超时时间,单位通常为秒 write-timeout: 30 # 写入超时时间,单位通常为秒 max-idle-connections: 200 # 连接池中整体的空闲连接的最大数量 keep-alive-duration: 300 # 连接空闲时间最多为多少秒 wenxin: apiKey: #你的apikey secretKey: #你的secretkey accessTokenUrl: https://aip.baidubce.com/oauth/2.0/token ERNIE_Bot: URL: https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/ernie-lite-8k#改成你用的 
创建TestController.java
package com.pet.controller; import com.alibaba.fastjson.JSON; import com.pet.common.WenXinConfig; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import okhttp3.*; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @RestController @Slf4j @RequestMapping("/test") public class TestController { @Resource private WenXinConfig wenXinConfig; //历史对话,需要按照user,assistant List<Map<String,String>> messages = new ArrayList<>(); /** * 非流式问答 * @param question 用户的问题 * @return * @throws IOException */ @PostMapping("/ask") public String test1(String question) throws IOException { if(question == null || question.equals("")){ return "请输入问题"; } String responseJson = null; //先获取令牌然后才能访问api if (wenXinConfig.flushAccessToken() != null) { HashMap<String, String> user = new HashMap<>(); user.put("role","user"); user.put("content",question); messages.add(user); String requestJson = constructRequestJson(1,0.95,0.8,1.0,false,messages); RequestBody body = RequestBody.create(MediaType.parse("application/json"), requestJson); Request request = new Request.Builder() .url(wenXinConfig.ERNIE_Bot_4_0_URL + "?access_token=" + wenXinConfig.flushAccessToken()) .method("POST", body) .addHeader("Content-Type", "application/json") .build(); OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build(); try { responseJson = HTTP_CLIENT.newCall(request).execute().body().string(); //将回复的内容转为一个JSONObject JSONObject responseObject = JSON.parseObject(responseJson); //将回复的内容添加到消息中 HashMap<String, String> assistant = new HashMap<>(); assistant.put("role","assistant"); assistant.put("content",responseObject.getString("result")); messages.add(assistant); } catch (IOException e) { log.error("网络有问题"); return "网络有问题,请稍后重试"; } } return responseJson; } /** * 构造请求的请求参数 * @param userId * @param temperature * @param topP * @param penaltyScore * @param messages * @return */ public String constructRequestJson(Integer userId, Double temperature, Double topP, Double penaltyScore, boolean stream, List<Map<String, String>> messages) { Map<String,Object> request = new HashMap<>(); request.put("user_id",userId.toString()); request.put("temperature",temperature); request.put("top_p",topP); request.put("penalty_score",penaltyScore); request.put("stream",stream); request.put("messages",messages); System.out.println(JSON.toJSONString(request)); return JSON.toJSONString(request); } } 
postman测试

前端  创建advice.vue (使用了elment-ui)

<template> <div class="container"> <div class="input-group"> <input type="text" v-model="question" placeholder="请输入您的需求" class="input-field"> <el-button @click="ask" type="ptimary">获取建议</el-button> <el-button @click="reset" type="success">重置</el-button> </div> <div class="input-group"> <div>建议: </div> <el-input type="textarea" :autosize="{ minRows: 4, maxRows: 8}" v-model="answer" v-loading="loading"> </el-input> </div> </div> </template> <script> export default { name: 'Advice', data() { return { question: '', answer: '', loading: false } }, methods: { ask() { if(this.question === '') { this.$message('请输入需求'); }else{ this.loading = true this.$axios.post(this.$httpUrl + '/test/ask?question=' + this.question).then(res => { this.answer = res.data.result; this.loading = false }).catch(error => { console.error('Error', error); }); } }, reset(){ this.question="" this.answer="" this.loading=false } } } </script> <style scoped> body { font-family: Arial, sans-serif; margin: 0; padding: 0; background-color: #f7f7f7; } .container { max-width: 600px; margin: 100px auto; padding: 20px; /* background-color: #fff;*/ border-radius: 5px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); } .input-group { display: flex; align-items: center; margin-bottom: 20px; } .input-group input[type="text"] { flex: 1; padding: 10px; border: 1px solid #ccc; border-radius: 3px; font-size: 16px; transition: border-color 0.3s ease; resize: both; /* Allows resizing */ } .input-group input[type="text2"] { flex: 1; padding: 10px; border: 1px solid #ccc; border-radius: 3px; font-size: 16px; transition: border-color 0.3s ease; resize: both; /* Allows resizing */ } .input-group button { padding: 10px 20px; border: none; border-radius: 3px; cursor: pointer; font-size: 16px; transition: background-color 0.3s ease; margin-left: 5px; } .suggestion { margin-top: 30px; /* Increase top margin */ padding: 20px; /* Increase padding */ border: 1px solid #ccc; border-radius: 5px; font-size: 20px; } </style> 

jsontokenclijavaurlappbotsocapictocreateassistantivaunitetfparseseowebproxyira
  • 本文作者:李琛
  • 本文链接: https://wapzz.net/post-16615.html
  • 版权声明:本博客所有文章除特别声明外,均默认采用 CC BY-NC-SA 4.0 许可协议。
本站部分内容来源于网络转载,仅供学习交流使用。如涉及版权问题,请及时联系我们,我们将第一时间处理。
文章很赞!支持一下吧 还没有人为TA充电
为TA充电
还没有人为TA充电
0
  • 支付宝打赏
    支付宝扫一扫
  • 微信打赏
    微信扫一扫
感谢支持
文章很赞!支持一下吧
关于作者
2.3W+
5
0
1
WAP站长官方

活久见!谁想的这种办法让大模型PK

上一篇

赵明:苹果进军AI走了荣耀定义的路 领先三年

下一篇
  • 复制图片
按住ctrl可打开默认菜单