vue使用axios发送http请求后端springBoot @RequestParam接收不到,解决办法

本文详细记录了一位开发者在使用Vue.js前端框架与SpringBoot后端框架进行跨域HTTP请求时遇到的问题及解决过程。通过调整Content-Type为application/x-www-form-urlencoded并使用URLSearchParams对参数进行封装,成功解决了@RequestParam参数无法被后端接收到的难题。

最近在项目中使用vue.js进行前端开发,刚刚接触vue一路磕磕绊绊遇到了很多问题,在这里记录下解决办法。

 这是我们系统中前端的一个axios发送http请求的部分代码片段,向后台发送http请求,后端springBoot始终接收不到

@RequestParam的参数,看下面:

// 封装axios
const http =axios.create({
  timeout: 1000 * 30,
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json; charset=utf-8'
  }
})

// 发送post请求
this.$http({
    url: 'http://localhost:8080/bindT/1'),
    method: 'post',
    data: {
        ids : ['1','2','3']
    }
}).then(({data}) => {
    if (data && data.code === 0) {
        this.$message({
            message: '操作成功',
            type: 'success',
            duration: 1500
        })
    } else {
        this.$message.error(data.msg)
    }
})
@RequestMapping("/bindT/{type}")
public R bindT(@PathVariable("type") String type, @RequestParam List<String> ids) {
    System.out.println("ids:" + ids.toString());
    return R.ok();
}
2020-07-09 15:15:10.422 ERROR 13316 --- [io-8097-exec-24] c.b.s.c.exception.RRExceptionHandler : 
Required List parameter 'ids' is not present
org.springframework.web.bind.MissingServletRequestParameterException: Required List parameter 'ids' is not present
	at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:204)
	at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:112)
	at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:124)

在网上也找了好多办法都没有解决,如:修改data里面的内容使用dataForm封装、修改headers等等。最终找到一个解决办法:修改headers信息使用

'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'

并且对参数进行

 URLSearchParams()

封装处理。

效果参考下面:

// 封装axios
const http =axios.create({
  timeout: 1000 * 30,
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json; charset=utf-8'
  }
})

// 对参数进行封装
let searchParams = new URLSearchParams()
searchParams.set('ids', ['1','2','3'])

//发送post请求
this.$http({
    url: 'http://localhost:8080/bindT/1'),
    headers: { //修改头信息,因为只有该处使用,所以不修改全局配置
        'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
    },
    method: 'post',
    data: searchParams
}).then(({data}) => {
    if (data && data.code === 0) {
        this.$message({
            message: '操作成功',
            type: 'success',
            duration: 1500
        })
    } else {
        this.$message.error(data.msg)
    }
})

 后端就可以正常接收了

ids:[1,2,3]
<think>好的,我现在需要解决用户的问题:使用Vue3、Axios、Spring Boot和MyBatis实现登录后显示用户名的功能。首先,我得理清楚前后端的交互流程,以及每个部分需要做什么。 用户提到了登录成功后显示用户名,这通常涉及前端发送登录请求后端验证用户信息,返回成功状态和用户数据,前端存储用户信息(比如用户名),然后在页面上显示出来。根据用户提供的引用内容,特别是引用[3]中的登录功能实现,后端Controller处理登录请求,检查数据库中的用户是否存在。不过引用[3]返回的是简单的字符串,而这里需要返回更多数据,比如用户名,以便前端显示。 首先,后端的部分可能需要调整。原来的登录接口返回的是"success"或者错误信息,但为了前端能获取用户名,应该返回一个包含用户信息的JSON对象,比如包含用户名。因此,需要修改Controller层的返回值,使用@ResponseBody或者@RestController来返回JSON数据。 然后,数据库查询部分,可能需要不仅仅检查用户是否存在,还要获取用户名。在MyBatis的Mapper中,查询语句应该返回用户对象,包含id、name等字段。这样Service层可以获取用户信息并返回给Controller。 前端方面,Vue3中使用Axios发送POST请求到登录接口,处理响应结果。如果登录成功,需要将用户名保存到前端的存储中,比如Vuex或者Pinia状态管理,或者本地存储(localStorage/sessionStorage),然后在页面中显示出来。例如,在导航栏或欢迎页面显示“欢迎,用户名”。 接下来,考虑各个层级的代码结构: 后端: 1. 数据库:用户表需要有username和password字段,可能还有id。 2. MyBatis Mapper:编写根据用户名和密码查询用户的方法,返回用户对象。 3. Service层:调用Mapper,如果查询到用户,则返回用户信息;否则返回null或抛出异常。 4. Controller层:接收前端传来的用户名和密码,调用Service,返回包含状态码、消息和用户数据的JSON。 前端: 1. 登录表单:使用Vue3的响应式数据绑定用户名和密码。 2. Axios请求发送登录请求后端,携带表单数据。 3. 处理响应:成功时存储用户信息,跳转到主页或其他页面,显示用户名。 4. 状态管理:可能需要使用Pinia或Composition API来管理用户状态,以便在不同组件中访问用户名。 还需要考虑跨域问题,确保前端Vue3应用和后端Spring Boot服务能够通信,可能需要在后端配置CORS。 根据引用[2]中的Axios示例,前端在methods中定义登录方法发送请求,并在响应处理中获取数据。例如,在Vue3的setup函数中使用axios.post,然后存储返回的用户名。 关于安全性,密码不应该明文传输,应该使用HTTPS,后端应对密码进行加密存储,比如使用BCrypt加密,但用户的问题可能暂时不涉及这些细节,所以示例代码可能简化处理。 可能的代码步骤: 后端: - 创建User实体类,包含id、username、password等字段。 - UserMapper接口,定义selectByUsernameAndPassword方法。 - UserService调用Mapper,返回User对象。 - LoginController处理/login请求,返回JSON,如{code: 200, message: "success", data: {username: "张三"}}。 前端: - 使用Vue3的ref绑定表单输入。 - 登录函数中,axios.post发送用户名和密码。 - 响应成功后,将用户名保存到localStorage或Pinia store。 - 在主页组件中读取存储的用户名并显示。 现在需要检查各个引用中的内容是否有帮助。引用[3]的Controller返回字符串,需要调整为返回JSON。引用[2]中的Axios示例是Vue2的,需要调整为Vue3的语法,比如使用composition API。 另外,用户提到Vue3,所以可能需要使用<script setup>语法,以及reactive或ref来管理状态。例如,使用reactive来保存用户信息,登录成功后更新状态,并在模板中显示。 最后,确保前后端数据格式一致,比如登录请求的参数是JSON还是表单数据,后端Controller的参数接收方式是否正确。例如,使用@RequestParam或者@RequestBody来处理前端传递的数据。 可能遇到的问题包括跨域配置Axios请求配置(如Content-Type),以及后端是否正确处理请求。需要测试接口,确保返回正确的数据格式。</think>### 解决方案:Vue3 + Axios + SpringBoot + MyBatis 登录后显示用户名 #### 一、后端实现(SpringBoot + MyBatis) 1. **数据库表结构** ```sql CREATE TABLE t_user ( id INT PRIMARY KEY, username VARCHAR(50), password VARCHAR(50) ); INSERT INTO t_user VALUES (1, '张三', '123456'); ``` 2. **实体类** ```java // User.java @Data public class User { private Integer id; private String username; private String password; } ``` 3. **Mapper接口** ```java // UserMapper.java @Mapper public interface UserMapper { @Select("SELECT * FROM t_user WHERE username=#{username} AND password=#{password}") User selectByLogin(@Param("username") String username, @Param("password") String password); } ``` 4. **Controller层** ```java // LoginController.java @RestController public class LoginController { @Autowired private UserMapper userMapper; @PostMapping("/login") public Map<String, Object> login(@RequestBody Map<String, String> params) { User user = userMapper.selectByLogin(params.get("username"), params.get("password")); if (user != null) { return Map.of("code", 200, "data", user.getUsername(), "msg", "登录成功"); } return Map.of("code", 401, "msg", "账号或密码错误"); } } ``` #### 二、前端实现(Vue3 + Axios) 1. **登录组件(Login.vue)** ```vue <script setup> import { ref } from 'vue'; import axios from 'axios'; import { useRouter } from 'vue-router'; const formData = ref({ username: '', password: '' }); const router = useRouter(); const handleLogin = async () => { try { const response = await axios.post('http://localhost:8080/login', formData.value); if (response.data.code === 200) { localStorage.setItem('username', response.data.data); router.push('/dashboard'); } } catch (error) { console.error('登录失败:', error); } }; </script> <template> <form @submit.prevent="handleLogin"> <input v-model="formData.username" placeholder="用户名"> <input v-model="formData.password" type="password" placeholder="密码"> <button type="submit">登录</button> </form> </template> ``` 2. **主页组件(Dashboard.vue)** ```vue <script setup> import { ref } from 'vue'; const username = ref(localStorage.getItem('username') || ''); </script> <template> <h1>欢迎回来,{{ username }}</h1> </template> ``` #### 三、关键配置 1. **跨域配置SpringBoot)** ```java // WebConfig.java @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:5173") // Vue3 默认端口 .allowedMethods("*"); } } ``` 2. **Axios全局配置(main.js)** ```javascript import { createApp } from 'vue' import App from './App.vue' import axios from 'axios' const app = createApp(App) app.config.globalProperties.$axios = axios.create({ baseURL: 'http://localhost:8080', timeout: 5000 }) app.mount('#app') ``` #### 四、流程说明 1. 用户提交登录表单时,前端通过`axios.post`发送请求到`/login`接口 2. 后端验证通过后返回用户名数据(示例中存储到`localStorage`) 3. 页面跳转至仪表盘页面,通过`localStorage.getItem`读取用户名并显示[^3][^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值