SpringMVC笔记(二)

一、常用注解

1.@RequestParam

作用于参数上,用于提交参数与实际参数名称不一致时候生效,即name为提交的时候的参数名字,但是绑定给了username;

    @RequestMapping("/anno")
    public String action(@RequestParam(name="name") String username){
        System.out.println(username);
        return "success";
    }

2.@RequestBody

作用于参数,获取POST提交参数的请求体

    @RequestMapping("/anno")
    public String action(@RequestBody String body){
        System.out.println(body);
        return "success";
    }

3.@PathVariable

作用于参数,restful风格获取参数,将请求路径中的{id}封装到方法参数中

@RequestMapping("/path/{sid}")
    public String path(@PathVariable(name="sid") String id){
        System.out.println(id);
        return "success";
    }

请求路径:http://localhost:8080/path/10
控制台打印10;

4.@RequestHeader

作用于参数,获取请求头参数

 @RequestMapping("/anno/header")
    public String header(@RequestHeader("Cookies") String cookies){
        System.out.println(cookies);
        return "success";
    }

5.@CookieValue

作用于参数,获取Cookies,根据键获取值
获取cookie中username的值

 @RequestMapping("/anno/header")
    public String header(@CookieValue("username") String username){
        System.out.println(username);
        return "success";
    }

6.@ModelAttribute

作用于参数和方法,在方法上加上该注解泽优先于请求的controller方法执行
用处:在用户提交参数不完整的情况下,可以使用该注解来添加提交参数

 @RequestMapping("/anno/modelAttr")
    public String modelAttr(@ModelAttribute("attr")User user){
        System.out.println(user);
        return "success";
    }
    @ModelAttribute
    public void attrPre(Map<String,User> map){
        User user=new User();
        user.setUsername("222");
        user.setPassword("123");
        map.put("attr",user);
    }

这样即使即使没有提交username,password也会使用@modelAttribute方法中对应的map的user值;

7.@SessionAttributes

作用于类,用于向session域里存值

@Controller
@SessionAttributes("msg")
public class HelloController {
    @RequestMapping("/anno/sessionAttr")
    public String sessionAttr(ModelMap modelMap, SessionStatus sessionStatus){
        //添加
        modelMap.addAttribute("msg","hello sessionAttrbutes");
        //获取
        modelMap.get("msg");
        //删除
        sessionStatus.setComplete();
        return "success";
    }
}

二、响应数据和结果视图

1.返回值分类

1.1 String类型

Controller方法返回字符串可以指定逻辑视图的名称,根据视图解析器为物理视图的地址。

  @RequestMapping(value="/hello")
  public String sayHello() {
      System.out.println("Hello SpringMVC!!");
      // 跳转到XX页面
      return "success";
  }
1.2 void类型
  1. 如果控制器的方法返回值编写成void,执行程序报404的异常,默认查找JSP页面没有找到。在注解@RequestMapping(value="/hello") 下,默认会跳转到hello的页面,相当于返回string为hello。
  2. 可以使用请求转发或者重定向跳转到指定的页面
  @RequestMapping(value="/init")
    public void initAdd(HttpServletRequest request,HttpServletResponse response) throws 
Exception {
        System.out.println("请求转发或者重定向");
        // 请求转发
         request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request, 
response);
        // 重定向
         response.sendRedirect(request.getContextPath()+"/success.jsp");
        
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        
        // 直接响应数据
        response.getWriter().print("hello mvc");
        return;
    }
3.ModelAndView类型
  1. ModelAndView对象是Spring提供的一个对象,可以用来调整具体的JSP视图
  2. 具体的代码如下
   /**
     * 返回ModelAndView对象
     * 可以传入视图的名称(即跳转的页面),还可以传入对象。
     */
    @RequestMapping(value="/findAll")
    public ModelAndView findAll() throws Exception {
        ModelAndView mv = new ModelAndView();
        // 跳转到list.jsp的页面
        mv.setViewName("list");
        
        // 模拟从数据库中查询所有的用户信息
        List<User> users = new ArrayList<>();
        User user1 = new User();
        user1.setUsername("张三");
        user1.setPassword("123");
        
        User user2 = new User();
        user2.setUsername("赵四");
        user2.setPassword("456");
                
        users.add(user1);
        users.add(user2);
        // 添加对象
        mv.addObject("users", users);
        
        return mv;
    }

2.SpringMVC框架提供的转发和重定向

controller方法返回String类型

2.1 forward转发
public String testVoid() throws Exception {
        return "forward:/WEB_INF/jsp/success.jsp";
    }
2.2 redirect 重定向
public String testVoid() throws Exception {
        return "redirect:/index.jsp";
    }

3.ResponseBody响应json数据

3.1. 配置静态资源不拦截

DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到,从而
不能被使用。解决问题就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加如下配置

  • mvc:resources标签配置不过滤
  • location元素表示webapp目录下的包下的所有文件
  • mapping元素表示以/static开头的所有请求路径,如/static/a 或者/static/a/b
      <!-- 设置静态资源不过滤 -->
    <mvc:resources location="/css/" mapping="/css/**"/>  <!-- 样式 -->
    <mvc:resources location="/images/" mapping="/images/**"/>  <!-- 图片 -->
    <mvc:resources location="/js/" mapping="/js/**"/>  <!-- javascript -->
3.2.使用@RequestBody获取请求体数据,@ResponseBody将结果解析成json

3.2.1导入需要的jar包

  <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.9.0</version>
    </dependency>

3.2.2 controller类
控制太打印post请求提交的数据,并且返回把User对象解析成json字符串返回

 @RequestMapping("/testbody")
    public @ResponseBody User testVoid(@RequestBody User body) throws Exception {
        System.out.println(body);
        return body;
    }

3.2.3 ajax提交

$(function () {
            $("#btn").click(function () {
                $.ajax({
                    url:"/mvc/testbody",
                    contentType:"application/json;charset=utf8",
                    data:'{"username":"unclez","password":"zhg99524"}',
                    dataType:"json",
                    type:"post",
                    success:function (data) {
                        alert(data.username);
                    }
                });
            });
        });

三、文件上传

1.传统方式

1.1 controller方法
 @RequestMapping("/file")
    public String fileupload1(HttpServletRequest request) throws Exception {
        String path = request.getSession().getServletContext().getRealPath("/uploads/");
        File file = new File(path);
        // 判断路径是否存在,如果不存在,创建该路径
        if(!file.exists()) {
            file.mkdirs();
        }
        DiskFileItemFactory factory=new DiskFileItemFactory();
        ServletFileUpload sf=new ServletFileUpload(factory);
        List<FileItem> items = sf.parseRequest(request);
        for(FileItem item:items){
            if(!item.isFormField()){
                String name=item.getName();
                File f=new File(path,name);
                item.write(f);
                item.delete();
            }
        }
        return "success";
    }
1.2 表单
<form action="/mvc/file" method="post" enctype="multipart/form-data">
    名称:<input type="text" name="picname"/><br/>
    图片:<input type="file" name="upload"/><br/>
    <input type="submit" value="上传"/>
</form>

2.SpringMVC本服务器方式

2.1 配置文件解析器对象
    <!-- 配置文件解析器对象,要求id名称必须是multipartResolver -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="10485760"/>
    </bean>
2.1 controller类
@RequestMapping("/file")
    public String fileupload1(HttpServletRequest request,MultipartFile upload) throws Exception {
        String path = request.getSession().getServletContext().getRealPath("/uploads/");
        File file = new File(path);
        // 判断路径是否存在,如果不存在,创建该路径
        if(!file.exists()) {
            file.mkdirs();
        }
        String filename = upload.getOriginalFilename();
        filename=UUID.randomUUID()+"_"+filename;
        upload.transferTo(new File(path,filename));
        return "success";
    }

3.SpringMVC分其他服务器上传

3.1 jar包
 <dependency>
      <groupId>com.sun.jersey</groupId>
      <artifactId>jersey-core</artifactId>
      <version>1.18.1</version>
    </dependency>
    <dependency>
      <groupId>com.sun.jersey</groupId>
      <artifactId>jersey-client</artifactId>
      <version>1.18.1</version>
    </dependency>
3.2 控制器
@RequestMapping("/file2")
    public String fileupload2(HttpServletRequest request,MultipartFile upload) throws Exception {
        String server_path="远程服务器地址";
        String filename = upload.getOriginalFilename();
        Client client=Client.create();
        WebResource resource = client.resource(server_path + filename);
        resource.put(upload.getBytes());
        return "success";
    }

四、异常处理

1. 异常处理思路

Controller调用service,service调用dao,异常都是向上抛出的,最终有DispatcherServlet找异常处理器进行异常的处理。比如统一跳转404.html之类的

2.自定义异常类

public class MyException extends Exception {
    // 异常提示信息
    private String message;
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public MyException(String message) {
        this.message = message;
    }

}

3.自定义异常处理器

public class MyExecptionResolver implements HandlerExceptionResolver {
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        ModelAndView mv=new ModelAndView();
        if (ex instanceof MyException)
        {
            mv.addObject("errorMsg",ex.getMessage());
        }else {
            //do something..
        }
        mv.setViewName("404");
        return mv;
    }
}

4.配置异常类

<bean id="myExecptionResolver" class="com.unclezs.resolver.MyExecptionResolver"/>

五、拦截器

1.概述

  1. SpringMVC框架中的拦截器用于对处理器进行预处理和后处理的技术。
  2. 可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链中的拦截器会按着定义的顺序执行。
  3. 拦截器和过滤器的功能比较类似,有区别
    1. 过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。
    2. 拦截器是SpringMVC框架独有的。
    3. 过滤器配置了/*,可以拦截任何资源。
    4. 拦截器只会对控制器中的方法进行拦截。
  4. 拦截器也是AOP思想的一种实现方式
  5. 想要自定义拦截器,需要实现HandlerInterceptor接口。

2. 自定义拦截器步骤

创建类,实现HandlerInterceptor接口,重写需要的方法

3. HandlerInterceptor接口中的方法

  1. preHandle方法是controller方法执行前拦截的方法
    1. 可以使用request或者response跳转到指定的页面
    2. return true放行,执行下一个拦截器,如果没有拦截器,执行controller中的方法。
    3. return false不放行,不会执行controller中的方法。
  2. postHandle是controller方法执行后执行的方法,在JSP视图执行前。
    1. 可以使用request或者response跳转到指定的页面
    2. 如果指定了跳转的页面,那么controller方法跳转的页面将不会显示。
  3. afterHandle方法是在JSP执行后执行
    1. request或者response不能再跳转页面了

4.配置多个拦截器

<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/*"/>
            <!-- 哪些方法不进行拦截 -->
            <!--<mvc:exclude-mapping path="/user/*"/>-->
            <bean class="com.unclezs.interceptor.MyInterceptor"/>
       </mvc:interceptor>
       <mvc:interceptor>
            <mvc:mapping path="/*"/>
            <bean class="com.unclezs.interceptor.MyInterceptor2"/>
       </mvc:interceptor>
   </mvc:interceptors>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352

推荐阅读更多精彩内容

  • 对于java中的思考的方向,1必须要看前端的页面,对于前端的页面基本的逻辑,如果能理解最好,不理解也要知道几点。 ...
    神尤鲁道夫阅读 812评论 0 0
  • SpringMVC介绍 Spring web mvc 和Struts2都属于表现层的框架,它是Spring框架的一...
    day_Sunny阅读 748评论 0 0
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,096评论 1 32
  • 凌晨3:30,听时间哒哒前行。浓稠的黑幕里,秒针上的荧光颤颤悠悠,一点一点爬出一条弧线。 打开床头灯,蓝色的香薰炉...
    绎如阅读 462评论 6 2
  • 今天是我第五次听《炒股的智慧》一书了。昨天大势的跌幅让我开始反思,我的策略确实就像是个新手!关键是到昨天为止我还不...
    道二十三阅读 102评论 0 0