Categories

Tags

springMVC入门(三)

项目目录如下:

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注解