1. 程式人生 > >springmvc的三種Controller處理方式及錯誤處理器

springmvc的三種Controller處理方式及錯誤處理器

後端控制器主要控制資料和檢視,告知和返回給dispatcherservlet。
控制器可以有3種方法返回值

為了突出重點,先把控制器類buyProduct裡實現的3種方法發一下

1.ModelAndView

/*
    * 1,用modelandview傳回值和檢視,不太推薦
    * */
    @RequestMapping(value = "/buyProduct.do",method = {RequestMethod.POST,RequestMethod.GET})
    public ModelAndView getInfo(RedirectAttributes attr, HttpServletRequest request){
        ModelAndView mav=new ModelAndView();
        productForm form=new productForm();
        form.setName(request.getParameter("name"));
        form.setDescription(request.getParameter("description"));
        form.setPrice(Double.valueOf(request.getParameter("price")));

        product p=new product();
        p.setName(form.getName());
        p.setDescription(form.getDescription());
        p.setPrice(form.getPrice());

        mav.addObject("form",form);
        mav.addObject("product",p);
        mav.addObject("name",form.getName());
        mav.addObject("description",p.getDescription());
        mav.addObject("price",form.getPrice());
        mav.setViewName("showInfo");
        return mav;
    }

如上,modelandview用addObject和setViewName就能完成

2.Model

/*
    * 2。用String傳檢視地址,model傳參
    * 能將引數和檢視解耦,強力推薦
    * */
    @RequestMapping(value = "/buyProduct.do",method = {RequestMethod.POST,RequestMethod.GET})
    public String getInfo(Model model, HttpServletRequest request){
        productForm form=new productForm();
        form.setName(request.getParameter("name"));
        form.setDescription(request.getParameter("description"));
        form.setPrice(Double.valueOf(request.getParameter("price")));
        
        product p=new product();
        p.setName(form.getName());
        p.setDescription(form.getDescription());
        p.setPrice(form.getPrice());
        
        model.addAttribute("form",form);
        model.addAttribute("product",p);
        model.addAttribute("name",form.getName());
        model.addAttribute("description",p.getDescription());
        model.addAttribute("price",form.getPrice());

        return "showInfo";

        //重定向
      //  return "redirect:/showInfo.do";

        //內部轉發
//        return "forward:showInfo";
    }

這種方法能將引數和檢視解耦,強力推薦
返回的檢視名由檢視解析器解析
本來想實現重定向和內部轉發的,但好像檢視解析器不起作用,只能絕對路徑
這個問題暫時沒找到原因

3.void

 /*
    * 3.這種和servlet沒啥區別
    * */
    @RequestMapping(value = "/buyProduct.do",method = {RequestMethod.POST,RequestMethod.GET})
    public void getInfo(Model model, HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        productForm form=new productForm();
        form.setName(request.getParameter("name"));
        form.setDescription(request.getParameter("description"));
        form.setPrice(Double.valueOf(request.getParameter("price")));

        product p=new product();
        p.setName(form.getName());
        p.setDescription(form.getDescription());
        p.setPrice(form.getPrice());

        request.setAttribute("form",form);
        request.setAttribute("product",p);
        request.setAttribute("name",form.getName());
        request.setAttribute("description",p.getDescription());
        request.setAttribute("price",form.getPrice());

        request.getRequestDispatcher("/WEB-INF/demo1Jsp/showInfo.jsp").forward(request,response);
    }

這裡的model對應於jsp中EL的sessionScope,因為model是存放在session裡
這種方式適合非同步請求,就是ajax請求伺服器時,傳送的是json格式,目前還沒弄過

差點忘了貼剩下的程式碼
web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <display-name>dispatcher</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/demo1.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <!--預設為0,在該servlet的第一個請求時載入
                為1,在程式啟動時轉載並初始化servlet-->
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

</web-app>

demo1.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!-- 配置controller掃描包 -->
    <context:component-scan base-package="demo1Java" />

    <!--使用Flash重定向傳值時必須加入
        相當於配置了處理器對映器和處理器介面卡-->
    <mvc:annotation-driven />

    <!-- 配置檢視解析器 -->
    <bean  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 配置邏輯檢視的字首 -->
        <property name="prefix" value="/WEB-INF/demo1Jsp/" />
        <!-- 配置邏輯檢視的字尾 -->
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

product類

package demo1Java;

/**
 * Created by Administrator on 2018/10/17.
 */
public class product {
    private String name,description;
    private double price;

    public product() {

    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

productForm類

package demo1Java;

/**
 * Created by Administrator on 2018/10/17.
 */
public class productForm {
    private String name,description;
    private double price;

    public productForm() {

    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

showInfo.jsp

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2018/10/20
  Time: 11:26
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>${param.name}商品資訊</title>
</head>
<body>
<%--form:${form}<br><br>
product:${product}<br><br>
商品名:${form.name}<br><br>
商品描述:${description}<br><br>
商品價格:${param.price}<br><br>--%>
<%--form:${requestScope.form}<br><br>
product:${requestScope.product}<br><br>
商品名:${requestScope.product.name}<br><br>
商品描述:${requestScope.product.description}<br><br>
商品價格:${requestScope.form.price}<br><br>--%>
form:${sessionScope.form}<br><br>
product:${requestScope.product}<br><br>
商品名:${requestScope.product.name}<br><br>
商品描述:${requestScope.product.description}<br><br>
商品價格:${requestScope.form.price}<br><br>
test311
</body>
</html>

showProduct.jsp(其實是編寫商品資訊的介面)

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2018/10/17
  Time: 21:30
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>新增商品</title>
</head>
<body>
<fieldset>
    <legend>請輸入要新增的商品資訊</legend>
    <form action="/buyProduct.do" method="post">
        請輸入商品名:<input name="name" value="" /><br><br>
        請輸入描述:<textarea name="description" rows="3" cols="30" value=""></textarea><br><br>
        請輸入商品價格:<input name="price" value="0.0" />
        <input type="submit">
    </form>
</fieldset>
</body>
</html>

錯誤處理器

異常分為兩種:預期異常和執行時異常RuntimeException
前者通過捕獲而獲取出錯資訊;
後者不用宣告也不用捕獲,主要是null和陣列越界等,主要通過規範程式碼開發、測試通過手段減少執行時異常的發生

在這裡插入圖片描述

首先,定義異常類

package ErrorSolver;

/**
 * Created by Administrator on 2018/10/22.
 */
public class messageException extends Exception {

    String message=null;

    public messageException() {

    }

    public messageException(String message) {
        this.message=message;
        System.err.println(message);
    }

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

異常處理類

package ErrorSolver;

import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;

/**
 * Created by Administrator on 2018/10/22.
 */
public class exceptionHandler implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest,
                                         HttpServletResponse httpServletResponse,
                                         Object o, Exception e) {
        ModelAndView mav=new ModelAndView();
        String msg="";
        if(e instanceof messageException){
            msg=e.getMessage();
        }else{
            Writer out=new StringWriter();
            PrintWriter s=new PrintWriter(out);
            e.printStackTrace(s);
            msg=out.toString();
        }

        mav.addObject("message",msg);
        mav.setViewName("error");
        return mav;
    }
}

在demo1.xml配置異常處理Bean

<!-- 配置全域性異常處理器 -->
    <bean id="handler" class="ErrorSolver.exceptionHandler"></bean>

錯誤顯示頁面error.jsp,在/WEB-INF/demo1Jsp路徑下,能被檢視解析器解析路徑

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2018/10/22
  Time: 15:40
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>錯誤處理器</title>
</head>
<body>
${message}
</body>
</html>

在showInfo.jsp下弄個測試,加上這句

1/0=<%=1/0%>

親測有效

指我過者,吾師也