SpringMVC接收请求参数和页面传参

本文深入解析了Spring MVC控制器中的关键方法和参数处理,包括如何通过HttpServletRequest获取请求参数,使用注解如@ModelAttribute自动注入Bean属性,以及如何向JSP页面传值。此外,文章还介绍了使用ModelAndView、ModelMap进行数据传递,并详细说明了Model数据如何通过HttpServletRequest的Attribute传值到视图页面。同时,文章提供了关于Session存储、数据绑定、转发与重定向的操作示例,以及SpringMVC中复杂的对象、数组等数据绑定的全面示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

查看原文:http://www.ibloger.net/article/279.html

1,使用HttpServletRequest获取

@RequestMapping("/login.do")  
public String login(HttpServletRequest request){  
    String name = request.getParameter("name")  
    String pass = request.getParameter("pass")  
}  

2,Spring会自动将表单参数注入到方法参数,和表单的name属性保持一致。和Struts2一样

@RequestMapping("/login.do")  
public String login(HttpServletRequest request, String name,  
@RequestParam("pass")String password) // 表单属性是pass,用变量password接收  
{  
   syso(name);  
   syso(password)  
}  

3,自动注入Bean属性

<form action="login.do">  
用户名:<input name="name"/>  
  密码:<input name="pass"/>  
<input type="submit" value="登陆">  
</form>  

//封装的User类  
public class User{  
  private String name;  
  private String pass;  
}  

@RequestMapping("/login.do")  
public String login(User user) {  
   syso(user.getName());  
   syso(user.getPass());  
}  

向页面传值:
当Controller组件处理后,向jsp页面传值,
1,使用HttpServletRequest 和 Session 然后setAttribute(),就和Servlet中一样
2,使用ModelAndView对象
3,使用ModelMap对象
4,使用@ModelAttribute注解

Model数据会利用HttpServletRequest的Attribute传值到success.jsp中

@RequestMapping("/login.do")  
public ModelAndView  login(String name,String pass){  
    User user = userService.login(name,pwd);  
    Map<String,Object> data = new HashMap<String,Object>();  
    data.put("user",user);  
    return new ModelAndView("success",data);  
}  

使用ModelMap参数对象示例:
ModelMap数据会利用HttpServletRequest的Attribute传值到success.jsp中

@RequestMapping("/login.do")  
public String login(String name,String pass ,ModelMap model){  
    User user  = userService.login(name,pwd);  
    model.addAttribute("user",user);  
    model.put("name",name);  
    return "success";  
} 

ModelMap对象的 addAttribute,put两个方法有什么区别?
ModelMap是继承自LinkedHashMap的,则put方法是继承自 HashMap的方法,没什么特殊的
而addAttribute方法的定义
public ModelMap addAttribute(String attributeName,Object attributeValue){
Assert.notNull(attributeName, "Model attribute name must not be null");
     put(attributeName, attributeValue);
     return this;
}
其实也是调用的put方法,但是会在调用之前判断 key值是否为null,如果为null则会报错java.lang.IllegalArgumentException: Model attribute name must not be null,而put方法不会检查key值是否会空
综上,则
ModelMap对象的addAttribute,put两个方法有什么区别就是 addAttribute是不允许添加空值的key,put是允许的

使用@ModelAttribute示例
在Controller方法的参数部分或Bean属性方法上使用
@ModelAttribute数据会利用HttpServletRequest的Attribute传值到success.jsp中

@RequestMapping("/login.do")  
public String login(@ModelAttribute("user") User user){  
    //TODO  
   return "success";  
}  

@ModelAttribute("name")  
public String getName(){  
    return name;  
}  

Session存储:
可以利用HttpServletReequest的getSession()方法

@RequestMapping("/login.do")  
public String login(String name,String pwd  
                            ModelMap model,HttpServletRequest request){  
     User user = serService.login(name,pwd);  
     HttpSession session = request.getSession();  
     session.setAttribute("user",user);  
     model.addAttribute("user",user);  
     return "success";  
}  

Spring MVC 默认采用的是转发来定位视图,如果要使用重定向,可以如下操作
1,使用RedirectView
2,使用redirect:前缀

public ModelAndView login(){  
   RedirectView view = new RedirectView("regirst.do");  
   return new ModelAndView(view);  
}  

或者用如下方法,工作中常用的方法:

public String login(){  
    //TODO  
    return "redirect:regirst.do";  
}  

SpringMVC数据绑定全面示例(复杂对象,数组等)

/**
 * 最简的配置,不是用@RequestParam,效果和get2一样,默认required=false
 * 请求方式不限
 * @param p1
 * @param map
 */
@RequestMapping(value="get0")
public void get0(String p1,ModelMap map){
    map.addAttribute("p1", p1);//往页面传递
}

/**
 * value="p1"表示参数名称<br>
 * required=true表示如果没有传递参数"p1",则会报400参数异常<br>
 * 使用void表示约定的路径,即request/get1.jsp
 * @param p1
 * @param map
 */
@RequestMapping(value="get1",method=RequestMethod.GET)
public void get1(@RequestParam(value="p1",required=true)String p1,ModelMap map){
    map.addAttribute("p1", p1);//往页面传递
}

/**
 * 和get1不同的是,p1这个参数不一定非得需要,即使不给这个参数,也可以正常运行<br>
 * 返回String是视图的名称,只要将map赋值,给的值也会带到前抬
 * @param p1
 * @param map
 * @return
 */
@RequestMapping(value="get2",method=RequestMethod.GET)
public String get2(@RequestParam(value="p1",required=false)String p1,ModelMap map){
    map.addAttribute("p1", p1);//往页面传递
    return "request/get2";
}

/**
 * 和get2不同的是,返回的对象是ModelAndView
 * 表示绑定了视图和数据的对象,数据就是ModelMap中的Key-Value
 * @param p1
 * @param map
 * @return
 */
@RequestMapping(value="get3",method=RequestMethod.GET)
public ModelAndView get3(@RequestParam(value="p1",required=false)String p1,ModelMap map){
    map.addAttribute("p1", p1);
    return new ModelAndView("request/get2",map);
}

/**
 * 跳转到页面
 * @throws NoSuchAlgorithmException 
 */
@RequestMapping("userForm")
public String userForm(HttpServletResponse response) throws NoSuchAlgorithmException{
    CookieUtils.writeCookie(response, -1, "x", "dddddddddddddd");
    return "request/userForm";
}

/**
 * 绑定数据到User对象,支持Map,Set,List,Array等,但是需要使用下标,不是很灵活
 * 请查看user2的写法
 * @param user
 * @param map
 */
@RequestMapping(value="user")
public void user(User user,ModelMap map){
    map.addAttribute("user", user);
}

/**
 * 这里可以接受List,Array,Set等,写法是一样的,注意前端写法<br>
 * 另外这个必须要使用MappingJacksonHttpMessageConverter这个消息转换器
 * 请看我上面的配置
 * @param user
 * @return
 */
@ResponseBody
@RequestMapping("user2")
public String user2(@RequestBody List<User> user){
    System.out.println(user.size());
    return "";
}

/**
 * 这个方法只支持POST
 * @param s
 * @return
 */
@ResponseBody
@RequestMapping("array")
public String array(@RequestBody String[] s){
    System.out.println(s.length);
    return "";
}

/**
 * SpringMVC也是支持这种写法
 * @param id
 * @return
 */
@ResponseBody
@RequestMapping(value="array/{id}",method=RequestMethod.GET)
public String array2(@PathVariable("id")Long[] id){
    System.out.println(id.length);
    return "array length:"+id.length+"";
}

/**
 * 一个表单对应多个Bean对象,这些Bean中有相同的属性,那么需要在分装他们的一个整体的对象
 * 使之支持object.property的表达式
 * @param c
 */
@ResponseBody
@RequestMapping("complex")
public void complexObject(C c){
    System.out.println(c.getA().getX());
    System.out.println(c.getB().getX());
}

/**
 * 读取Cookie的值
 * @param x
 * @return
 */
@ResponseBody
@RequestMapping("cookie")
public String cookie(@CookieValue("x")String x){
    return x;
}
<think>好的,用户现在遇到了在Spring MVC框架下,当请求参数中包含“20%”时,参数获取不到的问题。首先,我需要分析这个问题的可能原因。 用户之前询问过Spring MVC参数解析机制,现在的问题可能是参数解析过程中的编码问题导致的。比如,当参数值含有特殊字符如百分号时,如果没有正确编码解码,服务器可能无法正确解析。 首先,可能的原因之一是URL编码问题。用户在发送请求时,如果参数值包含特殊字符如%,需要确保客户端在发送前对参数进行正确的URL编码。例如,%在URL编码中是%25,如果客户端没有正确编码,服务器在解析时可能截断或错误解析参数。 接下来,服务器端的解码设置是否正确。Spring MVC默认使用的是容器的解码方式,比如Tomcat的URIEncoding设置。如果容器的解码字符集与客户端发送的编码不一致,可能导致解码错误。例如,Tomcat默认的URI解码字符集是ISO-8859-1,而如果客户端使用的是UTF-8,就会出现乱码或解析失败。 另外,需要考虑的是@RequestParam注解的使用。如果参数是通过查询字符串传递的,Spring MVC会自动处理解码,但如果容器没有正确配置,可能导致解码失败。此外,如果参数是通过POST表单提交的,需要检查是否设置了正确的字符编码过滤器,比如CharacterEncodingFilter,并强制请求使用UTF-8编码。 还有一种可能是参数被截断。比如,%后面的字符可能被解析为URL编码的一部分,如果后面跟着非十六进制字符,可能导致解析错误。例如,如果参数是“20%abc”,服务器可能会尝试解析%ab作为URL编码,但c不是十六进制字符,导致整个参数解析失败。 需要验证客户端是否正确编码了参数。例如,使用Postman或浏览器发送请求时,查看实际发送的URL是否将%转义为%25。如果没有正确转义,参数值会被截断在%处,导致服务器获取到的参数不完整。 解决方案可能包括: 1. 客户端确保对参数值进行URL编码,将%替换为%25。 2. 服务器端配置正确的字符编码,如在Tomcat的server.xml中设置URIEncoding="UTF-8"。 3. 在Spring MVC中添加CharacterEncodingFilter,确保请求响应的编码正确。 4. 检查@RequestParam注解的配置,确保正确使用。 还需要考虑不同场景下的处理方式,比如GET请求POST请求的不同处理,路径变量与查询参数的区别等。例如,路径变量中的%也需要正确编码,否则可能导致路径解析错误。 此外,可能需要查看日志或调试代码,确认参数在到达Controller之前是否已经被正确解码。例如,在DispatcherServlet处理请求时,查看参数解析的中间结果,或者启用Spring的调试日志来跟踪参数解析过程。 总结来说,用户的问题可能源于编码不一致或未正确转义特殊字符,导致服务器无法正确解析参数。需要从客户端编码、服务器解码配置以及框架处理机制三个方面进行排查调整。</think>在 Spring MVC 框架中,当请求参数值包含 `20%` 这类特殊字符(尤其是 `%`)时,参数可能无法正确获取,这通常与 **URL 编码解码** **框架配置** 相关。以下是具体原因解决方案: --- ### 一、问题原因 #### 1. **URL 编码规则未被正确处理** - `%` 是 URL 的保留字符,表示编码的开始(如 `%20` 表示空格)。如果参数值中直接包含 `%` 而未转义,服务器会将其视为编码标识符,导致解析失败。 - **示例**: 客户端发送 `param=20%` → 服务器会尝试将 `%` 后的字符解析为编码,但 `%` 后没有有效字符,导致截断或解析错误。 #### 2. **容器默认解码行为** - Tomcat 等 Servlet 容器默认使用 `ISO-8859-1` 解码 URL,若客户端未正确编码特殊字符(如 UTF-8),会导致乱码或截断。 - **常见场景**: GET 请求参数值包含 `%`,未经过 URL 编码直接传递。 #### 3. **Spring MVC 参数绑定机制** - 使用 `@RequestParam` 或 `@PathVariable` 时,若未显式配置编码,可能因字符集不一致导致解析失败。 --- ### 二、解决方案 #### 1. **客户端:正确编码参数值** - 在发送请求前,对参数值中的 `%` 进行 URL 编码(替换为 `%25`)。 **示例**: ```plaintext 原始参数值:20% 编码后参数值:20%25 ``` - **实现方式**: - JavaScript 使用 `encodeURIComponent()`: ```javascript let param = encodeURIComponent("20%"); // 输出 "20%25" ``` - Java 使用 `URLEncoder.encode()`: ```java String param = URLEncoder.encode("20%", StandardCharsets.UTF_8); // 输出 "20%25" ``` #### 2. **服务端:配置容器解码字符集** - **Tomcat 配置**: 在 `conf/server.xml` 的 `<Connector>` 标签中,添加 `URIEncoding="UTF-8"`: ```xml <Connector port="8080" protocol="HTTP/1.1" URIEncoding="UTF-8" connectionTimeout="20000" redirectPort="8443" /> ``` - **Spring Boot 配置**: 在 `application.properties` 中设置: ```properties server.tomcat.uri-encoding=UTF-8 ``` #### 3. **Spring MVC:强制字符编码** - 添加 `CharacterEncodingFilter` 强制请求响应使用 UTF-8: ```java @Configuration public class WebConfig implements WebMvcConfigurer { @Bean public FilterRegistrationBean<CharacterEncodingFilter> encodingFilter() { FilterRegistrationBean<CharacterEncodingFilter> bean = new FilterRegistrationBean<>(); bean.setFilter(new CharacterEncodingFilter()); bean.addInitParameter("encoding", "UTF-8"); bean.addInitParameter("forceEncoding", "true"); bean.addUrlPatterns("/*"); return bean; } } ``` #### 4. **路径变量(`@PathVariable`)的特殊处理** - 如果参数在 URL 路径中(如 `/api/{param}`),需确保客户端编码后的值符合 URL 规范: ```plaintext 原始路径:/api/20%25 ``` - 服务端无需额外解码,Spring MVC 会自动处理。 --- ### 三、验证步骤 1. **客户端发送编码后的请求**: ```plaintext GET /api/test?param=20%25 ``` 2. **服务端接收参数**: ```java @GetMapping("/api/test") public String test(@RequestParam String param) { return "Received: " + param; // 输出 "Received: 20%" } ``` --- ### 四、常见错误场景 | **场景** | **现象** | **解决方案** | |-----------------------------|-----------------------------|--------------------------------| | 客户端未编码 `%` 直接发送 `20%` | 服务器获取到 `20`(`%` 后内容丢失) | 客户端使用 `encodeURIComponent` 编码 | | Tomcat 未配置 `URIEncoding` | 参数值乱码(如 `20æ`) | 配置 `URIEncoding="UTF-8"` | | POST 表单未设置编码 | 表单参数解析失败 | 添加 `CharacterEncodingFilter` | --- ### 五、总结 - **核心问题**:`%` 是 URL 编码的保留字符,必须转义为 `%25`。 - **关键配置**:客户端正确编码 + 服务端统一字符集(UTF-8)。 - **扩展建议**:对路径参数查询参数统一使用 URL 编码工具处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值