项目目录如下:
Product.java
package com.model;
import java.io.Serializable;
import java.math.BigDecimal;
public class Product implements Serializable {
private static final long serialVersionUID = 123456789L;
private String name;
private String description;
private BigDecimal 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 BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
}
ProductForm.java
package com.model;
public class ProductForm {
private String name;
private String description;
private String 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 String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
ProductService.java
package com.service;
import com.model.Product;
public interface ProductService {
Product add(Product product);
Product get(int id);
}
ProductServiceImpl.java
package com.service;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.stereotype.Service;
import com.model.Product;
import com.service.ProductService;
public class ProductServiceImpl implements ProductService {
private Map<Long, Product> products =
new HashMap<Long, Product>();
private AtomicLong generator = new AtomicLong();
public ProductServiceImpl() {
Product product = new Product();
product.setName("产品1");
product.setDescription("产品简介");
product.setPrice(new BigDecimal(39.99));
add(product);
}
@Override
public Product add(Product product) {
long newId = generator.incrementAndGet();
product.setId(newId);
products.put(newId, product);
return product;
}
@Override
public Product get(long id) {
return products.get(id);
}
}
ProductController.java
package com.mycontroller;
import java.math.BigDecimal;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.model.Product;
import com.model.ProductForm;
@Controller
public class ProductController {
private static final Log logger =
LogFactory.getLog(ProductController.class);
@RequestMapping(value="/input-product")
public String inputProduct() {
logger.info("inputProduct called");
return "ProductForm";
}
@RequestMapping(value="/save-product")
public String saveProduct(ProductForm productForm, Model model) {
logger.info("saveProduct called");
// no need to create and instantiate a ProductForm
// create Product
Product product = new Product();
product.setName(productForm.getName());
product.setDescription(productForm.getDescription());
try {
product.setPrice(new BigDecimal(productForm.getPrice()));
} catch (NumberFormatException e) {
}
// add product
model.addAttribute("product", product);
return "ProductDetails";
}
}
ProductForm.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Product Form</title>
</head>
<body>
<form action="save-product" method="post">
<fieldset>
<legend>Add a product</legend>
<p>
<label for="name">Product Name: </label>
<input type="text" id="name" name="name"
tabindex="1">
</p>
<p>
<label for="description">Description: </label>
<input type="text" id="description"
name="description" tabindex="2">
</p>
<p>
<label for="price">Price: </label>
<input type="text" id="price" name="price"
tabindex="3">
</p>
<p>
<input id="reset" type="reset" tabindex="4">
<input id="submit" type="submit" tabindex="5">
</p>
</fieldset>
</form>
</body>
</html>
ProductDetails.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Product Details</title>
</head>
<body>
<div>
<h4>The product has been saved.</h4>
<p>
<h5>Details:</h5>
Product Name: ${product.name}<br/>
Description: ${product.description}<br/>
Price: $${product.price}
</p>
</div>
</body>
</html>
浏览器访问http://localhost:8080/input-product
下面使用@Autowired和@Service进行依赖注入
dispatcher-servlet.xml添加一项
<!--service-->
<context:component-scan base-package="com.service"/>
ProductServiceImpl.java加入@Service
@Service
public class ProductServiceImpl implements ProductService {
ProductController.java修改如下
package com.mycontroller;
import java.math.BigDecimal;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.model.Product;
import com.model.ProductForm;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.bind.annotation.PathVariable;
import com.service.ProductService;
@Controller
public class ProductController {
private static final Log logger =
LogFactory.getLog(ProductController.class);
@Autowired
protected ProductService productService;
@RequestMapping(value="/input-product")
public String inputProduct() {
logger.info("inputProduct called");
return "ProductForm";
}
@RequestMapping(value = "/save-product", method = RequestMethod.POST)
public String saveProduct(ProductForm productForm, RedirectAttributes redirectAttributes) {
logger.info("saveProduct called");
// no need to create and instantiate a ProductForm
// create Product
Product product = new Product();
product.setName(productForm.getName());
product.setDescription(productForm.getDescription());
try {
product.setPrice(new BigDecimal(productForm.getPrice()));
} catch (NumberFormatException e) {
}
// add product
Product savedProduct = productService.add(product);
redirectAttributes.addFlashAttribute("message", "The product was successfully added.");
return "redirect:/view-product/" + savedProduct.getId();
}
@RequestMapping(value = "/view-product/{id}")
public String viewProduct(@PathVariable Long id, Model model) {
Product product = productService.get(id);
model.addAttribute("product", product);
return "ProductView";
}
}
注解的作用,注解有@Repository,@Service和@Controller等等。
这里拿@Service举例
首先设置自动扫描
<!--自动扫描service包-->
<context:component-scan base-package="com.service"/>
由于上面的设置,spring能找到com.service包下面的类
然后给ProductServiceImpl加入@Service
@Service
public class ProductServiceImpl implements ProductService {
其作用就相当于applicationContext.xml文件里面的:
<bean id="ProductServiceImpl"
class="com.service.ProductServiceImpl" scope="prototype">
</bean>
@Repository,@Service和@Controller这三个没什么功能上的差别,差别只是在语义上,@Repository/@Service/@Controller分别代表了特定语义的类,这个有点类似于HTML 5提出的语义化标签,就像HTML 5里面的“header”和“body”,其实功能上来说没有,只是语义表达的更清楚。
@Autowired注解,即自动装载,ProductService 是一个提供各种Product的接口。为 productService 字段添加 @Autowired 注解会使 ProductService 的一个实例被注入到 ProductController 实例中。相当于类属性的setter方法,使用该注解可以省去手写setter方法。当时使用 为自动连接属性传递的时候,Spring 会将这些传递过来的值或者引用自动分配给那些属性。
这里的ProductService只有一个实现类,spring自动装载了ProductServiceImpl;如果有多个实现类,spring就会不知道你用的是哪个实现类而报错,这时候需要用到@Qualifier注解来区分
Qualifier注解
Spring MVC在每次调用请求处理方法时,都会创建Model类型的一个实例。 若 使用该实例,则可以在方法中添加一个 Model 类型的参数。实际上,还可以使用在方法中添加 ModelAttribute 注解类型来访问 Model 实例。该注解类型也是 org.springframework. web.bind.annotation 包的成员。
ModelAttribute注解