SpringMVC简单例子(二)

来源:互联网 发布:志鸿优化系列丛书2017 编辑:程序博客网 时间:2024/05/22 09:40

1、应用@Autowired和@Service进行依赖注入

将依赖注入到SpringMVC控制器的最简单的方法就是通过注解@Autowired到字段或方法。还有类的依赖注入要注明@Service,指示该类是一个服务,并在配置文件中添加扫描依赖基本包

 <context:component-scan base-package="service"></context:component-scan>

2、代码实例

目录结构

这里写图片描述

ProductController类

@Controllerpublic 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 类增加了

@Autowiredprivate ProductService productService;

给私有字段增加@Autowired注解,还有使用重定向和Flash属性,使用请求参数和路径变量,这两个后面再详细讲。

ProductService接口

ProductService是一个提供各种处理产品方法的接口,上面为productService字段添加@Autowired
注解会使ProductService的一个实例被注入到ProductController实例中

public interface ProductService {    Product add(Product product);    Product get(long id);}

ProductServiceImpl类

注明@Service,使用该类被Spring扫描到

@Servicepublic 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)

运行结果

这里写图片描述
这里写图片描述
这里写图片描述

原创粉丝点击