后端控制器主要控制数据和视图,告知和返回给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%>
亲测有效