使用注解方式首先需要更改配置文件,启动注解。修改的 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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<description>Spring MVC Configuration</description>
<!-- 加载配置属性文件 -->
<context:property-placeholder ignore-unresolvable="true" location="classpath:springmvcdemo.properties" />
<!-- 使用Annotation自动注册Bean,只扫描@Controller -->
<!-- <context:component-scan base-package="com.etfox.test.foxb.controller,com.etfox.test.foxb.service" use-default-filters="false">base-package 如果多个,用“,”分隔
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan> -->
<context:component-scan base-package="com.etfox.test.fox*.controller" />
<context:component-scan base-package="com.etfox.test.fox*.service" />
<!-- 默认注解支持 -->
<mvc:annotation-driven />
<!-- 配置SpringMVC的视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="${web.view.prefix}"/>
<property name="suffix" value="${web.view.suffix}"/>
</bean>
<!-- 定义无Controller的path<->view直接映射 -->
<mvc:view-controller path="/" view-name="redirect:${web.view.index}"/>
</beans>
其中 @Controller 是用来标注一个控制器,相当于手动配置一个 bean,只是这里使用注解自动注册 bean 而已,@RequestMapping 注释地址映射,暂且不详细谈,
先贴出使用注解的控制器
/**
* Copyright ©2017 DarkFOX. All rights reserved.
*
* @Title: ProductController.java
* @Prject: SpringMvcDemo
* @Package: com.bwh.test.x00a.controller
* @Description: TODO
* @author: ETFox
* @date: 2017年4月25日 上午9:51:32
* @version: V1.0
*/
package com.etfox.test.foxb.controller;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.etfox.test.foxb.model.Product;
import com.etfox.test.foxb.model.ProductForm;
import com.etfox.test.foxb.service.ProductService;
/**
* @ClassName: InputProductController
* @Description: TODO 使用注解风格的控制器
* @author: ETFox
* @date: 2017年4月25日 上午9:51:32
*/
@Controller
public class ProductController{
private static final Log logger = LogFactory.getLog(ProductController.class);
@Autowired
private ProductService productService;
/**
* @Title: handleRequest
* @Description: TODO 进入录入页面
* @param model
* @return
* @return: String
*/
@RequestMapping("/foxb_input")
public String inputProduct() {
logger.info("InputProductController called");
return "foxb/ProductForm";
}
/**
* @Title: saveProduct
* @Description: TODO 保存产品并且跳转显示页面
* @param pa
* @param model
* @return
* @return: String
*/
@RequestMapping(value="/foxb_save",method=RequestMethod.POST)
public String saveProduct(ProductForm pa, Model model) {
Product product = new Product();
product.setName(pa.getName());
product.setPrice(Double.valueOf(pa.getPrice()));
logger.info("SaveProductController called");
model.addAttribute("product", product);
return "foxb/ProductDetails";
}
/**
* @Title: saveProduct
* @Description: TODO 重定向
* @param pa
* @param redirectAttributes
* @return
* @return: String
*/
@RequestMapping(value="/foxb_save_redirect",method=RequestMethod.POST)
public String saveProduct(ProductForm pa,
RedirectAttributes redirectAttributes) {
Product product = new Product();
product.setId(19961001L);//自定义一个ID,不做其他更改方便理解
product.setName(pa.getName());
product.setPrice(Double.valueOf(pa.getPrice()));
logger.info("SaveProductController called");
Product add = productService.add(product);
logger.info(add.getId()+"--"+add.getName()+"--"+add.getPrice());
redirectAttributes.addFlashAttribute("message", "Test Redirect 传值");
return "redirect:/viewproduct/"+add.getId();//这里的redirect必须是方法映射路径,jsp无效。
}
@RequestMapping("/viewproduct/{id}")
public String viewProduct(@PathVariable Long id ,Model model){
logger.info("===> /viewproduct/${id}"+id);
Product product = productService.get(id);
model.addAttribute("product", product);
return "foxb/ProductDetailsRedirect";
}
}
PRODUCT:
/**
* Copyright ©2017 DarkFOX. All rights reserved.
*
* @Title: Product.java
* @Prject: SpringMvcDemo
* @Package: com.bwh.test.x00a.model
* @Description: TODO
* @author: ETFox
* @date: 2017年4月25日 上午11:51:45
* @version: V1.0
*/
package com.etfox.test.foxb.model;
/**
* @ClassName: Product
* @Description: TODO
* @author: ETFox
* @date: 2017年4月25日 上午11:51:45
*/
public class Product {
public Long id;
public String name;//产品名称
public double price;//价格
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
PRODUCTFORM,用来做数据转换的,相当于翻译,因为Java 的数据类型是多样的,然后 请求中的数据 都是 String 类型的,这里使用这个类来先接受数据,再转换为对应
POJO 中的类型,稍后我们可以用数据绑定来代替这个类,就无需中间的转换 POJO 了:
/**
* Copyright ©2017 DarkFOX. All rights reserved.
*
* @Title: ProductAdmin.java
* @Prject: SpringMvcDemoFox
* @Package: com.etfox.test.foxb.model
* @Description: TODO
* @author: ETFox
* @date: 2017年4月25日 下午5:17:09
* @version: V1.0
*/
package com.etfox.test.foxb.model;
/**
* @ClassName: ProductAdmin
* @Description: TODO
* @author: ETFox
* @date: 2017年4月25日 下午5:17:09
*/
public class ProductForm {
private String name;
private String price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
service:使用
@Service
标注的类
,将自动注册到Spring容器【跑题了。。。也不算,springmvc 和 spring 本就是一家,springmvc 只不过是 spring 的一个组件而已】,扫描注册之后我们可以使用 @Autowired 或者 @Resource 获取它的实例
/**
* Copyright ©2017 DarkFOX. All rights reserved.
*
* @Title: ProductServiceImp.java
* @Prject: SpringMvcDemoFox
* @Package: com.etfox.test.foxb.service
* @Description: TODO
* @author: ETFox
* @date: 2017年4月25日 下午5:57:03
* @version: V1.0
*/
package com.etfox.test.foxb.service;
import org.springframework.stereotype.Service;
import com.etfox.test.foxb.model.Product;
/**
* @ClassName: ProductServiceImp
* @Description: TODO
* @author: ETFox
* @date: 2017年4月25日 下午5:57:03
*/
@Service
public class ProductServiceImp implements ProductService {
/**
* @Title:ProductServiceImp
* @Description:TODO
*/
public ProductServiceImp() {
// TODO Auto-generated constructor stub
System.out.println("ProductServiceImp 构造函数加载。。");
}
/**
* @Title: add
* @Description: TODO
* @param pro
* @return
* @see com.etfox.test.foxb.service.ProductService#add(com.etfox.test.foxb.model.Product)
*/
@Override
public Product add(Product pro) {
Product product = new Product();
product.setId(pro.getId());
product.setName(pro.getName());
product.setPrice(pro.getPrice());
return product;
}
/**
* @Title: edit
* @Description: TODO
* @param id
* @return
* @see com.etfox.test.foxb.service.ProductService#edit(java.lang.Long)
*/
@Override
public Product get(Long id) {
return null;
}
}
其中 controller 中的 return 是对应的响应的视图 , @RequestMapping ,
@RequestMapping
RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
RequestMapping注解有六个属性,下面我们把她分成三类进行说明。
1、 value, method;
value: 指定请求的实际地址,指定的地址可以是URI Template 模式(后面将会说明);
method: 指定请求的method类型, GET、POST、PUT、DELETE等;
2、 consumes,produces;
consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
3、 params,headers;
params: 指定request中必须包含某些参数值是,才让该方法处理。
headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。
比如还是如使用普通方式实现 controller 方式要访问目标页面只要在 URL 后面拼接 requestmapping 后面的地址就可以访问到对应的界面,若控制器类上面也使用了
requestmapping 那么,这个requestmapping 的value 将作为父节点进行访问 127.0.0.1:8080/projectname/a/b ,就可以访问,后续章节,将会贴出围绕这些知识点的 demo工程。