SpringMVC(二)

来源:互联网 发布:ubuntu输入法设置中文 编辑:程序博客网 时间:2024/06/17 15:46

参数传递(View to Controller)

@RequestMapping映射请求

负责将不同请求映射到相对应的控制器上,具体包括四个方面的信息项,请求URL,请求参数,请求方法,请求头。

1)通过请求URL进行映射

package cn.jbit.web;import org.apache.log4j.Logger;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;@Controller//对类标注使其成为一个可以处理HTTP请求的控制器public class IndexController{    private Logger logger=Logger.getLogger(IndexController.class);    //对方法index()进行注解,也确定了index()方法对应的url是@RequestMapping后面紧跟的("index")    @RequestMapping("index")    public String index(@RequestParam String username){//绑定请求参数        logger.info("HELLO,"+username);        return "index";//返回index字符串,通过视图解析器转换为真正的View(/WEB-INF/jsp/index.jsp)    }}

存在问题:不传入参数会报错。
这里写图片描述
这里写图片描述

注意:RequestMapping不仅可以注解在方法处,也可以注解在类上。

package cn.jbit.web;import org.apache.log4j.Logger;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;@Controller//对类标注使其成为一个可以处理HTTP请求的控制器@RequestMapping("index")public class IndexController{    private Logger logger=Logger.getLogger(IndexController.class);    //对方法index()进行注解,也确定了index()方法对应的url是@RequestMapping后面紧跟的("index")    @RequestMapping("/index")    public String index(@RequestParam String username){        logger.info("HELLO,"+username);        return "index";//返回index字符串,通过视图解析器转换为真正的View(/WEB-INF/jsp/index.jsp)    }}

此时的地址栏地址为:http://localhost:8080/SSM1/index/index?username=hh

这种方式可以便于业务的管理。

2)通过请求参数,请求方法进行映射

@RequestMapping还可以通过请求参数,请求方法来映射请求。通过多条件可以让映射更加精确。

package cn.jbit.web;import org.apache.log4j.Logger;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;@Controller//对类标注使其成为一个可以处理HTTP请求的控制器public class IndexController{    private Logger logger=Logger.getLogger(IndexController.class);    //value表示请求的url,method表示请求方法,params表示请求参数    @RequestMapping(value="index",method=RequestMethod.GET,params="username")    public String index(@RequestParam String username){        logger.info("HELLO,"+username);        return "index";    }}
访问地址:http://localhost:8080/SSM1/index?username=hsh

注意:上述代码中,value表示请求的url,method表示请求方法(GET或者POST方法),params表示请求参数,三者条件都匹配才能进入方法index()。即url必须是index,method必须为get方法,params必须是username才行。


@RequestParam

之前的不传入参数会报错的问题没有解决,需要通过RequestParam解决。

通过@RequestParam注解指定其对应的请求参数。@RequestParam有三个参数:
1.value:参数名
2.required:是否必须,默认为true,表示必须包含参数名否则异常。
3.defaultValue:默认参数,一般不使用。

package cn.jbit.web;import org.apache.log4j.Logger;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;@Controller//对类标注使其成为一个可以处理HTTP请求的控制器public class IndexController{    private Logger logger=Logger.getLogger(IndexController.class);    @RequestMapping("index")    public String index(@RequestParam(value="username",required=false) String username){        logger.info("HELLO,"+username);        return "index";    }}

此处required设置成false,则地址栏不输入username参数也不会报错,只是logger会显示空值。


参数传递(Controller to View)

SpringMVC提供了多种方式输出数据模型

1.ModelAndView

ModelAndView既包含视图信息又包含模型数据。

常用方法

1.添加模型数据

ModelAndView.addObject(String attributeName,Object attributeName)

第一个参数为key,第二个参数为Value,注意数据类型。

ModelAndView.addAllObject(Map<String,?> modelMap)

数据模型其实就是一个map对象,可以添加map对象到model中。

2.设置视图

void setView(View view)

指定具体视图对象

void setViewName(String viewName)

指定一个逻辑视图名,String类型

package cn.jbit.web;import org.apache.log4j.Logger;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.servlet.ModelAndView;@Controller//对类标注使其成为一个可以处理HTTP请求的控制器public class IndexController{    private Logger logger=Logger.getLogger(IndexController.class);    @RequestMapping("index")    public ModelAndView index(@RequestParam(value="username",required=false) String username){        logger.info("HELLO,"+username);        ModelAndView mav=new ModelAndView();        //传模型数据        mav.addObject("name", username);        //添加视图        mav.setViewName("index");        return mav;    }}
<%@ page language="java" contentType="text/html; charset=utf-8"    pageEncoding="utf-8"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %><!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>Insert title here</title></head><body><h1>Hello,SpringMVC</h1>${name} </body></html>

这里写图片描述

2.Model

还可以使用SpringMVC提供的Model对象来完成数据传递,直接使用model对象入参,把数据模型username传入model中即可,model对象也是一个map类型的数据结构,对于key的指定可有可无,没有key时默认对象类型作为key,例如string(注意一定是小写不是大写)。

案例:

@Controller//对类标注使其成为一个可以处理HTTP请求的控制器public class IndexController{    private Logger logger=Logger.getLogger(IndexController.class);    @RequestMapping("index")    public String index(@RequestParam(value="username",required=false) String username,Model model){        logger.info("HELLO,"+username);        model.addAttribute("name", username);//有key        model.addAttribute(username);//没有key        return "index";    }}
<body><h1>Hello,SpringMVC</h1><h1>有key${name}</h1><h1>没有key${string}</h1> //注意,此处string一定是小写的</body>

这里写图片描述

3.Map

和model入参方法类似,不过推荐使用model。

@Controller//对类标注使其成为一个可以处理HTTP请求的控制器public class IndexController{    private Logger logger=Logger.getLogger(IndexController.class);    @RequestMapping("index")    public String index(@RequestParam(value="username",required=false) String username,Map<String,Object> map){        logger.info("HELLO,"+username);        map.put("name", username);        return "index";    }}

4.@ModelAttribute

将入参的数据对象放到数据模型。

5.@SessionAttributes

将模型中的属性存入HttpSession中,以便在多个请求之间共享该属性。


单例模式:

单例模式即系统运行期间,有且仅有一个实例。
要满足三个点:
1.一个类仅有一个实例(最基本要求),需要类只能提供私有的构造器,保证不能随意创建该类的实例。
2.必须自行创造这个实例,自定义本类的私有(private)静态(static)对象,以便向外界提供时使用。
3.必须自行向这个系统提供这个实例。即必须提供一个静态共有方法(public static XX()),该方法创建或者获得它本身的私有对象并返回。

两种实现方法:
1.懒汉模式
对于懒汉模式,我们可以这样理解:该单例类非常懒,只有在自身需要的时候才会行动,从来不知道及早做好准备。它在需要对象的时候,才判断是否已有对象,如果没有就立即创建一个对象,然后返回,如果已有对象就不再创建,立即返回。
懒汉模式只在外部对象第一次请求实例的时候才去创建。

//类加载时不创建实例,调用getInstance()方法才能有实例。public static synchronized ConfigManager getInstance(){//用到了同步锁保证线程安全    if(ConfigManager==null){    configManager=new ConfigManager();    }    return configManager;}

2.饿汉模式
对于饿汉模式,我们可以这样理解:该单例类非常饿,迫切需要吃东西,所以它在类加载的时候就立即创建对象。

...//类加载时直接初始化Private static ConfigManager configManager =new ConfigManager();//饿汉模式public static ConfigManager getInstance(){    return configManager;}

我们对比一下懒汉模式和饿汉模式的优缺点:
懒汉模式,它的特点是运行时获得对象的速度比较慢,但加载类的时候比较快。它在整个应用的生命周期只有一部分时间在占用资源。
饿汉模式,它的特点是加载类的时候比较慢,但运行时获得对象的速度比较快。它从加载到应用结束会一直占用资源。

饿汉模式优化(静态内部类):
要求其具备延迟加载的特性:

public class Singleton {private static Singleton singleton;private Singleton(){    //整个应用运行期间只执行一次的业务代码操作。如读取配置文件等。}public static class SingletonHelper{    private static final Singleton INSTANCE=new Singleton();}public static Singleton getInstance(){    singleton=SingletonHelper.INSTANCE;    return  singleton;}public static Singleton test(){    return singleton;//调用test()未实例化singleton}}
public class Test12 {    public static void main(String[] args) {        System.out.println("Singleton.test()---->"+Singleton.test());        System.out.println("Singleton.getInstance()---->"+Singleton.getInstance());    }//Singleton.test()---->null//Singleton.getInstance()---->test.Singleton@1db9742}

使用ServletAPI对象作为入参

如果我们需要HttpSession对象,就可以直接将HttpSession作为入参使用。

@RequestMapping(value="index",method=RequestMethod.POST)    public String doLogin(@RequestParam String userName,@RequestParam String upwd,HttpSession session,HttpServletRequest request){......}

静态资源文件的引用

由于DispatcherServlet请求映射为“/”,SpringMVC将捕获所以web容器的请求,也包括了静态资源的请求,由于找不到相应处理器,所以静态资源将无法访问。

这里采用<mvc:resources/>标签来解决,首先为方便管理,将静态资源文件(js,css,images等)都放在统一目录下,例如”/WebRoot/statics”,这时在springmvc-servlet.xml中增加配置如下:

<mvc:resources mapping="/statics/**" location="/statics/"

mapping:将静态资源映射到指定路径(/statics)下
location:本地静态资源所在的目录
最后需要修改页面引用静态文件的目录路径,加上“/statics”。