SpringMVC学习(1)--模型2之Servlet

来源:互联网 发布:mac book 安装idea 编辑:程序博客网 时间:2024/06/05 01:57

学习SpringMVC之前先看它能解决什么问题,在没使用SpringMVC之前我们是怎么处理的,这样就能更好的理解它的好处所在。

1.模型2

模型2基于模型-视图-控制(MVC)模式,视图负责展示,模型封装了应用的数据和业务逻辑。控制器负责接受输入,改变模型和视图跳转。
模型2中,Servlet和Filter都可以充当控制器,比如SpringMVC使用一个Servlet当控制器,Struts2使用一个Filter作为控制器。模型采用POJO,采用一个JavaBean来持有模型状态,并将业务逻辑放入一个Action类中。视图一般是JSP页面,当然也有其他技术。

2.模型2的简单应用

例子:填写一个产品表单的表格,提交并将其保存,显示在页面。
这里写图片描述

这里写图片描述

下面是分层之后的项目结构:
这里写图片描述

1.Controller接口

我们将所有业务逻辑代码提取为controller,Controller中只有一个方法handleRequest(),用来统一处理所有请求。

package controller;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/** * Created by kay on 2016/12/14. */public interface Controller {    String handleRequest (HttpServletRequest request, HttpServletResponse response)throws ServletException,IOException;}

2.InputProductController和SaveProductController都实现Controller接口

InputProduct是用来显示表格页面,所以只返回页面,SaveProduct将提取请求表单中的参数,然后做一些处理,比如验证,数据格式转换,然后传给模型类Product存到数据库等等,最后返回详细的显示页面。

public class InputProductController implements Controller{    @Override    public String handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException{        return "/WEB-INF/jsp/ProductForm.jsp";    }}/** * Created by kay on 2016/12/14. */public class SaveProductController implements Controller{    @Override    public String handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException{        //解决post提交表单中文参数乱码问题,以utf-8接收请求        request.setCharacterEncoding("utf-8");        ProductForm productForm=new ProductForm();        productForm.setName(request.getParameter("name"));        productForm.setDescription(request.getParameter("description"));        productForm.setPrice(request.getParameter("price"));        //添加验证        ProductValidator productValidator=new ProductValidator();        Map<String,String> errors=productValidator.validate(productForm);        if(errors.isEmpty()){            Product product=new Product();            product.setName(productForm.getName());            product.setDescription(productForm.getDescription());            try {            //数据类型转换                product.setPrice(Float.parseFloat(productForm.getPrice()));            }catch (NumberFormatException e){                e.printStackTrace();            }            //.....存入数据库等等操作...            request.setAttribute("product",product);            return "/WEB-INF/jsp/ProductDetails.jsp";        }else {            request.setAttribute("errors",errors);            request.setAttribute("form",productForm);            return "/WEB-INF/jsp/ProductForm.jsp";        }    }}

3.Product类 和ProductForm类
Product是数据库实体的映射,Product接收表单数据

这里写图片描述

这里写图片描述

4.DispatcherServlet检查每个URI,创建对应的Controller并跳转页面

DispatcherServlet是很多实现MVC模型的核心机制(Struts2,SpringMVC),接收所有请求并分发到不同的处理和跳转,我这里做一个简单的模仿。

package servlet;import controller.InputProductController;import controller.SaveProductController;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/** * Created by kay on 2016/12/14. */public class DispatcherServlet extends HttpServlet{    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        process(req,resp);    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        process(req,resp);    }//统一处理    private void process(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException{    //获取URI        String uri=request.getRequestURI();        int lastIndex=uri.lastIndexOf("/");        String action =uri.substring(lastIndex+1);        String dispatchUrl=null;        if(action.equals("product_input")){            InputProductController controller=new InputProductController();            dispatchUrl=controller.handleRequest(request,response);        }else if(action.equals("product_save")){            SaveProductController controller=new SaveProductController();            dispatchUrl=controller.handleRequest(request,response);        }        if(dispatchUrl!=null){ //服务器请求转发           request.getRequestDispatcher(dispatchUrl).forward(request,response);        }    }}

5.校验器 ProductValidator

做一些简单的验证,验证的逻辑当然会插入到Controller中去处理

public class ProductValidator {    public Map<String,String> validate(ProductForm productForm) {        Map<String,String> errors = new HashMap<>();        String name = productForm.getName();        if (name == null || name.trim().isEmpty()) {            errors.put("name","商品不能为空!");        }        String price = productForm.getPrice();        if (price == null || price.trim().isEmpty()) {            errors.put("price","价格不能为空");        } else {            try {                Float.parseFloat(price);            } catch (NumberFormatException e) {                errors.put("price","Invalid price value");            }        }        return errors;    }}

6.页面ProductForm.jsp和ProductDetails.jsp
这里写图片描述

这里写图片描述

7.最后是web.xml中Servlet的配置

类似于SpringMVC配置DispathcerServlet,只不过Spring中的是org.springframework.web.servlet.DispatcherServlet。这里是我们自己的DispatcherServlet

这里写图片描述

3.小结

以上,如果我们自己来开发一个模型2的应用程序,则要负责写一个DispatcherServlet和控制类,DispatcherServlet要能完成的事情如下:
1.根据URI调用对应的Action
2.根据表单参数值来构造表单类
3.调用控制对象的相应方法
4.转到一个视图页面,比如JSP

说道这里,顺便也谈一下Servlet+JavaBean+JSP模式开发MVC的缺点:

1.Servlet作为控制器的缺点:
(1)逻辑处理可能比较复杂,比如要根据请求参数再来判断调用action,每次请求都要判断
(2)请求参数要手动的封装到模型中去,就是写很多set属性
(3)视图跳转和传递模型都要严重依赖ServletAPI
2.JavaBean作为模型的缺点
又要封装数据,又要进行业务处理,组件比较庞大。
解决办法是有,三层结构,JavaBean组件:域模型层+业务逻辑层+持久层
3.视图缺点:绑定在JSP

来看SpringMVC提供的好处:

1.内置的DispatcherServlet,不用额外开发
2.基于XML配置文件
3.实例化控制器,根据输入构造bean
4.自动绑定请求参数,然后完成数据类型的转换(属性编辑器)
5.内置常见的校验器
6.基于Spring,和 Spring无缝融合
7.支持多种视图技术,除了常见的JSP,Velocity,FreeMarker

当然也不能说SpringMVC就是十全十美的,很多技术的出现只是为了解决一些实际的问题,简化开发,新技术的提出也会带来新的问题。

以上,为学习SpringMVC的第一次总结,为了更好的理解和运用,首先要知道在不使用它的前提是我们是怎么来做的,然后就明白它解决了什么问题,核心是什么。   Kay
1 0