• 第四章节-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>
    

      

      

      

      

     

      

  • 相关阅读:
    CentOS 7 下Emacs无法录入中文的问题
    GPS文件中的C1--->P1转换
    centos7上搭建http服务器以及设置目录访问
    在Linux和Windows之间的远程控制的实现
    Emacs中的代码折叠控制
    Fortran程序调试中的“吐核”错误
    CentOS 7.6 系统上添加最新版 NetCDF 4.6.1
    迁移 Emacs 的自定义设置
    CentOS 7系统上制作Clonezilla(再生龙)启动U盘并克隆双系统
    [CentOS 7] TexLive2017中kpsewhich Bug的修复
  • 原文地址:https://www.cnblogs.com/chuiyuan/p/4617729.html
Copyright © 2020-2023  润新知