SpringMVC 基础笔记(一)

来源:互联网 发布:战网更新网络错误 编辑:程序博客网 时间:2024/06/07 05:26

SpringMVC 处理模型:

1、所有request请求,如果需要交由SpringMVC处理,必须在DispatcherServlet对请求进行处理

2、所有请求根据请求的信息,通过handlerMapping进行获得相关的Handler映射。

3、根据handler的映射信息,获得handler然后通过handlerAdapter对handler进行统一封装代用。

3、然后根据handler的处理获得相应的ModelAndView,然后通过ModelAndView获得请求的模型数据和需要进行response的视图信息

4、根据ModelAndView中的视图信息调用ViewResolver,获得相应的视图(JSP等)

5、根据实际的视图进行response渲染,并返回给客户端


其中controller就是我们的handler然后通过handlerAdapter进行适配,至于我们的DefaultAnnotationHandlerMapping是通过@RequestMapping进行标识。可以发现其实HandlerMapping和HandlerAdapter、ViewResolver的实现类都可以进行调整的,当然默认已经几乎够用了。


首先对SpringMVC进行配置,我们需要配置web.xml 因为需要声明DispatcherServlet 截获所有请求,第二需要在web.xml中定义SpringMVC的配置文件。

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee             http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"         version="3.1">    <display-name>Spring Review Web Application</display-name>    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>            classpath:applicationContext.xml        </param-value>    </context-param>    <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>    <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:mvc.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>
可以见到有contextConfigLocation配置定义了SpringMVC的配置文件位置。当然这不是唯一定义SpringMVC配置文件位置的方式:

1、不写配置文件的位置,默认为servlet-name的名字+servlet.xml,以上面为例:servlet-name为springMvc,默认配置文件为:/WEB-INF/springMvc-servlet.xml

2、配置namespace,如果配置namespace的情况下,配置文件的位置和文件名是:/WEB-INF/<namespace>.xml。

3、第三种方式就是上面那种,也是我经常使用的一种,因为我用maven创建项目,所有配置文件习惯放在resource列表中。


当然也有一些不常用的属性这里也列出一下:

1、publishContext: boolean类型的属性,默认为true。决定是否将WebApplicationContext 发表到ServletContext的属性列表中。调用者可以使用servletContext找到WebApplicationContext实例,对应的属性名为DispatcherServlet#getServletContextAttributeName()返回值。

2、publishEvents:boolean类型属性,当DispatcherServlet处理完一个请求后,是否需要向容器发布一个ServletRequestHandlerEvent事件,默认为true,如果容器中没有监听可以设置为false来提高运行性能。


SpringMVC配置文件

其实SpringMVC配置文件和Spring的基本配置文件差不多。但是最重要的概念是,Spring容器和SpringMVC容器的关系,SpringMVC的容器是作为Spring容器的子容器。所以SpringMVC容器中的bean能够访问Spring容器中的资源,但是反过来则不可以。

<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.xsd        http://www.springframework.org/schema/context        http://www.springframework.org/schema/context/spring-context.xsd        http://www.springframework.org/schema/mvc        http://www.springframework.org/schema/mvc/spring-mvc.xsd">    <context:component-scan base-package="com.maxfunner"/>    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"          p:prefix="/WEB-INF/views/" p:suffix=".jsp" p:order="2"    ></bean></beans>

这里首先定义了关于组建的扫描的包起始位置,当然这里最重要是controller的扫描。这里我们定义了viewResolver是InternalResourceViewResolver,这个viewResolver稍后会详细详解,这里定义了InternalResourceViewResolver的作用是,定义从handler获得的视图位置解释。例如:我们从控制器返回一个“login”字符串,则将会解释视图为/WEB-INF/views/login.jsp的视图,然后将这个视图进行渲染和响应。


然后我们做一个简单的控制器

@Controller@RequestMapping("/user")public class UserController {    @Autowired    UserService userService;    public UserService getUserService() {        return userService;    }    public void setUserService(UserService userService) {        this.userService = userService;    }    @RequestMapping("/register.html")    public String registerHtml() {        return "user/register";    }    @RequestMapping("/login.html")    public String loginHtml() {        return "user/login";    }    @RequestMapping("/register.action")    public ModelAndView registerAction(User user) {        this.userService.saveUser(user);        ModelAndView modelAndView = new ModelAndView();        modelAndView.setViewName("user/main");        modelAndView.addObject("user", user);        return modelAndView;    }    @RequestMapping("/{userId}")    public String getUserById(@PathVariable("userId") int userId, ModelMap modelMap) {        modelMap.put("user", this.userService.getUserById(userId));        return "user/main";    }    @RequestMapping(value = "/list")    public String userList(int begin, int end, ModelMap modelMap) {        List<User> userList = this.userService.getUserByIdRange(begin, end);        modelMap.addAttribute("userList", userList);        return "user/list";    }    @RequestMapping(value = "/login.action", params = {"username=admin"})    public ModelAndView adminLogin(String username, String password) {        ModelAndView modelAndView = new ModelAndView();        User user = this.userService.login(username, password);        modelAndView.addObject("user", user);        modelAndView.setViewName("user/main");        System.err.println(">>>>>>> adminLogin !!!");        return modelAndView;    }    @RequestMapping(value = "/login.action", params = {"username!=admin"})    public ModelAndView normalLogin(String username, String password,                                    @CookieValue("JSESSIONID") String jsessionId) {        ModelAndView modelAndView = new ModelAndView();        User user = this.userService.login(username, password);        modelAndView.addObject("user", user);        modelAndView.setViewName("user/main");        System.err.println(">>>>>>> normalLogin !!! " + jsessionId);        return modelAndView;    }}

这里可以看见很多种获http请求信息绑定的方式,首先解释几件事:

@RequestMapping:@RequestMapping 为响应的方位URL,这个是针对于项目而然的,这里的RequestMapping 在类的头部也有定义,方法也有定义。在类中定义是非必要的,但是一般我们都会这样做,原因是为了对类进行URL分类。如果用户访问路径为/user/login.html 则这里会访问到loginhtml方法当中。如果我们没有定义类的RequestMapping则 用户访问loginHtml则用户的访问路径为/login.html。然而@RequestMapping最重要的是将请求匹配到相应的处理方法当中,所以匹配方式可以有如下这些:

1、@RequestMapping("/user/*/main") 使用通配符进行多个url匹配到单个处理方法当中,通配符*一个路径下的任意目录名称(不包括子目录),通配符**则为一个路径下的任意目录名称(包括子目录),?代表匹配任意字符。举个例子:/user/*/main 匹配 /user/ab/main  /user/dd/main ... ,  /user/**/main 匹配 /user/admin /user/ccd/dd/main /user/add/admin ... , /user/??/main 匹配 /user/dd/main  /user/da/main

2、对请求参数的访问限制:我们可以通过@RequestMapping的param的属性对其进行控制,例子:

@RequestMapping(value = "/login.action", params = {"username=admin"})   如果username参数值为admin 则映射到这个处理方法当中。

 @RequestMapping(value = "/login.action", params = {"username!=admin"}) 如果username参数值不等于admin 则映射到这个处理方法中。

除此之外,!admin则代表请求不包含admin的参数,admin则代表请求包含admin参数。当然如果多个条件可以使用“,” 分开。

3、对请求方法(method)进行绑定,@RequestMapping(value = "/register.action",method = RequestMethod.POST) 这个处理方法 请求method为post才会访问。

4、@RequestMapping 还可以将我们传入的URL作为一个占位符,然后将这个占位符相应的实际路径并定到处理方法的参数中,例子:

    @RequestMapping("/{userId}")
    public String getUserById(@PathVariable("userId") int userId, ModelMap modelMap) {
        modelMap.put("user", this.userService.getUserById(userId));
        return "user/main";
    }


入参绑定

一般情况下,我们最简单就是讲参数名称定义为提交的参数名称一致,spring就会为我们进行绑定,当然我们可以使用@RequestParam进行参数绑定,而且这@RequestParam提供了参数的一些绑定方式,例如这个参数是否必须、参数名是什么等


@RequestParam

value -->参数名称

required --> 这个参数是否为必要参数,默认为true

defaultValue ---> 默认参数,这个设置了required自定设置为false。而且极少情况会使用到这个参数。

@RequestMapping(value = "/login.action", params = {"username=admin"})
    public ModelAndView adminLogin(@RequestParam(value = "username",required = true) String username,@RequestParam(value = "password",required = true)  String password) {
        ModelAndView modelAndView = new ModelAndView();
        User user = this.userService.login(username, password);
        modelAndView.addObject("user", user);
        modelAndView.setViewName("user/main");
        return modelAndView;
    }


@CookieValue 将Cookie参数绑定到处理方法的参数上:

@RequestMapping(value = "/login.action", params = {"username!=admin"})
    public ModelAndView normalLogin(String username, String password,@CookieValue(value = "JSESSIONID",required = false) String jsessionId)


@RequestHeader 将请求头信息绑定到参数中:

@RequestMapping("/index.html")
public String index(@RequestHeader("Accept-Encoding") String encoding) {
      return "user/index";

 }


对form表单的参数封装对象直接绑定:

@RequestMapping(value = "/register.action", method = RequestMethod.POST)
    public ModelAndView registerAction(User user) {
        this.userService.saveUser(user);
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("user/main");
        modelAndView.addObject("user", user);
        return modelAndView;
  }

则请求参数的名称和User对象的属性名称一致,spring会进行对象的创建和对应属性的绑定操作。


绑定Servlet API对象作为处理方法的入参:

@RequestMapping("/index.html")public String index(HttpServletRequest request, HttpServletResponse response, HttpSession session) {    return "user/index";}

Spring会根据参数进行动态绑定,非常方便。然而SpringMVC也提供了一个代理原生ServletAPI对象的接口,WebRequest。


我们甚至可以使用OutputStream作为处理方法中的入参:

@RequestMapping("/userImage")public void getImage(OutputStream outputStream) throws IOException {    Resource resource = new ClassPathResource("/timg.jpeg");    FileCopyUtils.copy(resource.getInputStream(),outputStream);}

访问相关路径会获得一张图片



原创粉丝点击