折腾:
【未解决】Mac中用vue-admin-template实现智能电力前端页面功能模块
期间,需要去此处vue-admin-template中,实现http的rest的api的post调用
并解析返回的json
就像postman中的:
此处找到,现有的post的http的请求:
src/client/vue-admin-template/src/api/user.js
import request from '@/utils/request' export function login(data) { return request({ url: '/vue-admin-template/user/login', method: 'post', data }) }
用的是/utils/request
src/client/vue-admin-template/src/utils/request.js
import axios from 'axios' import axios from 'axios' import { MessageBox, Message } from 'element-ui' import store from '@/store' import { getToken } from '@/utils/auth' // create an axios instance const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url // withCredentials: true, // send cookies when cross-domain requests timeout: 5000 // request timeout }) ...
用的是axios
src/client/vue-admin-template/src/api/iec104.js
import request from '@/utils/request' export function addIEC104(iec104DataStr) { console.log('iec104DataStr=%s', iec104DataStr) return request({ url: 'http://localhost:8080/iec104/add/', method: 'post', data: { 'data': iec104DataStr } }) }
但是却不知道如何被页面中调用。
看到另外一个table中
src/client/vue-admin-template/src/views/table/index.vue
是:
<script> import { getList } from '@/api/table'
所以也去试试
src/client/vue-admin-template/src/views/form/index.vue
<script> import { addIEC104 } from '@/api/iec104' export default { ... methods: { onSubmit() { console.log('this.form.iec104DataStr=%s', this.form.iec104DataStr) addIEC104(this.form.iec104DataStr).then(response => { console.log('response=%s', response) const { data } = response console.log('data=%s', data) }) this.$message('submit!') },
结果调试报错:
【已解决】vuejs中调用本地localhost的api报错:Access to XMLHttpRequest at from origin has been blocked by CORS policy
不过又出现别的错误了:
去看看什么情况
2020-02-25 20:06:59,290 INFO IEC104Controller.java:47 - post iec104: payload={data={ "data": "68 59 F0 D2 00 00 15 A6 14 00 05 00 01 07 00 02 00 00 00 00 00 CF 5D 96 5D B2 5D 45 00 01 00 FE FF 7C 00 84 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 86 13 00 00 02 00 00 00 00 00 FE FF 00 00 00 00 98 00 00 00 00 00 02 00 00 00 00 00 " }} 2020-02-25 20:06:59,291 INFO IEC104Controller.java:57 - filted104DataStr={ "data":"6859F0D2000015A614000500010700020000000000CF5D965DB25D45000100FEFF7C008402000000000000000000000000000000000000000000000000000086130000020000000000FEFF00000000980000000000020000000000" } 2020-02-25 20:06:59,294 ERROR IEC104Controller.java:62 - IllegalFormatException: error=非法报文。报文应为16进制数字组成,并且由0x68或者0x10为报文头,0x16为报文尾(104规约无)。 非法报文。报文应为16进制数字组成,并且由0x68或者0x10为报文头,0x16为报文尾(104规约无)。 at com.crifan.xxx.analysis.protocol104.Analysis.analysis(Analysis.java:32)
去看看代码
原理是:
后端代码:
src/server/xxx/xxx/src/main/java/com/crifan/xxx/IEC104Controller.java
@PostMapping(path="/add") // Map ONLY POST Requests // public @ResponseBody String addNewIEC104 ( public @ResponseBody IEC104 addNewIEC104 ( // @RequestParam String data // @RequestParam String data, // @RequestParam String parseResult @RequestBody Map<String, Object> payload ) { // @ResponseBody means the returned String is the response, not a view name // @RequestParam means it is a parameter from the GET or POST request logger.info("post iec104: payload={}", payload); String dataStr = (String) payload.get("data"); IEC104 newIec104 = new IEC104(); newIec104.setData(dataStr); // String parseResult = "待解析成结果 to replace parsed result"; String parseResult = ""; String filted104DataStr = dataStr.replaceAll(" ", ""); logger.info("filted104DataStr={}", filted104DataStr); try{ parseResult = Analysis.analysis(filted104DataStr); logger.info("parseResult={}", parseResult);
输出的dataStr,却还是带了data的字符串的:
2020-02-25 20:06:59,290 INFO IEC104Controller.java:47 - post iec104: payload={data={ "data": "68 59 F0 D2 00 00 15 A6 14 00 05 00 01 07 00 02 00 00 00 00 00 CF 5D 96 5D B2 5D 45 00 01 00 FE FF 7C 00 84 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 86 13 00 00 02 00 00 00 00 00 FE FF 00 00 00 00 98 00 00 00 00 00 02 00 00 00 00 00 " }}
所以,回头找vuejs部分,发现是:
src/client/vue-admin-template/src/api/iec104.js
return request({ url: 'http://localhost:8080/iec104/add/', method: 'post', data: { 'data': iec104DataStr } })
看起来是:
此处data中不需要额外加上data的
那去看看request中,此处的data参数,难道不是POST的body吗??
去加上调试log看看
src/client/vue-admin-template/src/utils/request.js
// request interceptor service.interceptors.request.use( config => { // do something before request is sent if (store.getters.token) { // let each request carry token // ['X-Token'] is a custom headers key // please modify it according to the actual situation config.headers['X-Token'] = getToken() } console.log('config=%o', config) return config },
看到object是:
其中有个data
还是很奇怪
axios post data
import axios from 'axios' let data = {"code":"1234","name":"yyyy"}; axios.post(`${this.$url}/test/testRequest`,data) .then(res=>{ console.log('res=>',res); })
对啊,这个data就只是参数名,而不是data字符串本身
// Send a POST request axios({ method: 'post', url: '/user/12345', data: { firstName: 'Fred', lastName: 'Flintstone' } });
对啊,只是post的参数data而已
此处,两边都改为dataStr,看看结果如何
后端:
logger.info("post iec104: payload={}", payload); String dataStr = (String) payload.get("dataStr"); logger.info("dataStr={}", dataStr);
前端测试:
可以看出,的确是多个一个data
难道是此处的vuejs的模板中的requests额外加的?
算了,改为:
export function addIEC104(iec104DataStr) { console.log('iec104DataStr=%s', iec104DataStr) const postData = { 'dataStr': iec104DataStr } return request({ url: 'http://localhost:8080/iec104/add/', method: 'post', // data: { // 'data': iec104DataStr // } postData }) }
结果:
变成400了:
其中可见,data是空的
postData是有值的。
const postData = { 'dataStr': iec104DataStr } return request({ url: 'http://localhost:8080/iec104/add/', method: 'post', data: postData }) }
结果:
data好像
"{"dataStr":"{\n\t\"dataStr\": \"68 59 F0 D2 00 00 15 A6 14 00 05 00 01 07 00 02 00 00 00 00 00 CF 5D 96 5D B2 5D 45 00 01 00 FE FF 7C 00 84 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 86 13 00 00 02 00 00 00 00 00 FE FF 00 00 00 00 98 00 00 00 00 00 02 00 00 00 00 00 \"\n}"}"
多了个回车和换行
但是也还是多了个dataStr的外层包裹
-》很是奇怪。
然后才明白:
是此处自己搞错了:
自己的vuejs的前端,自己额外输入的是带key的字符串:
{ "dataStr": "68 59 F0 D2 00 00 15 A6 14 00 05 00 01 07 00 02 00 00 00 00 00 CF 5D 96 5D B2 5D 45 00 01 00 FE FF 7C 00 84 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 86 13 00 00 02 00 00 00 00 00 FE FF 00 00 00 00 98 00 00 00 00 00 02 00 00 00 00 00 " }
去掉后:
68 59 F0 D2 00 00 15 A6 14 00 05 00 01 07 00 02 00 00 00 00 00 CF 5D 96 5D B2 5D 45 00 01 00 FE FF 7C 00 84 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 86 13 00 00 02 00 00 00 00 00 FE FF 00 00 00 00 98 00 00 00 00 00 02 00 00 00 00 00
应该就可以了。
data是dataStr的json了。
但是还是报错
不过看server端,是正常解析了:
看来是前端返回的值的处理的问题。
去看代码
src/client/vue-admin-template/src/utils/request.js
// response interceptor service.interceptors.response.use( /** * If you want to get http information such as headers or status * Please return response => response */ /** * Determine the request status by custom code * Here is just an example * You can also judge the status by HTTP Status Code */ response => { const res = response.data ...
所以此处可以根据提示
// response interceptor service.interceptors.response.use( /** * If you want to get http information such as headers or status * Please return response => response */ response => response, /** * Determine the request status by custom code * Here is just an example * You can also judge the status by HTTP Status Code */ // response => { // const res = response.data // // if the custom code is not 20000, it is judged as an error. // if (res.code !== 20000) { // Message({ // message: res.message || 'Error', // type: 'error', // duration: 5 * 1000 // }) // // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired; // if (res.code === 50008 || res.code === 50012 || res.code === 50014) { // // to re-login // MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', { // confirmButtonText: 'Re-Login', // cancelButtonText: 'Cancel', // type: 'warning' // }).then(() => { // store.dispatch('user/resetToken').then(() => { // location.reload() // }) // }) // } // return Promise.reject(new Error(res.message || 'Error')) // } else { // return res // } // }, error => { console.log('err' + error) // for debug Message({ message: error.message, type: 'error', duration: 5 * 1000 }) return Promise.reject(error) } )
或者进一步的:
// response => response, response => { console.log('response=%o', response) return response },
去调试看看
至少不报错了。
再去写代码解析返回的结果:
onSubmit() { console.log('this.form.iec104DataStr=%s', this.form.iec104DataStr) addIEC104(this.form.iec104DataStr).then(response => { console.log('response=%o', response) const { data } = response console.log('data=%o', data) const parseResult = data.parseResult console.log('parseResult=%s', parseResult) this.form.respJson = data })
已经可以返回:
但是最后会报错:
很明显是:
this.form.respJson = data
赋值是不对的。
所以去:
【已解决】vuejs中把json对象转换为json字符串且格式化带缩进
【总结】
最后用代码:
后端server:
src/server/xxx/xxx/src/main/java/com/crifan/xxx/IEC104Controller.java
... import org.springframework.web.bind.annotation.CrossOrigin; ... @Controller // This means that this class is a Controller @CrossOrigin @RequestMapping(path="/iec104") // This means URL's start with / (after Application path) public class IEC104Controller { private static Logger logger = LoggerFactory.getLogger(IEC104Controller.class.getName()); @Autowired // This means to get the bean called userRepository // Which is auto-generated by Spring, we will use it to handle the data private IEC104Repository iec104Repository; @PostMapping(path="/add") // Map ONLY POST Requests // public @ResponseBody String addNewIEC104 ( public @ResponseBody IEC104 addNewIEC104 ( // @RequestParam String data // @RequestParam String data, // @RequestParam String parseResult @RequestBody Map<String, Object> payload ) { // @ResponseBody means the returned String is the response, not a view name // @RequestParam means it is a parameter from the GET or POST request logger.info("post iec104: payload={}", payload); String dataStr = (String) payload.get("dataStr"); logger.info("dataStr={}", dataStr); IEC104 newIec104 = new IEC104(); newIec104.setData(dataStr); ...
前端vuejs:
src/client/vue-admin-template/src/api/iec104.js
import request from '@/utils/request' export function addIEC104(iec104DataStr) { console.log('iec104DataStr=%s', iec104DataStr) const postData = { 'dataStr': iec104DataStr } return request({ url: 'http://localhost:8080/iec104/add/', method: 'post', data: postData }) }
src/client/vue-admin-template/src/utils/request.js
// response interceptor service.interceptors.response.use( /** * If you want to get http information such as headers or status * Please return response => response */ // response => response, response => { console.log('response=%o', response) return response }, /** * Determine the request status by custom code * Here is just an example * You can also judge the status by HTTP Status Code */ // response => { // const res = response.data // // if the custom code is not 20000, it is judged as an error. // if (res.code !== 20000) { // Message({ // message: res.message || 'Error', // type: 'error', // duration: 5 * 1000 // }) // // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired; // if (res.code === 50008 || res.code === 50012 || res.code === 50014) { // // to re-login // MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', { // confirmButtonText: 'Re-Login', // cancelButtonText: 'Cancel', // type: 'warning' // }).then(() => { // store.dispatch('user/resetToken').then(() => { // location.reload() // }) // }) // } // return Promise.reject(new Error(res.message || 'Error')) // } else { // return res // } // }, error => { console.log('err' + error) // for debug Message({ message: error.message, type: 'error', duration: 5 * 1000 }) return Promise.reject(error) } )
src/client/vue-admin-template/src/views/form/index.vue
<template> <div class="app-container"> <el-form ref="form" :model="form" label-width="120px"> <!-- <el-form-item label="Activity name"> <el-input v-model="form.name" /> </el-form-item> <el-form-item label="Activity zone"> <el-select v-model="form.region" placeholder="please select your zone"> <el-option label="Zone one" value="shanghai" /> <el-option label="Zone two" value="beijing" /> </el-select> </el-form-item> <el-form-item label="Activity time"> <el-col :span="11"> <el-date-picker v-model="form.date1" type="date" placeholder="Pick a date" style="width: 100%;" /> </el-col> <el-col :span="2" class="line">-</el-col> <el-col :span="11"> <el-time-picker v-model="form.date2" type="fixed-time" placeholder="Pick a time" style="width: 100%;" /> </el-col> </el-form-item> <el-form-item label="Instant delivery"> <el-switch v-model="form.delivery" /> </el-form-item> <el-form-item label="Activity type"> <el-checkbox-group v-model="form.type"> <el-checkbox label="Online activities" name="type" /> <el-checkbox label="Promotion activities" name="type" /> <el-checkbox label="Offline activities" name="type" /> <el-checkbox label="Simple brand exposure" name="type" /> </el-checkbox-group> </el-form-item> <el-form-item label="Resources"> <el-radio-group v-model="form.resource"> <el-radio label="Sponsor" /> <el-radio label="Venue" /> </el-radio-group> </el-form-item> --> <el-form-item label="IEC 104数据"> <el-input v-model="form.iec104DataStr" autosize type="textarea" /> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit">新增数据并解析</el-button> <el-button @click="onClear">清空</el-button> </el-form-item> <el-form-item label="返回结果"> <el-input v-model="form.respJson" autosize type="textarea" /> </el-form-item> </el-form> </div> </template> <script> import { addIEC104 } from '@/api/iec104' import { Message } from 'element-ui' export default { data() { return { form: { // name: '', // region: '', // date1: '', // date2: '', // delivery: false, // type: [], // resource: '', iec104DataStr: '', respJson: '' } } }, methods: { onSubmit() { console.log('this.form.iec104DataStr=%s', this.form.iec104DataStr) addIEC104(this.form.iec104DataStr).then(response => { console.log('response=%o', response) const { data } = response console.log('data=%o', data) const parseResult = data.parseResult console.log('parseResult=%s', parseResult) // this.form.respJson = JSON.stringify(data, null, 2) this.form.respJson = parseResult }) Message({ message: '已提交', type: 'info', duration: 1.5 * 1000 }) // this.$message('已提交!') }, onClear() { this.form.iec104DataStr = '' this.form.respJson = '' // this.$message({ // message: '已清除!', // type: 'warning' // }) Message({ message: '已清除', type: 'warning', duration: 1.5 * 1000 }) } } } </script> <style scoped> .line{ text-align: center; } </style>
即可实现:
页面中输入:
68 59 F0 D2 00 00 15 A6 14 00 05 00 01 07 00 02 00 00 00 00 00 CF 5D 96 5D B2 5D 45 00 01 00 FE FF 7C 00 84 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 86 13 00 00 02 00 00 00 00 00 FE FF 00 00 00 00 98 00 00 00 00 00 02 00 00 00 00 00
然后点击按钮,正常发送到后端,后端解析返回结果,呈现到对应输入框内:
转载请注明:在路上 » 【已解决】vue-admin-template中如何用vuejs去发送REST的api的POST请求并返回和解析json字符串