1. 程式人生 > >SpringMVC第三篇【收集引數、字串轉日期、結果重定向、返回JSON】

SpringMVC第三篇【收集引數、字串轉日期、結果重定向、返回JSON】

業務方法收集引數

我們在Struts2中收集web端帶過來的引數是在控制器中定義成員變數,該成員變數的名字與web端帶過來的名稱是要一致的…並且,給出該成員變數的set方法,那麼Struts2的攔截器就會幫我們自動把web端帶過來的引數賦值給我們的成員變數….

那麼在SpringMVC中是怎麼收集引數的呢????我們SpringMVC是不可能跟Struts2一樣定義成員變數的,因為SpringMVC是單例的,而Struts2是多例的。因此SpringMVC是這樣乾的:

  • 業務方法寫上引數
  • 引數的名稱要和web端帶過來的資料名稱要一致

接收普通引數

如果是普通引數的話,我們直接在方法上寫上與web端帶過來名稱相同的引數就行了!


<form action="${pageContext.request.contextPath}/hello.action" method="post">
    <table align="center">
        <tr>
            <td>使用者名稱:</td>
            <td><input type="text" name="username"></td>
        </tr>
        <tr>
            <td
>
編號</td> <td><input type="text" name="id"></td> </tr> <tr> <td colspan="2"> <input type="submit" value="提交"> </td> </tr> </table> </form>

    @RequestMapping(value
= "/hello.action") public String hello(Model model, String username, int id) throws Exception { System.out.println("使用者名稱是:" + username); System.out.println("編號是:" + id); model.addAttribute("message", "你好"); return "/index.jsp"; }

效果:

這裡寫圖片描述

接收JavaBean

我們處理表單的引數,如果表單帶過來的資料較多,我們都是用JavaBean對其進行封裝的。那麼我們在SpringMVC也是可以這麼做的。

  • 建立Javabean
  • javaBean屬性與表單帶過來的名稱相同
  • 在業務方法上寫上Javabean的名稱

建立JavaBean,javaBean屬性與表單帶過來的名稱相同


public class User {

    private String id;
    private String username;

    public User() {
    }
    public User(String id, String username) {
        this.id = id;
        this.username = username;
    }
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "id='" + id + '\'' +
                ", username='" + username + '\'' +
                '}';
    }
}

在業務方法引數上寫入Javabean


    @RequestMapping(value = "/hello.action")
    public String hello(Model model,User user) throws Exception {

        System.out.println(user);
        model.addAttribute("message", "你好");
        return "/index.jsp";
    }

這裡寫圖片描述

收集陣列

收集陣列和收集普通的引數是類似的,看了以下的程式碼就懂了。


<form action="${pageContext.request.contextPath}/hello.action" method="post">
    <table align="center">
        <tr>
            <td>使用者名稱:</td>
            <td><input type="text" name="username"></td>
        </tr>
        <tr>
            <td>愛好</td>
            <td><input type="checkbox" name="hobby" value="1">籃球</td>
            <td><input type="checkbox" name="hobby" value="2">足球</td>
            <td><input type="checkbox" name="hobby" value="3">排球</td>
            <td><input type="checkbox" name="hobby" value="4">羽毛球</td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" value="提交">
            </td>
        </tr>
    </table>

</form>

業務方法獲取引數


    @RequestMapping(value = "/hello.action")
    public String hello(Model model,int[] hobby) throws Exception {


        for (int i : hobby) {
            System.out.println("喜歡運動的編號是:" + i);

        }

        model.addAttribute("message", "你好");
        return "/index.jsp";
    }

效果:

這裡寫圖片描述

收集List<JavaBean>集合

我們在Spring的業務方法中是不可以用List這樣的引數來接收的,SpringMVC給了我們另一種方案!

我們使用一個JavaBean把集合封裝起來,給出對應的set和get方法。那麼我們在接收引數的時候,接收的是JavaBean


/**
 * 封裝多個Emp的物件 
 * @author AdminTC
 */
public class Bean {
    private List<Emp> empList = new ArrayList<Emp>();
    public Bean(){}
    public List<Emp> getEmpList() {
        return empList;
    }
    public void setEmpList(List<Emp> empList) {
        this.empList = empList;
    }
}

業務方法接收JavaBean物件


    /**
     * 批量新增員工
     */
    @RequestMapping(value="/addAll",method=RequestMethod.POST)
    public String addAll(Model model,Bean bean) throws Exception{
        for(Emp emp:bean.getEmpList()){
            System.out.println(emp.getUsername()+":"+emp.getSalary());
        }
        model.addAttribute("message","批量增加員工成功");
        return "/jsp/ok.jsp";
    }

在JSP頁面直接寫上empList[下表].


<form action="${pageContext.request.contextPath}/emp/addAll.action" method="POST">
        <table border="2" align="center">
            <caption><h2>批量註冊員工</h2></caption>
            <tr>
                <td><input type="text" name="empList[0].username" value="哈哈"/></td>
                <td><input type="text" name="empList[0].salary" value="7000"/></td>
            </tr>
            <tr>
                <td><input type="text" name="empList[1].username" value="呵呵"/></td>
                <td><input type="text" name="empList[1].salary" value="7500"/></td>
            </tr>
            <tr>
                <td><input type="text" name="empList[2].username" value="班長"/></td>
                <td><input type="text" name="empList[2].salary" value="8000"/></td>
            </tr>
            <tr>
                <td><input type="text" name="empList[3].username" value="鍵狀哥"/></td>
                <td><input type="text" name="empList[3].salary" value="8000"/></td>
            </tr>
            <tr>
                <td><input type="text" name="empList[4].username" value="綠同學"/></td>
                <td><input type="text" name="empList[4].salary" value="9000"/></td>
            </tr>
            <tr>
                <td colspan="2" align="center">
                    <input type="submit" value="批量註冊"/>
                </td>
            </tr>
        </table>
    </form>

其實這種方法看起來也沒有那麼難理解,我們就是向上封裝了一層【與接收普通的JavaBean類似的】

收集多個模型

我們有可能在JSP頁面上即有User模型的資料要收集,又有Emp模型的資料要收集….並且User模型的屬性和Emp模型的屬性一模一樣….此時我們該怎麼辦呢???

我們也是可以在User模型和Emp模型上向上抽象出一個Bean,該Bean有Emp和User物件

/**
 * 封裝User和Admin的物件
 * @author AdminTC
 */
public class Bean {
    private User user;
    private Admin admin;
    public Bean(){}
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    public Admin getAdmin() {
        return admin;
    }
    public void setAdmin(Admin admin) {
        this.admin = admin;
    }
}

在JSP頁面收集的時候,給出對應的型別就行了。


    <form action="${pageContext.request.contextPath}/person/register.action" method="POST">
        <table border="2" align="center">
            <tr>
                <th>姓名</th>
                <td><input type="text" name="user.username" value="${user.username}"/></td>
            </tr>
            <tr>
                <th>月薪</th>
                <td><input type="text" name="user.salary" value="${user.salary}"></td>
            </tr>
            <tr>
                <th>入職時間</th>
                <td><input 
                        type="text" 
                        name="user.hiredate" 
                        value='<fmt:formatDate value="${user.hiredate}" type="date" dateStyle="default"/>'/></td>
            </tr>
            <tr>
                <td colspan="2" align="center">
                    <input type="submit" value="普通使用者註冊" style="width:111px"/>
                </td>
            </tr>
        </table>    
    </form> 

字串轉日期型別

我們在Struts2中,如果web端傳過來的字串型別是yyyy-mm-dd hh:MM:ss這種型別的話,那麼Struts2預設是可以自動解析成日期的,如果是別的字串型別的話,Struts2是不能自動解析的。要麼使用自定義轉換器來解析,要麼就自己使用Java程式來解析….

而在SpringMVC中,即使是yyyy-mm-dd hh:MM:ss這種型別SpringMVC也是不能自動幫我們解析的。我們看如下的例子:

JSP傳遞關於日期格式的字串給控制器…

<form action="${pageContext.request.contextPath}/hello.action" method="post">
    <table align="center">
        <tr>
            <td>使用者名稱:</td>
            <td><input type="text" name="username"></td>
        </tr>
        <tr>
            <td>出生日期</td>
            <td><input type="text" name="date" value="1996-05-24"></td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" value="提交">
            </td>
        </tr>
    </table>

</form>

User物件定義Date成員變數接收


 public Date getDate() {
        return date;
    }
    public void setDate(Date date) {
        this.date = date;
    }

業務方法獲取Date值


    @RequestMapping(value = "/hello.action")
    public String hello(Model model, User user) throws Exception {

        System.out.println(user.getUsername() + "的出生日期是:" + user.getDate());


        model.addAttribute("message", "你好");
        return "/index.jsp";
    }

結果出問題了,SpringMVC不支援這種型別的引數:

這裡寫圖片描述

現在問題就丟擲來了,那我們要怎麼解決呢????

SpringMVC給出類似於Struts2型別轉換器這麼一個方法給我們使用:如果我們使用的是繼承AbstractCommandController類來進行開發的話,我們就可以重寫initBinder()方法了….

具體的實現是這樣子的:


    @Override
    protected void initBinder(HttpServletRequest request,ServletRequestDataBinder binder) throws Exception {
        binder.registerCustomEditor(Date.class,new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
    }

那我們現在用的是註解的方式來進行開發,是沒有重寫方法的。因此我們需要用到的是一個註解,表明我要重寫該方法


    @InitBinder
    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
        binder.registerCustomEditor(
                Date.class,
                new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));

    }

再次訪問:

這裡寫圖片描述

值得注意的是:如果我們使用的是Oracle插入時間的話,那麼我們在SQL語句就要寫TimeStrap時間戳插入進去,否則就行不通

結果重定向和轉發

我們一般做開發的時候,經常編輯完資料就返回到顯示列表中。我們在Struts2是使用配置檔案進行重定向或轉發的:

這裡寫圖片描述

而我們的SpringMVC就非常簡單了,只要在跳轉前寫上關鍵字就行了!



    public String hello(Model model, User user) throws Exception {

        System.out.println(user.getUsername() + "的出生日期是:" + user.getDate());
        model.addAttribute("message", user.getDate());
        return "redirect:/index.jsp";
    }

這裡寫圖片描述

以此類推,如果是想要再次請求的話,那麼我們只要寫上對應的請求路徑就行了!


    @RequestMapping(value = "/hello.action")
    public String hello(Model model, User user) throws Exception {

        return "redirect:/bye.action";
    }

    @RequestMapping("/bye.action")
    public String bye() throws Exception {

        System.out.println("我進來了bye方法");
        return "/index.jsp";
    }

這裡寫圖片描述

返回JSON文字

回顧一下Struts2返回JSON文字是怎麼操作的:

  • 匯入jar包
  • 要返回JSON文字的物件給出get方法
  • 在配置檔案中繼承json-default包
  • result標籤的返回值型別是json

那麼我們在SpringMVC又怎麼操作呢???

匯入兩個JSON開發包

  • jackson-core-asl-1.9.11.jar
  • jackson-mapper-asl-1.9.11.jar

在要返回JSON的業務方法上給上註解:


    @RequestMapping(value = "/hello.action")
    public
    @ResponseBody
    User hello() throws Exception {

        User user = new User("1", "zhongfucheng");
        return user;
    }

配置JSON介面卡



        <!--  
            1)匯入jackson-core-asl-1.9.11.jar和jackson-mapper-asl-1.9.11.jar
            2)在業務方法的返回值和許可權之間使用@ResponseBody註解表示返回值物件需要轉成JSON文字
            3)在spring.xml配置檔案中編寫如下程式碼:
            <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
                <property name="messageConverters">
                        <list>
                            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
                        </list>
                </property>
            </bean>
        -->

測試的JSP


    <input type="button" value="Emp轉JSON"/><p>

    <input type="button" value="List<Emp>轉JSON"/><p>

    <input type="button" value="Map<String,Object>轉JSON"/><p>

    <!-- Map<String,Object>轉JSON -->
    <script type="text/javascript">
        $(":button:first").click(function(){
            var url = "${pageContext.request.contextPath}/hello.action";
            var sendData = null;
            $.post(url,sendData,function(backData,textStaut,ajax){
                alert(ajax.responseText);
            });
        });
    </script>

測試:

這裡寫圖片描述

Map測試:


    @RequestMapping(value = "/hello.action")
    public
    @ResponseBody
    Map hello() throws Exception {

        Map map = new HashMap();

        User user = new User("1", "zhongfucheng");
        User user2 = new User("12", "zhongfucheng2");
        map.put("total", user);
        map.put("rows", user2);


        return map;
    }

這裡寫圖片描述

更新——————————————————————

如果傳遞進來的資料就是JSON格式的話,我們我們需要使用到另外一個註解@RequestBody,將請求的json資料轉成java物件

這裡寫圖片描述

這裡寫圖片描述