基于注解的Spring mvc 简单了解

来源:互联网 发布:endnote mac 编辑:程序博客网 时间:2024/06/05 19:58

通过一个实例的方式来写这篇博客吧,
假设我现在要创建一个 User

public class User {    private String userName;    private String userPassword;    private Keshi keshi;    /*setter,getter方法*/    }

Keshi(音译:科室)也是一个类

public class Keshi {    private String keshiId;    private String keshiName;    }

现在我想创建一个 User ,创建以前 ,让我们来想想Keshi这个类

Keshi肯定是要从数据库中取出来的,然后在页面给用户选择,不是User自己填写的 。

所以可以把显示填写的用户信息的控制器这样写

@Controllerpublic class KeshiController{    /*@Autowired(required=false)      private KeShiManager keshiService;*/    @RequestMapping(value = {"/keshilist.do"})    public String list(ModelMap model) {            List<Keshi> list=new ArrayList<>();            Keshi keshi1 = new Keshi();            Keshi keshi2 = new Keshi();            keshi1.setKeshiId("1");            keshi1.setKeshiName("测试1");            keshi2.setKeshiId("2");            keshi2.setKeshiName("测试2");            list.add(keshi1);            list.add(keshi2);             model.addAttribute("keshilist",list);            return "userAdd";    }}

当我们不用基于注解的时候,我们需要给我们的Controller直接或者间接实现Controller,并且在xml中配置HandMapping,这样我们的DispatcherServlet才能找出这个Controller,并让他”干活”
说一说这个类:
@Controller
这个注解 是表明这个类可以作为一个Controller类用,当你在webapplicationContext.xml中配置

 <!-- 配置扫描路径,base-package包中的@Controller会被全部扫面, -->        <context:component-scan         base-package="com.annotationController,com.wl.assertManagment.web"/>

如上所示,base-package可以配置你要扫描的包,如果有多个包,框架都会扫描,你也可以配置成base-package =“com”这样com中的所有类和com的子包,都会被扫描.

@RequestMapping(value = {“/keshilist.do”})
@RequeatMapping注解可以用于类上面,也可以用于方法面,表示这个类可以处理“keshilist.do”这个请求。
除此之外,在使用@RequestMapping时,你也可以指定,RequestMethod这个属性
例如:
@RequestMapping(value=”/b.do”, method={RequestMethod.POST,RequestMethod.GET})
POST表明这个方法只处理POST提交的请求,GET不处理,反过来也是一样的。当然这些你可以放在类上面声明,也可以放在方法上声明(方法声明上必须放一个@RequestMapping,这样框架才知道你要调用哪一个方法去处理这个请求)。如果类上加了方法上也加了,那么就是类上的加上方法上的url
比如:类上的是@RequestMapping(value=”/test”),方法上的是@RequestMapping(value=”/index.do”)那么这个类的这个方法对应的请求的路径就是“test/index.do”;

@RequestMapping还有一个params属性,这个属性可以让使用这个属性的Controller获得和MultiController同样的效果,
params要请求指定请求中的参数,例如:

@RequestMapping(method={RequestMethod.GET},params="params=values")

这个标记在某个方法上,表示这个方法处理的请求必须数GET得到的请求,并且请求中必须包含“params=values”这个参数,不仅要求参数的名字是”params”而且要求值必须是“values”,至于这个参数的位置则没有要求,有无其他参数也没有要求,只要有这个参数,并且值符合要求,则就框架就能让这个方法处理。post也一样,
上面的用法难免有点强人所难的嫌疑,所有框架也允许只使用参数名

@RequestMapping(method={RequestMethod.GET},params="params")

这时候,只要你的请求中包含参数名为“params”就行,至于其他的值,位置,有无其他的参数都不重要,框架只认”params”。这时候就能在一个类里面CRUD操作了。(目前我用的最多的就是引导页面。。)
除此之外还有就是params=”!params”同理这是不要出现参数名为“params”的请求。

之后就是方法的参数:
原则上你可以使用普通java的方法所有可以使用的参数,不过使用以下的这些方法,可以更方便:
1.request/response/session
2.org.springframework.web.context.request.WebRequest
3.java.io.InputStream/java.io.Reqder
4.java.io.OutputStream/java.io.Writer
5.java.util.Locale
6.java.util.Map/org.sparingframework.ui.ModelMap
以上这些类,只要你在参数中声明了。框架就能保证你能拿到这些东西,

/*原理是,框架在调用你定义的处理方法前会先拿到这些方法,之后根据你的方法声明,把相应的对象传递进去。*/MaodelAndView mav = ...ModelMap modelMap = new ModelMap();/*调用方法*/processMethod(modelMap)mav.addAllObject(modelMap)return mav;

返回类型
1.ModelAndView(典型的返回类型)
2.String(逻辑视图名字,模型数据根据需要,通过其他途径获取)
3.ModelMap(模型数据,采用默认的规则获取逻辑视图)

<!-- 配置viewResolver -->        <bean id="viewResolver"            class="org.springframework.web.servlet.view.InternalResourceViewResolver">            <property name="prefix" value="/" />            <property name="suffix" value=".jsp" />        </bean> //方法          @RequestMapping(value="/test.do",method={RequestMethod.GET,RequestMethod.POST},params="a")    public void mya1() {        System.out.println("may1");    }    /*以上方法将根据请求名:/test.do  到webContext下去找“test.jsp”*/

4.void(结合String和ModelMap处理)

在返回到我们的例子看一下,定义了一个KeshiController,并模拟产生了keshi的数据,并放到ModelMap中,
这样在页面上就能拿到模型数据中的数据了

 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <title></title>      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">  </head>  <body>   <form action="addUser.do" method="post" name="myform">      <input type="text" name="userName" /><br/>      <input type="password" name="userPassword" /><br/>      <select name="keshi.keshiId" class="form-control" id="sel">        <c:forEach var="keshi" items="${keshilist}">            <option value="${keshi.keshiId}">${keshi.keshiName}</option>        </c:forEach>       </select>      <!--jsp只能传递字符串,不能传递对象,所以不能直接将用户选中keshi类                传给后台,        隐藏域,传递 user.keshi.keshiName-->      <input type="hidden" name="keshi.keshiName" value="${keshilist[0].keshiName}" id="keshiName"/>         <input type="submit" value="提交" />    </form>      </body>  <script>  /*通过js来解决用户选择后,keshiId与keshiName不一致的问题*/    var sel=document.getElementById("sel");    sel.onchange= function(){            document.getElementById("keshiName").value =                 sel.options[sel.selectedIndex].text;            alert(document.getElementById("keshiName").value);        }   </script></html>

UserController

@Controllerpublic class UserController {    @RequestMapping("/addUser.do")    public String addUser(User user) {          return "success";    }}

请求参数到方法参数的绑定
如果你的请求包含参数名,与参数包含的参数名一致,框架就能保证相应的参数能对号入座。
例如:

///mya.do?str=asdasdasd&a=1@RequestMapping(method={RequestMethod.GET,RequestMethod.POST},params="a")    public void mya1(String a, String str) {        ...    //参数的顺序不影响,关键是名字一定要一样    //如果名字不一样,就有可能出问题,    /*如果请求中有一个 ..&age=20,而参数中没有这个名字,或者名字不一样如:'ages',这时框架不能找到名为‘ages’的请求参数,所有会给ages赋一个null,而int是无法接受这个事实的,所有会报错,如果是String或其他应用类型,则就纯粹是一个null*/    }

以上,如果非要用请求参数ages,则可以使用@RequestParam(“name”)

@RequestParam(“name”)
这个注释可以绑定请求参数到方法参数的对应关系
例如:

@RequestMapping(method={RequestMethod.GET,RequestMethod.POST},params="a")    public void mya1(@RequestParam("age") int ages, String str) {        /*这样请求参数的age,就可以绑定到ages上了*/    }    /*如果@RequestParam(“name”)标明的请求参数不存在,程序会抛出异常,@RequestParam的required属性,默认是‘true’,所有会抛出异常,可以改成‘false’*/    @RequestMapping(method={RequestMethod.GET,RequestMethod.POST},params="a")    public void mya1(@RequestParam(value="age",required=false) int ages, String str) {        /*这样即使请求参数不包含age,也不会抛出异常*/    }

指定javaBean对象应用
如上面我们的例子,方法参数可以使用对象,只要给javaBean提供setter方法,并且请求参数名称与javaBean对应的属性名称一样就,框架就能保证数据绑定正确。
如果你想传一个对象过去是不行的,因为,请求参数的传递只能是传字符,jsp会把你的keshi对象换成toString()得到的字符串

这里写图片描述
或者
这里写图片描述
(看你有没有重写keshi的toString()方法)
jsp会把字符“com.wl.assertManagment.web.Keshi@1519077”传递给UserController进行数据绑定,你试图将一个String赋值给一个类。肯定不行,所有会抛出异常
这里写图片描述
所有你要么在传递keshiId然后在UserController中调用方法查找出对应的keshi对象,赋值,要么,想我这样通过一个隐藏域将name传递过去,这里是keshi的属性不多,如果属性很多,推荐在后台赋值。也可以写一个自己的“ editors or conversion strategy ”
太麻烦了,(中间有一次手残,写好了,没发表,点了关机,辛辛苦苦写的全没了,内心几乎是崩溃的。)以后还是要分开写。。。有时间更新

1 0
原创粉丝点击