学习SpringMVC---控制器Controller之一系列注解

SpringMVC注解

打卡:日常学习第二天

@RequestMapping注解

  1)@RequestMapping 注解为控制器指定某一个URL请求路径
  2)@RequestMapping注解既可以写在类上也可以卸载方法上
        a.在类上标注:第一级的访问目录
        b.在方法上标注:第二级的访问目录
  3)@RequestMapping中的常用属性
       a. path  请求的路径
       b. value  与path属性是一样的
       c. params  限定请求参数的条件
       d.method   指定该方法的请求方式
       e.headers 发送过来的请求中必须要包含的请求头
       f. consumes 指定处理请求的提交内容类型(Content-Type),如果http的请求头中的Content-Type与@ RequestMapping中规定的媒体类型一致,方法才能响应。
       g. produces  指定返回值类型,则http请求的Accept必须与生成媒体类型一致才可以
  4)@RequestMapping作用:
       当DispatcherServlet 截获请求后,进行解析,通过控制器匹配@RequestMapping提供的映射信息确定请求所对应的处理方法。

案例演示

编写Controller控制器层的HelloDemo类
path、value、method 属性使用演示案例

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class HelloDemo {
    @RequestMapping(value = "/hello",method = RequestMethod.GET)
    public String hello(){
        return "hello";
    }
    /**
     * @RequestMapping("/hello") 映射路径
     * @param username  相当于request.getParameter("name")
     * @param model 用于存储数据,类似于request.setAttribute("name",name)
     * @return
     */
    @RequestMapping(path = "/hello",method = RequestMethod.POST)
    public String sayHello(String username, String password,Model model){
        model.addAttribute("msg",username+"---"+password);
        return "hello";
    }
}

编写hello.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>入门案例</title>
</head>
<body>
	<form method="post" action="${pageContext.request.contextPath}/hello.do">
	    <input type="text" name="username" id="username" placeholder="账号">
	    <input type="password" name="password" id="password" placeholder="密码">
	    <input type="submit" value="登录">
	</form>
	<h3>${msg}</h3>
</body>
</html>

params属性案例演示

@Controller
public class HelloDemo {
    @RequestMapping(value = "/hello",method = RequestMethod.GET)
    public String hello(){
        return "hello";
    }
    /**
     * @RequestMapping("/hello") 映射路径
     * @param username  相当于request.getParameter("name")
     * @param model 用于存储数据,类似于request.setAttribute("name",name)
     * @return
     */
    //params = {"username","password"}  表示请求过来的参数必须含有username、password这两个参数。否则报错
    @RequestMapping(path = "/hello",method = RequestMethod.POST,params = {"username","password"})
    public String sayHello(String username, String password,Model model){
        model.addAttribute("msg",username+"---"+password);
        return "hello";
    }
}

consumes、product属性案例演示

import com.ts.entity.User;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.awt.*;

@Controller
public class HelloDemo {

    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }
    /**
     * consumes属性:如果http的请求头中的Content-Type与@ RequestMapping中规定的consumes媒体类型一致,方法才能响应。
     * 浏览器的用户异步登录,指明contentType :"application/json" , contentType默认值为"application/x-www-form-urlencoded :
     *@RequestBody注解,指明方法参数与http的请求体数据绑定。
     * @RequestBody用来接收前端传递给后端的json字符串,数据不是源于http的参数,而是源于http的请求体。
     * 在映射方法指明生产媒体类型,则http请求的Accept必须与生成媒体类型一致才可以
     * 在ajax中指定dataType:"json"后,http的请求头格式如: Accept:  application/json, text/javascript
     * 加上@ResponseBody注解后,会自动将返回结果在响应体中响应到客户端。User对象会自动转为json对象。但是需要加入jackson相关依赖才可。
     * @param user  实体类
     * @return
     */
    @PostMapping(path = "/hello",consumes = {"application/json"},produces = {MediaType.APPLICATION_JSON_VALUE})
    @ResponseBody
    public User sayHello(@RequestBody String user){
        System.out.println(user);
        User user1=new User();
        user1.setUsername(user.split("&")[0].split("=")[1]);
        user1.setPassword(user.split("&")[1].split("=")[1]);
        return user1;
    }
}

consumes、product中的 .jsp 页面ajax发送请求

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>入门案例</title>
    <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.4.4.min.js"></script>
</head>
<script>
    function login() {
        var username = $("#username").val();
        var password = $("#password").val();
        var user={username:username,password:password};
        $.ajax({
            type:"POST",
            url:"${pageContext.request.contextPath}/hello.do",
            data:user,
            dataType:"json",
            contentType:"application/json",
            success:function (user) {
                alert(user.username+"输出传送的数据"+user.password);
            },
            error:function () {
                alert("请求失败,出现异常");
            }
        })
    }
</script>
<body>

<form method="post" action="${pageContext.request.contextPath}/hello.do">
    <input type="text" name="username" id="username" placeholder="账号">
    <input type="password" name="password" id="password" placeholder="密码">
    <input type="button" onclick="login()" value="登录">
</form>

</body>
</html>

@RequestParam 注解

 1)@RequestParam:绑定请求参数到控制器的方法参数
 2)@RequestParam中的常用属性
		a. value:请求参数中的参数名称
		b. required:默认为 true, 表示请求参数中必须包含对应的参数,若不存在,将抛出异常
		c. defaultValue: 默认值,当没有传递参数时使用该值

案例演示

控制器层类的编写,其jsp同上

@Controller
public class HelloDemo {
    @RequestMapping(value = "/hello",method = RequestMethod.GET)
    public String hello(){
        return "hello";
    }
    /**
     * @RequestMapping("/hello") 映射路径
     * @param username  相当于request.getParameter("name")
     * @param model 用于存储数据,类似于request.setAttribute("name",name)
     * @return
     */
    /*
         @RequestParam(value = "username",required = true;表示请求中的参数必须含有username参数名
        @RequestParam(value = "password",required = false,defaultValue = "6666666")
        required = false;表示password参数是可选的,如果请求过来的url中有这个参数,则使用真实的值
                          如果请求过来的url没有这个参数,defaultValue = "6666666"则使用默认值
    */
    @RequestMapping(path = "/hello",method = RequestMethod.POST)
    public String sayHello(@RequestParam(value = "username",required = true)String username, 
                           @RequestParam(value = "password",required = false,defaultValue = "6666666") String password,
                           Model model){
        model.addAttribute("msg",username+"---"+password);
        return "hello";
    }
}

@PathVariabl 注解

1)@PathVariable注解,可以创建RESTFul风格的web站点。
2)@PathVariable 解析使用URI模板
3)用于绑定 url 中的占位符。例如:请求 url 中 /hello/{username},这个{username}就是 url 占位符。
4)@PathVariable 中的常用属性
     a. value:用于指定 url 中占位符名称。
     b. required:表示是否必须提供占位符。

案例演示

控制层类的编写,jsp页面同理

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@Controller
public class HelloDemo {
    /**
     * @RequestMapping("/hello") 映射路径
     * @param username  相当于request.getParameter("name")
     * @param model 用于存储数据,类似于request.setAttribute("name",name)
     * @return
     */
    /*
      @RequestMapping(path = "/hello/{username}&{password}",method = RequestMethod.GET)
      请求方式为get请求,在url路径中必须包括username,password 参数,否则报错
      在方法中参数中可以使用@PathVariable(value = "username",required = true;获取参数
   */
    @RequestMapping(path = "/hello/{username}&{password}",method = RequestMethod.GET)
    public String sayHello(@PathVariable(value = "username",required = true)String username,
                           @PathVariable(value = "password",required = false) String password,
                           Model model){
        model.addAttribute("msg",username+"---"+password);
        return "hello";
    }
}

@GetMapping 与 @PostMapping 注解

Spring Framework 4.3之后,可以使用如下注解,简化@RequestMapping的写法:
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping

使用以上五种注解的步骤

 1、在spring-mvc.xml配置文件中 开启mvc注解驱动,导入mvc约束
 2、编写控制层的类

案例演示

@Controller
public class HelloDemo {

    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }
    @PostMapping(path = "/hello")
    public String sayHello(String username,String password,Model model){
        model.addAttribute("msg",username+"---"+password);
        return "hello";
    }
}

HttpSession安全性

HttpSession的数据结构,是按照sessionid来操作数据的,没有线程的并发控制。
当高并发访问HttpSession对象时,可以设置  synchronizeOnSession  = true
来提高线程安全性。
//将处理器放到spring容器中,才能生效
@Component
public class MyProcessor implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        return null;
    }

    //初始化之后执行的方法
    //处理器适配器,中设置session是同步
    public Object postProcessAfterInitialization(Object bean, String s) throws BeansException {
        //判断当前对象是不是处理器适配器
        if(bean instanceof RequestMappingHandlerAdapter){
            //向下转型为适配器
            RequestMappingHandlerAdapter adapter = (RequestMappingHandlerAdapter) bean;
            //条用适配器特有的设置session同步的方法
            adapter.setSynchronizeOnSession(true);
        }
        //返回
        return bean;
    }
}

@ResquestBody与消息转换器

1)@RequestBody注解,指明方法参数与http的请求体数据绑定。
2)@ResquestBody用于获取请求体内容。
			   直接使用得到是 key=value&key=value...结构的数据。
3)@ResquestBody 不适用get 请求方式。
4)@RequestBody中常用属性
	a. required 是否必须有请求体。
                默认值是:true。当取值为 true 时,get 请求会报错。
                如果取值为 false,get 请求得到是 null。

转换http请求体到方法参数,需要使用HttpMessageConverter。消息转换器还负责把方法参数转换为http回应体(response body)
RequestMappingHandlerAdapter支持@RequestBody注解,使用如下默认消息转换器:
ByteArrayHttpMessageConverter:转换字节数组
StringHttpMessageConverter:转换字符串
FormHttpMessageConverter:转换表单数据到MultiValueMap<String, String>.
SourceHttpMessageConverter:与XML数据源之间数据转换

案例演示

如果设置@RequestBody(required = true),get 请求会报错。

 @PostMapping(path = "/hello",consumes = {"application/json"},produces = {MediaType.APPLICATION_JSON_VALUE})
    @ResponseBody
    public User sayHello(@RequestBody(required = true) String user){
        System.out.println(user);
        User user1=new User();
        user1.setUsername(user.split("&")[0].split("=")[1]);
        user1.setPassword(user.split("&")[1].split("=")[1]);
        return user1;
    }

配置消息转换器

方法一:注解形式

 <mvc:annotation-driven>
        <!--消息转换器,设置string编码-->
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter" id="stringHttpMessageConverter">
                <constructor-arg value="UTF-8"></constructor-arg>
                <property name="writeAcceptCharset" value="false"></property>
            </bean>
            <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" id="byteArrayHttpMessageConverter"></bean>
            <bean class="org.springframework.http.converter.cbor.MappingJackson2CborHttpMessageConverter" id="jackson2CborHttpMessageConverter"></bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

方法二:bead形式

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" id="requestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                    <constructor-arg value="UTF-8"></constructor-arg>
                    <property name="writeAcceptCharset" value="false"></property>
                </bean>
            </list>
        </property>
    </bean>

@ResponseBody 与 转换器

@ResponseBody注解用于方法,表明方法返回信息将直接写入http回应体。

方法上没有@ResponseBody注解,String返回值表示视图名字。@ResponseBody主要用于ajax数据回应或字节流数据回应等,不经过视图,数据直接返回客户端。
同@RequestBody 一样,@ResponseBody也是使用HttpMessageConverter把方法返回数据转换为http回应体。

代码同@RequestBody

如何解决返回体中的乱码问题???

在 web.xml中配置编码过滤器,似于JavaWeb阶段
<!--配置编码过滤器-->
    <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>
    

如果返回的数据直接是json格式的数据,字符中含有中文,此时会出现乱码问题,解决如下,配置消息转换器

<mvc:annotation-driven>
     <!--  配置消息转换器,设置String的编码      -->
     <mvc:message-converters>
         <bean class="org.springframework.http.converter.StringHttpMessageConverter">
             <constructor-arg value="UTF-8"/>
             <property name="writeAcceptCharset" value="false"/>
         </bean>
     </mvc:message-converters>
</mvc:annotation-driven>

@RestController 注解

1)如果控制器,只服务于JSON、XML、多媒体数据等,是REST风格,则通常使用
   @RestController注解。

2)@RestController = @ResponseBody + @Controller

案例演示

最初学习的:
@Controller
public class HelloAction {

    @RequestMapping("/say")
    @ResponseBody
    public String say(){
        return "say hello to SpringMVC";
    }
}

可以用@RestController注解代替以上的代码

@RestController
public class HelloAction {

    @RequestMapping("/say")
    public String say(){
        return "say hello to SpringMVC";
    }
}

HttpEntity

HttpEntity表示http的request和resposne实体,它由消息头和消息体组成。

步骤一:在.jsp中发送ajax请求

$.ajax({
    type: "POST",
    url: targetUrl,
    data: user,//传递的参数
    dataType:"json",//前端可以接收服务器传过来的数据的类型,json
    contentType: "application/json",
    beforeSend: function(xhr){//请求发送之前执行函数,添加请求头
        xhr.setRequestHeader("token","asdfghjk");
    },
    success: function(user){
        alert(user.username);
    },
    error:function(){
        alert("异常,请检查");
    }

步骤二:在controller中获取请求头中的信息

@PostMapping(value = "/hello")
@ResponseBody
public ResponseEntity<User> login(@RequestBody String userString, RequestEntity requestEntity) {

    System.out.println(requestEntity.getUrl());
    //通过请求实体对象获取请求头,此处只演示几个,其余的自己获取即可
    HttpHeaders requestHeaders = requestEntity.getHeaders();
    System.out.println(requestHeaders);
    
    //创建一个响应头
    HttpHeaders responseHeader = new HttpHeaders();
    responseHeader.set("myResponseHeader","myValue");
    //userString绑定的请求体
    //登录成功,拿到一个user对象
    User user = new User();
    user.setUsername(userString.split("&")[0].split("=")[1]);
    user.setPassword(userString.split("&")[1].split("=")[1]);
    
    //HttpStatus:响应的状态码
    return new ResponseEntity<User>(user, responseHeader, HttpStatus.OK);
}

@ModelAttribute

1)它可以用于修饰方法和参数。
        出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。
        它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法。
        出现在参数上,获取指定的数据给参数赋值

案例演示

@Controller
@RequestMapping("/hello")
public class HelloDemo {

    @ModelAttribute
    public User add(){
        User user=new User();
        user.setUsername("rose");
        user.setPassword("love");
        return user;
    }

    @RequestMapping(path = "/login")
    public String sayHello(){
        
        return "hello";
    }
}

jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>入门案例</title>
</head>
<body>

<h1>${user.password}${user.username}</h1>

</body>
</html>

@SessionAttribute

1)@SessionAttribute 用于控制器方法间的参数共享
2)@SessionAttributes用于在会话中存储Model中指定名称的属性,用在类的级别。
3)@SessionAttribute注解用于方法参数,获取已经存储的session数据。
4)@SessionAttributes(value = {"user","shopcar"})

案例演示

@Controller
@RequestMapping("/account")
@SessionAttributes("account")//将model中的结果存入session
public class AccountAction {

    @Autowired
    private AccountService accountService;

    //将account对象存入model
    @ModelAttribute
    public Account findAccout(String number){
        return accountService.findAccount(number);
    }

    @RequestMapping("/find")
    public String findAccount(String number){
        return "account";
    }
}
@Controller
@RequestMapping("/shopping")
public class ShoppingAction {

    @RequestMapping("/buy")
    public String buy(@SessionAttribute Account account){
        //从session中获取account,消费
        account.setBalance(account.getBalance()-500);
        return "account";
    }
}

@RequestMapping处理put、delete方法

Spring3.0 添加了一个过滤器,可以将这些请求转换为标准的 http 方法,使得支持 GET、POST、PUT 与 DELETE 请求。

案例演示

@Controller
public class HelloDemo {
    
   @GetMapping("/hello")
   public String a(){
       return "hello";
   }

    @PutMapping(path = "/login")
    @ResponseBody
    public String sayHello(String username,String password){
        System.out.println(username);
        System.out.println(password);
        return "put提交--成功";
    }
}

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>入门案例</title>
</head>
<body>

<form method="post" action="${pageContext.request.contextPath}/login.do">
    <%-在首航设置隐藏域,name=”_method“ value="put/delete"--%>
    <input type="hidden" name="_method" value="PUT">
    <input type="text" name="username" id="username" placeholder="账号">
    <input type="password" name="password" id="password" placeholder="密码">
    <input type="submit" value="登录">
</form>

</body>
</html>

在web.xml配置隐藏过滤器

    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

@CookieValue

1)@CookieValue用于提取http请求中指定名称的cookie
2)@CookieValue 常用的属性
     a. value:指定 cookie 的名称。
     b. required:是否必须有此 cookie。

案例演示

@Controller
@RequestMapping("/user")
public class UserAction {


    @GetMapping("/hello")
    public String login(@CookieValue("JSESSIONID") String sessionID){
        System.out.println("JSESSIONID :" + sessionID);
        return "hello";
    }

    @PutMapping("/hello")
    @ResponseBody
    public String login(String username,String password,@CookieValue("JSESSIONID") String sessionID ){
        System.out.println("JSESSIONID :" + sessionID);
        System.out.println("put提交");
        return "获取cookieValue成功";
    }
}

@RequestHeader

1)@RequestHeader用于获取请求消息头。
2)@RequestHeader常用属性
       value:指定消息头名称
       required:是否必须有此消息头

案例演示

@GetMapping("/hello")
public String login(@RequestHeader("User-Agent")String userAgent,@RequestHeader
                    Map<String,String> headers){
    System.out.println("User-Agent : "+userAgent);
    //遍历map集合,获取所有的请求头的信息
    for(Map.Entry<String,String> entry : headers.entrySet()){
        System.out.println(entry.getKey());
    }
    return "hello";
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值