博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring MVC---基于注解的控制器
阅读量:4969 次
发布时间:2019-06-12

本文共 9782 字,大约阅读时间需要 32 分钟。


基于注解的控制器

  • SpringMVC是一个基于DispatcherServlet的MVC框架,每个请求最先访问的是DispatcherServlet,DispatcherServlet负责将每一个Request转发到相应的Handler,Handler处理后再返回相应的模型(Model)和视图(View)。在使用注解的Spring MVC中,处理器Handler是基于@Controller和@RequestMapping两个注解的,这两个注解可以提供非常灵活的匹配和处理方式。
@Controller和@RequestMapping注解
  • @Controller注解类型

  声明一个控制器类,Spring使用扫描机制来找到应用程序中所有基于注解的控制器类,控制器类的内部包含每个动作相应的处理方法,如下是一个@Controller的例子。

package com.example.controller;import org.springframework.web.servlet.mvc.support.RedirectAttributes;...@Controllerpublic class ProductController {    //request-handling methods here}

  为了保证Spring能扫描到控制器类,需要完成两个配置,首先要在Spring MVC的配置文件中声明Spring-context,如下所示:

  其次需要应用<component-scan/>元素,在该元素中指定控制器类的基本包。例如所有的控制器类都在com.example.controller及其子包下,则该元素如下:

  确保所有控制器都在基本包下,并且不要指定太广泛的基本包,否则会导致Spring MVC扫描无关的包。

  • @RequestMapping注解类型

  该注解类型在控制器类的内部定义每一个动作相应的处理方法,一个采用@RequestMapping注释的方法将成为一个请求处理方法,并由调度程序在接收到对应的URL请求时调用,下面是一个RequestMapping注解方法的控制器类。

package com.example.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;...@Controllerpublic class ProductController {        @RequestMapping(value="/productInput")    public String inputProduct(){        //do something here        return "ProductForm";    }}

  使用RequestMapping注解的value属性将URL映射到方法,在如上的例子中,我们将productInput映射到inputProduct()方法,通过http://localhost:8081/SpringMVC/productInput访问inputProduct方法。RequestMapping方法除了有value属性外,还有method属性,该属性用来指示该方法仅处理哪些http方法,例如,仅当HTTP POST或PUT方法时,调用下面的processOrder方法。

@RequestMapping(value="/order_process", method={RequestMethod.POST, RequestMethod.PUT})public String processOrder(){    //do something here    return "OrderForm";}

  如果method属性只有一个HTTP方法值,则无需{},直接为method=RequestMethod.POST,如果未指定method属性,则请求处理方法可以处理任意HTTP方法。此外RequestMapping注释类型也可以用来注释一个控制器类,如下所示:

import org.springframework.stereotype.Controller;...@Controller@RequestMapping(value="/customer")public class CustomerController{
@RequestMapping(value="/delete", method={RequestMethod.POST, RequestMethod.PUT}) public String deleteCustomer(){
//do something here return ...; }}

   在这种情况下,所有的方法都将映射为相对于类级别的请求,如例子中的deleteCustomer方法,由于控制器类映射使用"/customer",而deleteCustomer方法映射为"/delete",则需要通过http://localhost:8081/SpringMVC/customer/delete。

应用基于注解的控制器

  本节将通过一个例子说明基于注解的控制器,展示了一个包含两个请求处理方法的控制器类,项目目录结构如下:

 

  我们首先对类进行介绍,Product是产品类,包括产品的名称、描述和价格属性,该类实现了Serializable接口,而ProductForm类与HTML表单相映射,是Product在服务端的代表,表单对象传递ServletRequest给其他组件,还有当数据校验失败时,表单对象将用于保存和展示用户在原始表单上的输入。DBOperator类负责与mysql数据库打交道,ProductService定义了服务层的接口,ProductServiceImpl实现了ProductService中定义的接口。

Product类代码如下,包含属性和属性的set和get方法:

public class Product implements Serializable{    private static final long serialVersionUID = 1L;    private String name;    private String description;    private double 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;    }    public double getPrice() {        return price;    }    public void setPrice(double price) {        this.price = price;    }    public static long getSerialversionuid() {        return serialVersionUID;    }}
View Code

ProductForm代码如下,和Product类唯一区别就是不用实现Serializable接口:

public class ProductForm {    private String name;    private String description;    private double 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;    }    public double getPrice() {        return price;    }    public void setPrice(double price) {        this.price = price;    }}
View Code

DBOperator类包含两个方法,一个是执行sql语句,一个是从数据库中查询数据:

 

public class DBOperator {    private JdbcTemplate jdbcTemplate;    //通过setter的方式实现依赖注入    public void setJdbcTemplate(JdbcTemplate jdbcTemplate){        this.jdbcTemplate = jdbcTemplate;    }    public Map query(String sql,int id){        Map productInfo = this.jdbcTemplate.queryForMap(sql, id);        return productInfo;    }    public void insert(String sql,Object[] obj){        this.jdbcTemplate.update(sql, obj);    }}
View Code

  服务层的ProductService和实现类ProductServiceImpl如下,ProductServiceImpl类中通过@Autowired和@Service进行DBOperator对象的依赖,@Autowired注解会使DBOperator的一个实例被注入到ProductServiceImpl实例中,为了能是类能被spring扫描到,必须为其标注为@Service。

 

public interface ProductService {    public Long addProduct(Product product);    public Product queryProduct(long productID);}@Servicepublic class ProductServiceImpl implements ProductService{    //生成产品的ID,是数据库表中的主键    private AtomicLong generator = new AtomicLong();        @Autowired    private DBOperator operator;    @Override    public Long addProduct(Product product) {        // TODO Auto-generated method stub        Long id = generator.incrementAndGet();        String name = product.getName();        String description = product.getDescription();        double price = product.getPrice();        Object[] obj = new Object[]{id,name,description,price};        String sql = "insert into t_product values(?,?,?,?)";        operator.insert(sql,obj);        return id;    }    @Override    public Product queryProduct(long productID) {        // TODO Auto-generated method stub        String sql = "select * from t_product where id=?";        Map productInfo = this.operator.query(sql,(int)productID);        String name = (String) productInfo.get("name");        String description = (String) productInfo.get("description");        double price = (double) productInfo.get("price");        Product product = new Product();        product.setDescription(description);        product.setName(name);        product.setPrice(price);        return product;    }}
View Code

  当然最重头戏的还是ProductController类,该类中的方法通过RequestMapping指定Request和Handler的对应关系,而在saveProduct方法的参数中通过RedirectAttribute实现页面的重定向。

@Controllerpublic class ProductController {    private static final Log logger = LogFactory.getLog(ProductController.class);        @Autowired    private ProductService productService;        @RequestMapping(value="/productInput")    public String inputProduct(){        //logger.info("inputProduct called");        return "ProductForm";    }        @RequestMapping(value="/productSave", method=RequestMethod.POST)    public String saveProduct(ProductForm productForm, RedirectAttributes redirectAttributes){        //logger.info("saveProduct called");        Product product = new Product();        product.setName(productForm.getName());        product.setDescription(productForm.getDescription());        product.setPrice(productForm.getPrice());        //add product        Long productID = productService.addProduct(product);        redirectAttributes.addAttribute("message", "The product was successfully added.");        return "redirect:/product_view/" + productID;    }        @RequestMapping(value="/product_view/{id}")    public String viewProduct(@PathVariable Long id, Model model){        Product product = productService.queryProduct(id);        model.addAttribute("product", product);        return "ProductDetails";    }}
View Code

  如下是web.xml配置文件,应用servlet和servlet-mapping元素,servlet元素内的<load-on-startup>元素是可选的。如果存在,则它将在应用程序启动时装载servlet并调用它的init方法,若不存在,则在该servlet的第一个请求时加载,可以通过<init-param>中的<param-value>元素指定配置文件的路径,如果没有<init-param>元素,则默认路径为程序的WEB-INF目录下的servletName-servlet.xml。

springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
/WEB-INF/config/springmvc-config.xml
1
springmvc
/

  如下是配置文件(springmvc-config.xml),其中包括指定控制器类所在的包、默认访问路径请求的html、配置数据源(注意用户名和密码需要改为自己数据库的用户名和密码)通过setter的方式在DBOperator对象中注入jdbcTemplate对象,最后通过viewResolver指定视图文件所在的路径以及后缀。

商品表单视图(ProductForm.jsp)文件如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
商品信息
Add a product

商品详细信息表单(ProductDetail.jsp)问价如下:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"    pageEncoding="ISO-8859-1"%>
Save Product

The product has been saved.

Details:
Product Name: ${product.name }
Description: ${product.description }
Price: $${product.price }

  最后在Tomcat服务器下运行该web程序,报logging版本冲突异常(You have more than one version of 'org.apache.commons.logging.Log' visible,),将导入的jar包中的commons-logging-1.2.jar删除即可,并在浏览器地址栏中输入:http://localhost:8081/SpringMVC/productInput,即可实现对ProductForm.jsp视图的访问,然后输入商品信息,点击Add Product按钮,即可将商品信息添加到数据库(需要提前创建数据库(User)和数据库中的表(t_product(id,name,description,price))),并从数据库中查询插入信息并在ProductDetail.jsp视图中显示。

        

转载于:https://www.cnblogs.com/zhanglei93/p/6264796.html

你可能感兴趣的文章
ubuntu下如何查看用户登录及系统授权相关信息
查看>>
秋季学期学习总结
查看>>
SpringBoot 优化内嵌的Tomcat
查看>>
【LaTeX】E喵的LaTeX新手入门教程(1)准备篇
查看>>
highcharts曲线图
查看>>
extjs动态改变样式
查看>>
PL/SQL Developer 查询的数据有乱码或者where 字段名=字段值 查不出来数据
查看>>
宏定义
查看>>
笔记:git基本操作
查看>>
生成php所需要的APNS Service pem证书的步骤
查看>>
JavaWeb之JSON
查看>>
HOT SUMMER 每天都是不一样,积极的去感受生活 C#关闭IE相应的窗口 .
查看>>
windows平台上编译mongdb-cxx-driver
查看>>
optionMenu-普通菜单使用
查看>>
2016-2017-2点集拓扑作业[本科生上课时]讲解视频
查看>>
appium(13)- server config
查看>>
IIS负载均衡-Application Request Route详解第六篇:使用失败请求跟踪规则来诊断ARR...
查看>>
管理信息系统 第三部分 作业
查看>>
[Leetcode Week13]Search a 2D Matrix
查看>>
查看端口占用cmd命令
查看>>