SpringMVC 接收表單數據、數據綁定、解決請求參數中文亂碼


 

接收表單數據有3種方式。

 

1、使用簡單類型接收表單數據(綁定簡單數據類型)

表單:

  <form action="${pageContext.request.contextPath}/userController/handler" method="post">
    用戶名:<input name="username" type="text" /><br />
    密碼:<input name="password" type="password" /><br />
    年齡:<input name="age" type="number" /><br />
    <button type="submit">提交</button>
  </form>

action會有提示,但必須要在前面加${pageContext.request.contextPath}來獲取項目名(/項目名的形式),否則會把后面的路徑直接拼接到域名后面。

如果是SpringBoot,則不用加${pageContext.request.contextPath}。

 

 

controller:

@org.springframework.stereotype.Controller
@RequestMapping("/userController")
public class UserController{

    @RequestMapping("/handler")
    public ModelAndView handler(String username, String password, int age){
        ModelAndView mav = new ModelAndView("user_info");
        mav.addObject("username", username);
        mav.addObject("password", password);
        mav.addObject("age", age);
        return mav;
    }

}

參數名要和表單字段的name一致。

SpringMVC會自動將請求參數轉換為需要的數據類型。

 

如果表單字段很多,業務方法要寫很多參數,太麻煩,不推薦。

 

 


 

 

2、使用pojo類接收表單數據(綁定pojo類型)

pojo:

public class User {
    private String username;
    private String password;
    private int age;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

屬性名要與表單字段的name一致。

 

 

controller:

@org.springframework.stereotype.Controller
@RequestMapping("/userController")
public class UserController{

    @RequestMapping("/handler")
    public ModelAndView handler(User user){
        ModelAndView mav = new ModelAndView("user_info");
        mav.addObject("user", user);
        return mav;
    }

}

 

推薦使用。

 

 


 

 

3、使用擴展類接收表單數據(綁定pojo的包裝類)

擴展類:

public class UserExt {
    private User user;
    //此處省略其它成員變量

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

把bean寫為成員變量。

 

 

表單:

  <form action="${pageContext.request.contextPath}/userController/handler" method="post">
    用戶名:<input name="user.username" type="text" /><br />
    密碼:<input name="user.password" type="password" /><br />
    年齡:<input name="user.age" type="number" /><br />
    <button type="submit">提交</button>
  </form>

這里的user對應擴展類中的成員變量名。

 

 

controller:

@org.springframework.stereotype.Controller
@RequestMapping("/userController")
public class UserController{

    @RequestMapping("/handler")
    public ModelAndView handler(UserExt userExt){
        ModelAndView mav = new ModelAndView("user_info");
        mav.addObject("userExt", userExt);
        return mav;
    }

}

 

使用擴展類接收參數,主要是表單傳過來的數據有一些不屬於實體類,還需要用其它的成員變量來接收。

 

 


 

 

單選框、復選框的數據接收

 單選框可用普通類型來接收。

 

復選框常用於同時勾選多個選項,比如選擇愛好、批量刪除等(同一個name、多個value)。

復選框使用數組來接收,復選框的name要與數組名一致。

@org.springframework.stereotype.Controller
@RequestMapping("/userController")
public class UserController{

    @RequestMapping("/handler")
    public ModelAndView handler(String[] hobby){
        ModelAndView mav = new ModelAndView("user_info");
        mav.addObject("hobby",hobby);
        return mav;
    }

}

 

 


 

 

批量修改,使用List來接收

有時候我們需要批量插入、批量修改。

比如視圖以表格的形式列出了多個用戶的信息,管理員在頁面上修改了多個用戶的信息,現在要提交修改,需要使用List<User>來傳遞數據,批量添加也是一樣的。

不能直接使用List<User>來接收參數,需要使用包裝類包裝一下。

 

包裝類:

public class UserVO {
    private List<User> list;

    public List<User> getList() {
        return list;
    }

    public void setList(List<User> list) {
        this.list = list;
    }
}

VO只有一個屬性,及其getter、setter方法。

 

 

表單:

  <form action="${pageContext.request.contextPath}/userController/handler" method="post">
    User1:<br />
    username:<input name="list[0].username" type="text"><br />
    password:<input name="list[0].password" type="password"><br /><br />

    User2:<br />
    id:<input name="list[1].username" type="text"><br />
    name:<input name="list[1].password" type="password"><br /><br />

    <button type="submit">提交</button>
  </form>

此處list對應包裝類的成員變量名。

 

 

controller:

@org.springframework.stereotype.Controller
@RequestMapping("/userController")
public class UserController{

    @RequestMapping("/handler")
    public ModelAndView handler(UserVO userVO){
        ModelAndView mav = new ModelAndView("user_info");
        mav.addObject("list", userVO.getList());
        return mav;
    }

}

 

 


 

 

日期的接收

有時候需要接收表單傳遞的日期,比如生日。

 

后台有2種接收方式:

  • 使用String接收日期

如果不進行相關計算,使用String表示日期即可;如果要進行相關計算,先用String接收日期,在業務方法中把String轉換為Date(可以封裝為工具類,在業務方法中調用)。

表單使用<input type="text" />、<input type="date" />都可以,type="text"要嚴格校驗日期格式。

 

  • 使用Date接收日期

表單使用<input type="text" />、<input type="date" />都可以,如果使用type="text",日期格式只能是 年/月/日 (/分隔)。

 

 


 

 

DataBinder   數據綁定

數據綁定的概念:將請求參數的內容與controller中業務方法的參數綁定,比如表單數據的提交。

 

 

數據綁定的流程:

(1)Spring MVC將ServletRequest對象傳遞給DataBinder

 

(2)Spring MVC從controller的業務方法的簽名(聲明)中獲取參數表(形參名),把它傳遞給DataBinder

 

(3)DataBinder調用ConversionService對ServletRequest中的請求參數進行數據類型的轉換、格式化

   ( ConversionService會根據  原始類型  ——目標類型  調用對應的Converter來進行數據轉換。Spring MVC內置了常用的類型轉換器,我們也可以自定義類型轉換器。)

 

(4)DataBinder調用Validator校驗已經被轉換好的請求參數是否合法

 

(5)DataBinder調用BindingResult,把請求參數賦給業務方法中對應的參數,完成數據綁定。

 

 


 

 

解決前端傳過來的數據中文亂碼

使用spring mvc提供的編碼過濾器,過濾所有請求。

 

在web.xml中配置:

    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>

    <!--過濾所有請求-->
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

 

 


 

 

@RequestParam   必需的請求參數

controller:

@org.springframework.stereotype.Controller
@RequestMapping("/userController")
public class UserController{

    @RequestMapping("/handler")
    public String handler(int user_id,Model model){
        model.addAttribute("user_id", user_id);
        return "user_info";
    }

}

就算請求參數中沒有user_id這個字段,也會調用這個業務方法來處理,就是說參數不是必需傳遞的。

 

 

如果參數是必需的,要求HTTP請求參數中必需要有這個字段,可以這樣:

@org.springframework.stereotype.Controller
@RequestMapping("/userController")
public class UserController{

    @RequestMapping("/handler")
    public String handler(@RequestParamint user_id,Model model){
        model.addAttribute("user_id", user_id);
        return "user_info";
    }

}

用@RequestParam修飾某個參數,表示這個參數是必需的,如果沒有傳遞此參數,不會調用業務方法,直接報錯。

 

 

如果請求參數的字段名和業務方法的形參名不一致,比如請求參數中的字段名是id,而業務方法中的形參名是user_id,則必須指定該形參與請求參數中的哪個字段綁定: 

    @RequestMapping("/handler")
    public String handler(@RequestParam("id") int user_id,Model model){
        model.addAttribute("user_id", user_id);
        return "user_info";
    }

如果請求參數的字段名和業務方法的形參名一致,直接寫@RequestParam就行,SpringMVC會自動把請求參數賦給業務方法中同名的形參。

 

 

注意:

必需和必填不是一個概念,必需是指請求參數中必須要有這個字段,只有要這個字段就行,值可以是空的。

如果一個表單字段(有name屬性),沒填就提交了,請求參數中是有這個字段的,只不過值是空的。

 

 

可以設置是否必需:

@org.springframework.stereotype.Controller
@RequestMapping("/userController")
public class UserController{

    @RequestMapping("/handler")
    public String handler(@RequestParam(value = "user_id",required = false) int user_id,Model model){
        model.addAttribute("user_id", user_id);
        return "user_info";
    }

}

默認為true——必需,沒傳遞該參數直接報錯。

false——不是必需的,傳不傳遞都行,都會調用業務方法。

 

 

可以設置默認值:

@org.springframework.stereotype.Controller
@RequestMapping("/userController")
public class UserController{

    @RequestMapping("/handler")
    public String handler(@RequestParam(value = "user_id",defaultValue = "0") int user_id,Model model){
        model.addAttribute("user_id", user_id);
        return "user_info";
    }

}

如果沒有傳遞此參數,會自動使用默認值。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM