1、应用@Autowired和@Service进行依赖注入
将依赖注入到SpringMVC控制器的最简单的方法就是通过注解@Autowired到字段或方法。还有类的依赖注入要注明@Service,指示该类是一个服务,并在配置文件中添加扫描依赖基本包
<context:component-scan base-package="service"></context:component-scan>
2、代码实例
目录结构
ProductController类
@Controller
public class ProductController {
private static final Log logger = LogFactory
.getLog(ProductController.class);
@Autowired
private ProductService productService;
@RequestMapping(value = "/product_input")
public String inputProduct() {
logger.info("inputProduct called");
return "ProductForm";
}
@RequestMapping(value = "/product_save", 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(Float.parseFloat(productForm.getPrice()));
Product savedProduct = productService.add(product);
redirectAttributes.addFlashAttribute("message",
"The product was successfully added");
return "redirect:/product_view/" + savedProduct.getId();
}
@RequestMapping(value = "/product_view/{id}")
public String viewProduct(@PathVariable Long id, Model model) {
Product product = productService.get(id);
model.addAttribute("product", product);
return "ProductView";
}
}
以上的ProductController 类增加了
@Autowired
private ProductService productService;
给私有字段增加@Autowired注解,还有使用重定向和Flash属性,使用请求参数和路径变量,这两个后面再详细讲。
ProductService接口
ProductService是一个提供各种处理产品方法的接口,上面为productService字段添加@Autowired
注解会使ProductService的一个实例被注入到ProductController实例中
public interface ProductService {
Product add(Product product);
Product get(long id);
}
ProductServiceImpl类
注明@Service,使用该类被Spring扫描到
@Service
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("JX1 power Drill");
product.setDescription("Powerful hand drill,made to perfection");
product.setPrice(129.99F);
add(product);
}
@Override
public Product add(Product product) {
//添加一个产品,id加1
long newId=generator.incrementAndGet();
//设置id
product.setId(newId);
products.put(newId, product);
return product;
}
@Override
public Product get(long id) {
// TODO Auto-generated method stub
return products.get(id);
}
}
配置文件
< context:component-scan/>元素;一个用于扫描控制器类,另一个用于扫描服务类
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
">
<!-- 扫描包 -->
<context:component-scan base-package="controller"></context:component-scan>
<context:component-scan base-package="service"></context:component-scan>
<!-- 注解驱动 -->
<mvc:annotation-driven></mvc:annotation-driven>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp/"></property>
<!--后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
3、重定向和Flash属性
首先需要知道转发和重定向的区别,转发比重定向快,因为重定向经过客户端,而转发没有,但是若需要重定向到一个外部网站,那么无法使用转发
另外重定向的场景是避免用户重新加载页面是再次调用同样的动作,如:但提交产品表单,saveProduct方法将被调用,并执行相应的动作,实际上是将所描述的产品加入数据库中,但如果我们每次重新加载该页面,那么saveProduct方法又调用一次,同样的产品又被添加一次,所以重定向可以避免用户重新加载页面是再次调用同样的动作,在提交表单后,被重定向到一个ViewProduct页面
return "redirect:/product_view/" + savedProduct.getId();
使用转发可以将属性添加到model,实现传值到目标页面,而重定向经过客户端,所以model的数据在重定向时会丢失,但可以通过Flash属性解决重定向的传值问题
如:
使用Flash attribute需要在配置文件添加mvc:annotation-driven
<mvc:annotation-driven/>
这样Flash attribute会自动设为开启,然后需要在Spring Controller方法添加RedirectAttributes redirectAttributes
@RequestMapping(value = "/product_save", 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(Float.parseFloat(productForm.getPrice()));
Product savedProduct = productService.add(product);
redirectAttributes.addFlashAttribute("message",
"The product was successfully added");
return "redirect:/product_view/" + savedProduct.getId();
}
Flash attributes 在对请求的重定向生效之前被临时存储(通常是在session)中,并且在重定向之后被立即移除
4、路径变量
@RequestMapping(value = "/product_view/{id}")
public String viewProduct(@PathVariable Long id, Model model) {
Product product = productService.get(id);
model.addAttribute("product", product);
return "ProductView";
}
为了使用路径变量,需要在RequestMapping注解的值属性中添加一个变量,用花括号括起来,如
@RequestMapping(value = "/product_view/{id}")
然后在方法添加同名变量,并加上@PathVariable注解,当该方法被调用,请求URL的id值会被复制到路径变量中,并可以在方法中使用。
public String viewProduct(@PathVariable Long id, Model model)
运行结果