SpringMVC实战教程 | 第六篇:SpringMVC表单处理(重定向)

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)

运行结果

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值