第四章节-Spring MVC介绍(注解方式——二)

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

将依赖注入到Spring MVC控制器最简单的方法是通过注释@Autowired到字段或方法。

为了能作为依赖注入,类一定要声明成@Service,它表示类是一个服务。另外在配置文件中还要添加一个

<component-scan />元素来扫描依赖基本包。

<context: component-scan basepackage="dependencyPackage"/>

二、重定向和Flash属性

转发与重定向的不同:转发更快,因为重定向要经过客户端,而转发没有。

但是有时候用重定向更好,若要重定向到一个外部的网站,转发无法实现。

使用重定向不方便的一个地方是,不能轻松的传值给目标页面,而转发则可以简单的将属性添加到Model中,使目标视图可以文章。由于重定向经过了客户端,所以Model中的值在重定向时

丢失了。但是我们在Spring 3.1和更新的版本中,可以用Flash属性来进行重定向传值。

这里,我们在Spring MVC文件中要配置一个<annotation-driven/>元素,然后,还要在方法上添加一个新的参数类型RedirectAttribute.

三、请求参数和路径变量

请求参数与路径变量都可以用来发送值到服务器。二者都是URL的一部分。

  • 请求参数

采用 key= value的形式,并用&分隔。如下带有一个productId的请求参数。

http://localhost:8080/app04b/product_retrive?productId=3

在传统的方法中,我们用下面的方法来得到一个请求参数的值。

String productId=httpServletRequest.getParmeter("productId");

在Spring MVC中,我们有更简单的方法来得到请求参数的值:通过 RequestParam注释类型来注释方法参数 。如下

public void sendProduct(@RequestParam int productId )

@RequestParam注解的参数不一定是字符串。

  • 路径变量

类似请求变量,但是没有key部分,只是一个值。如在app04bk ,

/product_view/productId 

其中productId用来表示产品标识符的一个整数,用来发送一个值到服务器。

@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注解的值属性中添加一个变量。上面的例子中定义了一个名为id的路径变量。

然后在方法签名中添加同名的变量,并加上@PathVariable注解,当这个方法被调用的时候,请求URL的id 值将复制到路径变量中,这样就可以在方法中使用。路径变量的类型可以不是字符串,

Spring MVC将尽力转换成非字符串类型。

可以在请求中使用多个路径变量,如下

@RequestMapping (value="/product_view/{userId}/{orderId}")

有时候使用路径变量,浏览器会误解路径变量,略。

四、@ModelAttribute

前面说到,Spring MVC在每次调用 请求处理方法时,都会创建Model类型的一个实例 。如果我们要用这个实例,可以在方法中添加一个 Model类型的参数。还可以使用在方法中添加添加

ModelAttribute注释类型来访问Model实例。

1. 带@ModelAttribute注解的方法会将它输入的或者创建的参数对象添加到Model对象中(若方法中没有显式的添加)

如下

@RequestMapping (method=RequestMethod.POST)
public String submitOrder(@ModelAttribute("newOrder") Order order, Model model)
{
     ....
}

输入或者创建的Order实例将用newOrder键值添加到Model对象中,如果没有key,则使用这个对象类型的名字。如下面的会使用key="order"将Order实例添加到Model对象中。

public String submitOrder(@ModelAttribute Oder order, Model model)

2. @ModelAttribute 的第二个用处是标注一个非请求的处理方法

被@ModelAttribute标注的方法会在每次调用 这个控制器的请求处理方法前被调用,被标注的方法可以返回

 > 一个对象

如果返回一个对象,则返回的对象会自动添加到Model中。如

@ModelAttribute
public Product addProduct(@RequestParam String productId){
    return productSerivce.get(productId);
}

> void 类型  

这里,一定要添加一个Model类型的参数,并自行将实例添加到Model中。如下

@ModelAttribute 
public void populateModel(@RequestParam String id ,Model model){
    model.addAttribute(new Account(id));
}

五、例子

  • 工程目录

  • Controller代码
@Controller
public class ProductController {
	private static final Log logger = LogFactory.getLog(ProductController.class) ;
	//使ProductService的一个实例注入到里面,所以后面可以直接用了
	@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");
		//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(Float.parseFloat(productForm.getPrice()));
		} catch (NumberFormatException e) {
			e.printStackTrace();
		}
		// add product using Flash
		Product savedProduct = productService.add(product) ;
		redirectAttributes.addFlashAttribute("message", "the product was added ok") ;
		//重定向
		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";
	}
	
}
  • ProductService

提供一个各种处理产品方法的接口

public interface ProductService {
	Product add(Product product) ;
	Product get(long id) ;
}
  • ProductServiceImpl
//使类可以被扫描到,表示类是一个服务
@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 and drill");
		product.setPrice(129.9F);
		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); 
	}

}
  • web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
		xmlns="http://java.sun.com/xml/ns/javaee"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
	    <init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/config/springmvc-config.xml</param-value>
		</init-param>
        <load-on-startup>1</load-on-startup>    
	</servlet>

    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
  • springmvc-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd     
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
      <!--一个用于扫描控制器类,一个用于扫描服务类  -->
    <context:component-scan base-package="app04b.controller"/>
    <context:component-scan base-package="app04b.service"/>    
    
    <mvc:annotation-driven/>
    <mvc:resources mapping="/css/**" location="/css/"/>
    <mvc:resources mapping="/*.html" location="/"/>
    
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
  • ProductView.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML>
<html>
<head>
<title>View Product</title>
<style type="text/css">@import url("<c:url value="/css/main.css"/>");</style>
</head>
<body>
<div id="global">
    <h4>${message}</h4>
    <p>
        <h5>Details:</h5>
        Product Name: ${product.name}<br/>
        Description: ${product.description}<br/>
        Price: $${product.price}
    </p>
</div>
</body>
</html>

  

  

  

  

 

  

原文地址:https://www.cnblogs.com/chuiyuan/p/4617729.html