SpringMVC请求处理

1.1. 请求路径映射

实际项目中我们要借助@RequestMapping注解定义映射路径。其注解应用位置
类定义处: 提供初步的请求映射信息。
方法定义处: 提供进一步的细分映射信息

@Controller
@RequestMapping("/")//spring-mvc-v1的/  借助此注解定义映射关系,找到映射就能动态执行方法
public class HelloController {
    public HelloController() {
        System.out.println("HelloController.HelloController()");
    }
    @RequestMapping("doSayHello")//url对应的方法对象会存储到map
    public ModelAndView doSayHello(){
        //1.构建ModelAndView对象(作用:封装响应数据和视图信息)
        ModelAndView mv=new ModelAndView();
        //2.封装客户端页码要呈现的数据
        mv.addObject("message","I'm Spring MVC");
        //3.封装要呈现的页面视图信息
        mv.setViewName("index");//此名字会交给视图解析器进行解析
        return mv;//mvc底层会将modelandView中的model对象存储在请求作用域request.setAttribute()
    }
}

1.1.1. 普通url映射

@RequestMapping(value={"/doSayHello", "/user/doSayWelcome"}):
多个URL路径可以映射到同一个处理器的功能处理方法。(多个url映射同一个方法)

@Controller
@RequestMapping("/req/")
public class RequestHandleController {
    /**
     * @RequestMapping告诉springmvc将方法返回值以字符串形式呈现
     * 
     * @return
     */
    @RequestMapping("doReqUrlMap01")
    @ResponseBody
    public String doReqUrlMap01(){
        return "request url mapping请求url映射";
    }
}

控制层写方法,do开头或with开头

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 
 * @author Administrator
 *
 */
@Controller
@RequestMapping("/req/")
public class RequestHandleController {
    /**
     * @RequestMapping告诉springmvc将方法返回值以字符串形式呈现
     * 
     * @return
     */
    @RequestMapping({"doReqUrlMap01","widthReqUrlMap"})
    @ResponseBody
    public String doReqUrlMap01(){
        return "request url mapping,请求url映射";
    }
}

1.1.2. Rest风格url映射

REST即表述性状态传递(英文:Representational State Transfer,简称REST),是一种新的软件架构编码风格,是基于网络应用进行设计和开发的编码方式。可以降低开发的复杂度,提高程序的可伸缩性。例如:

@RequestMapping("/msg/{xxx}")
大括号里的内容相当于一个变量
只要前面/msg/一样,后面什么都行
请求的URL可以是“/msg/hello”或“/msg/welcome”

@RequestMapping("/msg/{id}/create"):

请求的URL可以是“/users/1/create”。

@RequestMapping("/msg/{mId}/topics/{tId}")

这样也是可以的,请求的URL可以是“/users/10/topics/12”。

说明:通过@PathVariable可以提取URI模板模式中的{×××}中的×××变量。

http://localhost:8080/项目名/doUpdate/1.do

package controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 
 * @author Administrator
 *
 */
@Controller
@RequestMapping("/req/")
public class RequestHandleController {
    /**
     * Rest风格url映射
     * 表述性状态传递
     * @return
     */
    @RequestMapping("doReqRestUrlMap{map}")
    @ResponseBody
    public String doReqRestUrlMap02(){
        return "request rest url mapping";
    }
}

2.1. 请求方式映射

2.1.1 请求方式限定

项目中Controller层对象的每个方法默认可以处理任意方式的请求,假如要指定控制层方法只能处理GET或只能处理POST请求,那该如何实现呢?

借助@RequestMapping注解中的method属性指定具体的请求处理方式,例如

@RequestMapping(value=”doSaveObj”,

method=RequestMethod.POST)

public String doSaveObject(Object obj){….}

知识点扩展:

1)@GetMapping 注解应用(定义的映射只能处理get请求)

2)@PostMapping 注解应用(定义的映射只能处理post请求)

2.1.2 请求方式组合

项目中还可在控制层方法上借助@RequestMapping注解中的method属性指定使用哪几种方式处理请求。

@RequestMapping(value=”doSaveObj”,

method={RequestMethod.POST,

RequestMethod.GET})

public String doSaveObject(Object obj){….}

<mvc:annotation-driven/>需要配置

package controller;

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.ResponseBody;

/**
 * 
 * @author Administrator
 *
 */
@Controller
@RequestMapping("/req/")
public class RequestHandleController {
    /**
     * 请求方式映射:如get,post请求等
     * @return
     */
    @RequestMapping(value="doReqMethodMap01",method={RequestMethod.POST,RequestMethod.GET})
    @ResponseBody
    public String doReqMethodMap01(){
        return "requset rest method mapping";
    }

    @GetMapping("doReqMethodMap02")
    @ResponseBody
    public String doReqMethodMap02(){
        return "requset rest get method mapping";
    }
    
    @PostMapping("doReqMethodMap03")
    @ResponseBody
    public String doReqMethodMap03(){
        return "requset rest post method mapping";
    }
}

3.1. 请求参数映射(重点)

3.1.1. 标准Servlet API(了解)

请求映射方法中可以直接使用ServletAPI 中的对象获取参数数据,例如

HttpServletRequest,HttpSession对象等,例如:


@RequestMapping(value="withRequest",method=RequestMethod.GET)

@ResponseBody

 public String withRequest(HttpServletRequest request){

 System. out .println(request.getRequestURI());

  return  "Obtainer 'foo' query parameter value

'"+request.getParameter("gid")+"'";

 }
    @RequestMapping("doReqParam01")
    @ResponseBody
    public String doReqParam01(HttpServletRequest request){
        return "obtain parameter's value is "+request.getParameter("pageCurrent");
    }

访问路径:http://localhost/spring-mvc-v1/req/doReqParam01.do?pageCurrent=2
提示:@ResponseBody注解作用:该注解作用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区,使用情况:返回的数据不是Html标签的页面,而是其他数据格式的数据时,(如Json、xml,普通文本等)使用;

3.1.2 直接量对象(重点)

SpringMVC 请求一个控制层资源时,可以在对应方法中直接使用参数变量接收参数数据,但参数变量的类型建议为对象类型。

    /**直接量(八种对象类型+String+Date)参数的获取*/
    //此方法由DispatcherServlet调用
    //此方法通过反射调用
    //此方法调用参数时如何注入?SpringMVC底层基于参数名进行值的注入
    @RequestMapping("doReqParam02")
    @ResponseBody
    public String doReqParam02(Integer pageCurrent){
        return "obtain parameter's value is "+pageCurrent;
    }

访问地址http://localhost/spring-mvc-v1/req/doReqParam02.do?pageCurrent=3
如果用int替换Integer那么不传值会报500

    @RequestMapping("doReqParam02")
    @ResponseBody
    public String doReqParam02(@RequestParam Integer pageCurrent){
        return "obtain parameter's value is "+pageCurrent;
    }

注解修饰的变量必须给值不然会报400(客户端传递参数不对,不符合服务器端要求,服务器拒收)

    @RequestMapping("doReqParam02")
    @ResponseBody
    public String doReqParam02(@RequestParam("page") Integer pageCurrent){
        return "obtain parameter's value is "+pageCurrent;
    }

http://localhost/spring-mvc-v1/req/doReqParam02.do?page=2

    @RequestMapping("doReqParam02")
    @ResponseBody
    public String doReqParam02(@RequestParam(value="page",required=false) Integer pageCurrent){
        return "obtain parameter's value is "+pageCurrent;
    }

默认是true,false不写参数不会报400 http://localhost/spring-mvc-v1/req/doReqParam02.do

    @RequestMapping("doReqParam02")
    @ResponseBody
    public String doReqParam02(@RequestParam(value="page",required=true) Integer pageCurrent){
        return "obtain parameter's value is "+pageCurrent;
    }

如果required=true,http://localhost/spring-mvc-v1/req/doReqParam02.do会报400

    @RequestMapping("doReqParam02")
    @ResponseBody
    public String doReqParam02(String name,@RequestParam(value="page",required=false) Integer pageCurrent){
        //spring mvc帮我们进行了字符转换
        return "obtain parameter's value is "+pageCurrent+", name is "+name;
    }

http://localhost/spring-mvc-v1/req/doReqParam02.do?page=3&name=liu

<mvc:annotation-driven/>需要配置

@RequestMapping("doReqParam03")
    @ResponseBody
    public String doReqParam03(Date birthday){
        //请求可以直接将日期字符串注入给此对象
        //springMVC默认可以处理的日期格式:yyyy/MM/ddd
        return "obtain parameter's value is "+birthday;
    }

http://localhost/spring-mvc-v1/req/doReqParam03.do?birthday=2008/12/12

    @RequestMapping("doReqParam03")
    @ResponseBody
    public String doReqParam03(@DateTimeFormat(pattern="yyyy-MM-dd")Date birthday){
        //请求可以直接将日期字符串注入给此对象
        //springMVC默认可以处理的日期格式:yyyy/MM/ddd
        //springMVC可以借助@DateTimeFormat注解处理指定格式,假如客户端请求中传递的日期格式不匹配,会出现400异常
        return "obtain parameter's value is "+birthday;
    }

http://localhost/spring-mvc-v1/req/doReqParam03.do?birthday=2008-12-12

<mvc:annotation-driven/>需要配置

    @RequestMapping("doReqParam04")
    @ResponseBody
    //可变参数
    public String doReqParam04(Integer...ids){
        return "obtain parameter's value is "+ids;
    }

http://localhost/spring-mvc-v1/req/doReqParam04.do?ids=1,2,3,4,5,6
运行结果

obtain parameter's value is [Ljava.lang.Integer;@f0e01f2
@RequestMapping("doReqParam04")
    @ResponseBody
    //可变参数
    public String doReqParam04(Integer... ids){
        //客户端传参数形式ids=200,222,302
        return "obtain parameter's value is "+Arrays.toString(ids);
    }

http://localhost/spring-mvc-v1/req/doReqParam04.do?ids=200,222,302
运行结果

obtain parameter's value is [200, 222, 302]

省去了如下代码

        String str=request.getParameter("ids");
        String []arr=str.split(",");
        Integer[] it=new Integer[arr.length];
        for(int i=0;i<arr.length;i++){
            it[i]=Integer.parseInt(arr[i]);
        }

3.1.3. Java bean对象(重点)

当请求中多个参数时可以通过在方法中定义多个参数接收参数数据,也可以利用一个javabean对象接收多个参数数据以简化多个参数变量的定义。使用对象接收数据,页面上传参数的值需要和实体类里属性的set方法一致。

package entity;

import java.io.Serializable;
import java.util.Date;

/**
 * POJO:日志实体对象 封装系统的日志信息 实现序列化接口,便于网络传输
 */
public class SysLog implements Serializable {
    private static final long serialVersionUID = -496934815638734874L;
    private Integer id;
    /**
     * 操作用户
     */
    private String username;
    /**
     * 执行的操作
     */
    private String operation;
    /**
     * 执行这个操作的方法
     */
    private String method;
    /**
     * 调用方法传入的参数
     */
    private String params;
    /**
     * 方法的执行时间
     */
    private Long time;
    /**
     * 用户的ip地址
     */
    private String ip;
    /**
     * 这个日志的创建时间
     */
    private Date createdTime;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getOperation() {
        return operation;
    }

    public void setOperation(String operation) {
        this.operation = operation;
    }

    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public String getParams() {
        return params;
    }

    public void setParams(String params) {
        this.params = params;
    }

    public Long getTime() {
        return time;
    }

    public void setTime(Long time) {
        this.time = time;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }



    public Date getCreatedTime() {
        return createdTime;
    }

    public void setCreatedTime(Date createdTime) {
        this.createdTime = createdTime;
    }

    @Override
    public String toString() {
        return "SysLog [id=" + id + ", username=" + username + ", operation=" + operation + ", method=" + method
                + ", params=" + params + ", time=" + time + ", ip=" + ip + ", createdTime=" + createdTime + "]";
    }


}

spring中任何一个对象都可看成javabean

/**使用javabean(VO-valueobject-值对象:封装值的,提供了getter、setter方法的;pojo持久化对象)接收数据*/
    @RequestMapping("doReqParam05")
    @ResponseBody
    public String doReqParam05(SysLog log){
        //请求中的参数要与pojo对象的set方法一致
        return "obtain parameter's value is "+log.toString();
    }

http://localhost/spring-mvc-v1/req/doReqParam05.do?id=10&username=zhangsan&operation=update
运行结果

obtain parameter's value is SysLog [id=10, username=zhangsan, operation=update, method=null, params=null, time=null, ip=null, createdTime=null]

3.1.4. 集合Map对象对象(了解)

说明: 通过map接收页面参数时,必须使用@RequestParam注解声明,否则map将拿不到数据

提示:假如方法参数时map类型,而使用@RequestParam注解进行修饰,此时的map一般是用来封装响应数据的一个对象。

@RequestMapping("doReqParam06")
    @ResponseBody
    public String doReqParam06(@RequestParam Map<String,Object>map){
        //请求中的参数要与pojo对象的set方法一致
        return "obtain parameter's value is "+map.toString();
    }

http://localhost/spring-mvc-v1/req/doReqParam06.do?id=100&title=a
运行结果

obtain parameter's value is {id=100, title=a}

3.1.6. Rest url数据(重点)

SpringMVC请求资源路径的URL可以通过{XXX}形式指定动态的URL,动态URL中的这个可变参数的值可以直接注入到方法对应的参数中。

@RequestMapping("doReqParam07/{id}")
    @ResponseBody
    //参数的值来自请求中的url
    public String doReqParam07(@PathVariable Integer id){
        //请求中的参数要与pojo对象的set方法一致
        return "obtain parameter's value is "+id;
    }

http://localhost/spring-mvc-v1/req/doReqParam07/168.do
运行结果

obtain parameter's value is 168
    @RequestMapping("doReqParam07/{var}/{name}")
    @ResponseBody
    //参数的值来自请求中的url
    public String doReqParam07(@PathVariable("var") Integer id,@PathVariable String name){
        //请求中的参数要与pojo对象的set方法一致
        //从reset风格url中获取请求数据,需要使用@PathVariable注解对参数进行修饰
        return "obtain parameter's value is "+id+" name is "+name;
    }

http://localhost/spring-mvc-v1/req/doReqParam07/168/zhang.do
运行结果

obtain parameter's value is 168 name is zhang

3.1.7. 请求头数据(了解)

当服务端要获取客户端请求头中数据信息时,可通过@RequestHeader即可将请求头中

的属性值绑定到处理方法的入参中,例如获取请求中Accept属性的值,然后传入到对应方法的参数中。

    @RequestMapping("doReqHeader01")
    @ResponseBody
    //参数的值来自请求中的url
    public String doReqHeader01(@RequestHeader String Accept){
        return "obtain parameter's value is Accept= "+Accept;
    }

http://localhost/spring-mvc-v1/req/doReqHeader01.do
运行结果

obtain parameter's value is Accept= text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    @RequestMapping("doReqHeader01")
    @ResponseBody
    //参数的值来自请求中的url
    public String doReqHeader01(@RequestHeader("Accept-Encoding") String AcceptEncoding){
        return "obtain parameter's value is AcceptEncoding= "+AcceptEncoding;
    }

http://localhost/spring-mvc-v1/req/doReqHeader01.do
运行结果

obtain parameter's value is AcceptEncoding= gzip, deflate
    @RequestMapping("doReqCookie01")
    @ResponseBody
    public String doReqCookie01(
    @CookieValue String JSESSIONID) {
            return "obtain COOKIE value is JSESSIONID " + JSESSIONID + "";
    }

http://localhost/spring-mvc-v1/req/doReqCookie01.do
运行结果

obtain COOKIE value is JSESSIONID DF4E61FA6FDC9C1C0AC614334A29993B

提示:方法中的参数名需要与请求头参数中某个参数名相同,具体请求头相关信息可以在浏览器控制台查看。

当应用中要获取请求中所有数据时可以在请求方法中定义一个HttpEntity<String>参数,通过此参数获取请求头及请求体中数据,例如

    @RequestMapping(value="doReqEntity01", method=RequestMethod.POST)
    public @ResponseBody String doReqEntity01(
    HttpEntity<String> entity) {
            return "Posted request body " + entity.getBody() + " headers = " + entity.getHeaders();
    }
   <form action="http://localhost/spring-mvc-v1/req/doReqEntity01.do" method="POST">
   <input type="text" name="user">
   <input type="submit">
   </form>
Posted request body user=good headers = {host=[localhost], user-agent=[Mozilla/5.0 (Windows NT 6.1; WOW64; rv:61.0) Gecko/20100101 Firefox/61.0], accept=[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8], accept-language=[zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2], accept-encoding=[gzip, deflate], referer=[http://localhost/spring-mvc-v1/doSayHello.do], content-type=[application/x-www-form-urlencoded], content-length=[9], cookie=[JSESSIONID=108236BEF06FFBECBD0F953655F2EA29], connection=[keep-alive], upgrade-insecure-requests=[1]}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容