TIP

注解太多了,记不清楚,有的地方得看过几遍才知道讲的是什么,对于有些东西只是知道个大概,加深一下印象。

# 直接从地址栏获取

地址栏中的静态数据,用一组键值对来表示。

<a href="param/getparam?username=srcrs&password=123456">获得参数</a>

在对应响应的方法体中,传入与地址栏“键”的名字一样的变量就可以拿到其对应的“值”。

public String getParam(String username,String password) {
    System.out.println(username+","+password);
    return "success";
}

# 以表单方式将数据封装到javabean中

首先得需要有一个javabean类。

public class Account implements Serializable {
    private String username;
    private String password;
    private Double money;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public Double getMoney() {
        return money;
    }
    public void setMoney(Double money) {
        this.money = money;
    }
}

javabean需要实现序列化,对应的成员属性需要实现setter和getter方法。

然后创建一个与此对应的form表单。

<form action="param/saveAccount" method="post">
    用户名:<input type="text" name="username"><br/>
    密 码:<input type="text" name="password"><br/>
    金 额:<input type="text" name="money"><br/>
    <input type="submit" value="提交">
</form>

DANGER

这里input标签中的name属性尤其要注意,其名需要和javabean中属性名相同。

这里有一个疑问,为什么javabean要实现序列化?

TIP

任何类型只要实现了Serializable接口,就可以被保存到文件中,或者作为数据流通过网络发送到别的地方。

我觉得这个才是关键,因为涉及到了前后端的交互,但是底层不知道如何运行。

对应实现的方法,参数列表可以直接写对应的javabean对象属性名,可以直接通过setter方法赋值。

public String saveAccount(Account account) {
    System.out.println("用户名:"+account.getUsername());
    System.out.println("密 码:"+account.getPassword());
    System.out.println("金 额:"+account.getMoney());
    return "success";
}
  • javabean中若包含对象该如何赋值?

TIP

假如Account中包含User类的实例对象user,User类中有属性uname,uage,则采用user.uname,user.uage即可为user赋值。

  • javabean中包括集合
List<String> lists;
Map<String,Integer> maps;
lists1:<input type="text" name="lists[0]"><br/>
lists2:<input type="text" name="lists[1]"><br/>
maps1:<input type="text" name="maps['one']"><br/>
maps2:<input type="text" name="maps['two']"><br/>

# 解决中文乱码

<!-- 中文乱码过滤器 -->
<filter>
  <filter-name>characterEncodingFilter</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
    <param-name>encoding</param-name>
    <param-value>UTF-8</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>characterEncodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

# @RequestParam

把请求中指定名称的参数给控制器中的形参赋值。就是为了处理绑定参数的时候,当传入的参数名和方法参数名不同赋值失败的问题。

如下所示,当k为name时,而方法中接收的参数使用的是username,这个时候就需要用到这个注解了。

<a href="anno/testRequestParam?name=打啊">跳转</a>
public String testRequestParam(@RequestParam("name") String username) {
    System.out.println(username);
    return "success";
}

# @RequestBody

用于获取请求体内容,直接使用可以得到key=value&key=value形式的数据,不适用get请求。提交一个表单,用户名和密码,在响应的方法参数的前面加上此注解就可以拿到请求体。

<form action="anno/testRequestBody" method="post">
  用户名:<input type="text" name="username"/><br/>
  密 码:<input type="text" name="password"/><br/>
  <input type="submit" value="提交"/>
</form>
public String testRequestParam(@RequestBody String body) {
    System.out.println(body);
    return "success";
}

# @PathVariable

用于绑定url中的占位符,例如,请求url中/delete/{id},这个{id}就叫做url的占位符。是spring3.0之后加入的,是springmvc支持rest风格url的重要标志。

restful风格我也没有用过,也不知道哪好哪不好,看着好像优点像多态,同一路径不同的请求方式会响应不同的方法,而我现在用的就是不同的方法有不同的路径。

@PathVariable("id") 里面的id则占位符也要是id。这样就可以取到id的值了。

<a href="anno/testPathVariable/10">提交</a>
@RequestMapping("/testPathVariable/{id}")
public String testPathVariable(@PathVariable("id") String id) {
    System.out.println(id);
    return "success";
}

# @RequestHeader

获取请求消息头。这个在获取请求头中哪个信息可以用到。

<a href="anno/testRequestHeader">提交</a>
public String testRequestHeader(@RequestHeader("Accept") String header) {
    System.out.println(header);
    return "success";
}

# @CookieValue

把指定cookie名称的值传入控制器方法参数。也就是拿Cookie中的某些值。和@RequestHeader的注解作用差不多都是为了请求头中的值,只不过这个更细化了一些。

<a href="anno/testCookieValue">提交</a>
@RequestMapping("/testCookieValue")
public String testCookieValue(@CookieValue("JSESSIONID") String ssid) {
    System.out.println(ssid);
    return "success";
}

# @ModelAttribute

在SpringMVC4.3以后加入,可以用于修饰方法和参数。出现在方法之前,先执行,它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法。

出现在方法上,获取指定的数据给参数取值。

更通俗的来讲,就是说在某个方法响应之前,另一个方法上有@ModelAttribute注解的会优先响应,例如可以对传入的参数是否合法,是否有空值,可以做一个检测,防止崩溃。

对以下例子执行顺序是:show(),testModelAttribute()。

<a href="anno/testModelAttribute">提交</a>
@RequestMapping("/testModelAttribute")
public String testModelAttribute() {
    System.out.println("testModelAttribute");
    return "success";
}
@ModelAttribute
public void show() {
    System.out.println("show");
}

# @SessionAttribute

可以在session域中增加,查找,删除数据。将一些值放到session域中的好处就是可以跨页面获取到这些值。作用于类之上。

这里如果在某个jsp页面需要使用EL表达式获取到session域中的值,默认是忽略的,需要设置成isELIgnored="false"不忽略。

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
  <h2>跳转页面成功</h2>
  ${sessionScope}
</body>
</html>
<a href="anno/testAddModelAttribute">增加</a>
<a href="anno/testFindModelAttribute">查找</a>
<a href="anno/testDelModelAttribute">删除</a>
/**
 * 增加
 * @param model
 * @return
 */
    @RequestMapping("/testAddModelAttribute")
    public String testAddModelAttribute(Model model) {
        model.addAttribute("msg","srcrs");
        return "success";
    }
/**
 * 查找
 * @param modelMap
 * @return
 */
@RequestMapping("/testFindModelAttribute")
public String testFindModelAttribute(ModelMap modelMap) {
    System.out.println(modelMap.get("msg"));
    return "success";
}
/**
 * 删除
 * @return
 */
@RequestMapping("/testDelModelAttribute")
public String testDelModelAttribute(SessionStatus status) {
    status.setComplete();
    return "success";
}