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
- SpringMVC学习(1)--模型2之Servlet
- 学习SpringMVC(七)之处理模型数据
- Servlet学习之七MV模型
- SpringMVC之DispatcherServlet(1)Servlet的初始化
- SpringMVC学习笔记(7):处理模型数据(2)
- SpringMVC学习笔记(6):处理模型数据(1)
- SpringMVC学习(五)之使用Servlet原生API作为参数
- 学习SpringMVC(五)之使用Servlet原生API
- SpringMVC学习(7):处理模型数据
- SpringMVC学习(四)-处理模型数据
- SpringMVC学习系列(1) 之 初识SpringMVC
- SpringMVC学习系列(1) 之 初识SpringMVC
- SpringMVC学习系列(1) 之 初识SpringMVC
- SpringMVC学习系列(1) 之 初识SpringMVC
- SpringMVC学习系列(1) 之 初识SpringMVC
- SpringMVC学习系列(1) 之 初识SpringMVC
- SpringMVC学习系列(1) 之 初识SpringMVC
- SpringMVC学习系列(1) 之 初识SpringMVC
- angularjs的form手动验证
- ServiceLoader
- PCA 降维算法详解
- 单链表的简单面试题
- OJ.坐公交
- SpringMVC学习(1)--模型2之Servlet
- Gradle 1.12用户指南翻译——第五十一章. 发布构件
- JsBridge与客户端交互
- NOIP2016 Day1 玩具谜题
- 闭包和函数声明那些事
- Sublime text 3 [Decode error - output not utf-8]或者[Decode error - output not gbk] 解决方法
- paper-7 - FEP: High Fidelity Experiment Platform for Mobile Internet
- 第16周项目1 -(5)归并排序
- 数据结构::二叉树的非递归实现