学习SpringMVC——通过注解使用SpringMVC
来源:互联网 发布:上瘾网络剧花絮视频 编辑:程序博客网 时间:2024/06/05 20:29
在上一篇博客中,写了一个简单的SpringMVC应用,其中的处理器适配器、处理器映射器、控制类/handler都是通过xml标签配置的。抛开配置的繁琐不说,基于xml的配置存在一个很大的缺点,即一个Controller/Handler类只能处理一个请求,因为只有handleRequest()方法才能处理请求并返回视图。这个问题可以通过注解来解决。相对于xml文件的配置,使用注解使用SpringMVC,具有以下两个优点:
- 一个控制器类可以处理多个请求(动作);
- 代码便于阅读和维护,因为控制器类和请求映射不需要存储在配置文件中,而是直接写在了方法的注解上。
这篇博客将使用注解来修改之前的SpringMVC应用。
一、导入jar包
我在测试的过程中,遇到了这个异常:java.lang.ClassNotFoundException: org.springframework.aop.TargetSource,异常原因是缺少aop的jar包,导入之后一切正常。这里让我很疑惑的是,应用中并没有使用到aop,没有导入这个jar包应该没有问题,这里先不深究,如果有大神知道原因,恳请留言指导。最后的jar包如下图所示:
二、Controller注解
要使用@Controller注解,需要在springmvc.xml文件中指定扫描基础包,如下:
<!-- 指定需要扫描的包 --><context:component-scan base-package="controller"></context:component-scan><context:component-scan base-package="model"></context:component-scan>
实际上,<context:component-scan base-package="###"></context:component-scan>
是Spring框架指定哪些包需要扫描的配置方法。有一个良好的习惯是,不要指定太过广泛的基本包,不要嫌麻烦,有几个包需要扫描就写几个<context:component-scan base-package="###"></context:component-scan>
。
接下来,就可以直接在控制器类添加@Controller注解了,如下:
package controller;import org.springframework.stereotype.Controller;@Controller("inputInfo")public class InputProductController1 { //省略了方法}
三、RequestMapping注解
要使用@RequestMapping注解,需要在springmvc.xml文件中指定以下内容:
<!-- 配置注解适配器 --><bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" /><!-- 配置注解映射器 --><bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
与上述配置方式相比,下面这种配置方式更为推荐:
<mvc:annotation-driven></mvc:annotation-driven><mvc:resources location="/css/" mapping="/css/**"></mvc:resources><mvc:resources location="/*.html" mapping="/"></mvc:resources>
(1)<mvc:annotation-driven></mvc:annotation-driven>
做了很多事情,包括指定注解适配器和注解映射器,还提供了:数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB),读写JSON的支持(Jackson);
(2)<mvc:resources>
指定了哪些静态资源需要单独处理,而不经过前端控制器(DispatcherServlet)处理。在将dispatcherservlet的URL模式设置为“/”时(如下所示),这个标签是必须的,这样可以保证正确地处理静态资源。
<!-- 配置前端控制器DispatcherServlet --><servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc1.xml</param-value> </init-param></servlet><servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern></servlet-mapping>
四、编写Controller类
将之前的SpringMVC应用的Controller类进行修改,这里分别命名为InputProductController1和SaveProductController1,代码如下:
(1)InputProductController1:
package controller;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;@Controller("inputInfo")public class InputProductController1 { private final Log logger = LogFactory.getLog(this.getClass()); @RequestMapping(value="inputProduct") public String inputProduct(){ logger.info("Call the method!"); return "productForm"; } @RequestMapping("/inputProduct1") public ModelAndView inputProduct1(){ logger.info("Call the method2!"); ModelAndView view = new ModelAndView(); view.setViewName("productForm"); return view; }}
上面的代码中,包含了两个方法,使用了两种@RequestMapping的写法,实际上,这两种写法是完全等效的,均指定了方法相对应的URL。
@RequestMapping还有另一个属性method,该属性用来指示方法仅仅处理那些HTTP方法。例如,仅当在HTTP POST方法时,才访问下面的processOrder方法(这个例子与本文中的SpringMVC应用没有任何关系)。
@RequestMapping(value="/processOrder",method="RequestMethod.POST")public String processOrder(){ //do something here return "orderForm";}
(2)SaveProductController1:
package controller;import java.io.UnsupportedEncodingException;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;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 org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.servlet.ModelAndView;import model.Product;@Controllerpublic class SaveProductController1 { private final Log logger = LogFactory.getLog("log"); @Resource() private Product product; @RequestMapping(value="/saveProduct") public ModelAndView saveProduct(HttpServletRequest request,HttpServletResponse response,@RequestParam String name,@RequestParam String description,@RequestParam String price){ logger.info("test"); try { request.setCharacterEncoding("UTF-8"); logger.info(name); logger.info(description); logger.info(price); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } /* product.setName(request.getParameter("name")); product.setDescription(request.getParameter("description")); product.setPrice(request.getParameter("price")); */ product.setName(name); product.setDescription(description); product.setPrice(price); ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("product", product); modelAndView.setViewName("productDetails"); return modelAndView; } @RequestMapping(value="/saveProduct1") public ModelAndView saveProduct1(Product product){ logger.info("saveProduct1 been called!"); ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("product", product); modelAndView.setViewName("productDetails"); return modelAndView; }}
上述代码中使用了@RequestParam注解,该注解代替了request.getParameter方法,可以解析request中的参数。但是这样的写法会导致方法的形参冗长,不便于阅读和后期维护,上述代码中的saveProduct1方法是另一种更加优秀的获取页面请求信息的方法,这种方法需要一个Product类。下面附上Product类的代码和productForm.jsp页面的代码:
Product类
package model;import org.springframework.stereotype.Component;@Component("product")public class Product { 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; }}
productForm.jsp页面:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body> <div id="global"> <form action="saveProduct1" method="post"> <fieldset> <legend>Add a product</legend> <label for="name">Product Name:</label> <input type="text" id="name" name="name" tabindex="1"><br> <label for="description">Description:</label> <input type="text" id="description" name="description" tabindex="2"><br> <label for="price">Price:</label> <input type="text" id="price" name="price" tabindex="3"><br> <div id="buttons"> <label for="dummy"></label> <input id="reset" type="reset" tabindex="4"> <input id="submit" type="submit" tabindex="5"> </div> </fieldset> </form> </div></body></html>
博客内容就写到这里,如有错误之处,还请留言指正。
- 学习SpringMVC——通过注解使用SpringMVC
- SpringMVC-通过注解来使用SpringMVC
- SpringMVC学习笔记——SpringMVC的简单应用(通过注解的方式)
- SpringMVC—注解方式
- springmvc-学习总结-注解
- springMVC注解学习记录
- springmvc 通过注解读取配置文件
- SpringMVC 使用 AOP注解
- springMVC----使用注解开发
- springMVC(二)注解使用
- 【SpringMVC】注解使用
- springMVC注解——@Autowired
- springMVC注解——@Transactional
- SpringMVC注解——@Scheduled
- springMVC—注解开发实例
- SpringMVC—相关注解介绍
- Spring MVC学习总结(18)——SpringMVC事务Transactional注解使用总结
- Spring MVC学习总结(18)——SpringMVC事务Transactional注解使用总结
- Trie——理论知识
- 正则表达式(java)
- css3 transform animation 动画 小结
- atitit 2017年学业计划 v5 r818.xlsx
- 正则表达式速查表
- 学习SpringMVC——通过注解使用SpringMVC
- atitit 课程表终生学习专业进修表从幼儿园到养老院 v2 r818.xlsx
- 20170819WindowsPrj01_02_文件扫描器
- Docker-v17 的层级(layer)概念
- 布丰投针实验(如何将Geogebra动态文件嵌入博客中)
- 缓存架构设计细节二三事
- 猜拳游戏(基于python面向对象1)
- NYOJ-837-Wythoff Game 【威佐夫博奕】
- Maven使用Tomcat热启动问题:java.lang.LinkageError: loader constraint violation