SpringMvc

常用注解

@RequestParams

value/name:请求参数中的名称
required:请求参数中是否必须提供此参数,默认值为true,表示必须提供,如果不提供将报错
@RequestMapping("/testRequestParam")
public String testRequestParam(@RequestParam("name") String uname) {
    System.out.println(uname);
    return "success";
}

@RequestBody

用于获取请求体内容,直接使用得到的是key=value&key=value....的结构
只适用于post方法(get方法没有请求体,参数都封装在地址栏上)
required:是否必须由请求体,默认是true,get方法请求方式会出错,如果取值为false,get请求得到null
@RequestMapping("/testRequestBody")
public String testRequestBody(@RequestBody String body, String uName) {
    System.out.println(uName);
    System.out.println(body);
    return "success";
}

@PathVariable

1.作用:绑定url中的占位符,eg:/delete/{id},{id}就是占位符
2.属性
	value:指定url中的占位符名称
3.Restful风格
	请求路径一样,可以分局不同的请求方式去执行后台的不同的方法
	restful风格的url优点:
		结构清晰
		符合标准
		易于理解
		扩展方便
@RequestMapping("/testPathVariable/{id}")
public String testPathVariable(@PathVariable("id") String ids) {
    System.out.println(ids);
    return "success";
}

@RequestHeader

获取请求头的值
	value:提供消息头名称
	required:是否必须有此消息头
@RequestMapping(value = "/testRequestHeader")
public String testRequestHeader(@RequestHeader(value = "Accept") String header){
    System.out.println("执行了");
    System.out.println(header);
    return "success";
}

@CookieValue

用于指定cookie名称的值传入控制器方法参数
	value:指定cookie的名称
	required:是否必须有此cookie
@RequestMapping("/testCookieValue")
public String testCookieValue(@CookieValue(value ="JSESSIONID")String cookieValue){
    System.out.println("cookieValue=>"+cookieValue);
    return "success";
}

@SessionAttribute

作用
	用于多次执行控制器方法间的参数共享
属性
	value:用于指定存入的数据名称
	type:用于指定存入的数据类型
@SessionAttributes({"msg"})//将添加的属性加入到session域中
public class AnnoController {
    @RequestMapping("/testSessionAttribute")
    public String testSessionAttribute(Model model){
        //model会将值传到request域对象中
      model.addAttribute("msg","haha");
        return "success";
    }
    //获取session域中的属性
    @RequestMapping("/getSessionAttribute")
    public String getSessionAttribute(ModelMap modelMap){
        String msg =(String) modelMap.get("msg");
        System.out.println(msg);
        return "success";
    }
}
//清除
    @RequestMapping("/delSessionAttribute")
    public String delSessionAttribute(SessionStatus status){
        System.out.println("delSessionAttribute");
       status.setComplete();
        return "success";
    }

@ModelAttribute

1.位于方法上时

放在方法上时,该方法会在控制器的方法执行之前,先执行。它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法

/**
 *有返回值时
 */
@ModelAttribute
public Users showUser(){
    System.out.println("test..modelAttribute");
    Users users = new Users();
    users.setDate(new Date());
    return users;
}
/**
 * 无返回值时
 */
@ModelAttribute
public void showUser2(String uName, Map<String,Users> map){
    System.out.println("test..modelAttribute");
    Users users = new Users();
    users.setDate(new Date());
    map.put("abc",users);
}

2.位于参数上时

value:用于获取数据的key,可以可以时pojo的属性名称,也可以时map结构中的key
应用场景:
	当表单提交数据不是完整的实体类数据时,保证没有提交的数据的字段使用数据库对象原来的数据
  @RequestMapping("/testModelAttribute")
    public String testModelAttribute(@ModelAttribute("abc") Users users){
        System.out.println(users);
        return "success";
    }

请求参数绑定

请求参数绑定

<!--请求参数绑定-->
<a href="param/testParam?username=df&&pwd=fe">请求参数的绑定</a>
@RequestMapping("testParam")
public String testParam(String username,String pwd) {
    System.out.println("执行了....");
    System.out.println("username=>"+username);
    System.out.println("pwd=>"+pwd);
    return "success";
}

请求参数绑定实体类

<%-- 将数据封装在实体类中--%>
<form action="param/saveAccount" method="post">
    姓名:<input type="text" name="username"/><br><!--name属性的值必须跟实体类相对应-->
    密码:<input type="password" name="pwd"><br>
    金额:<input type="text" name="money"><br>
    <!--引用类型-->
    用户名:<input type="text" name="user.uName"><br>
    年龄:<input type="text" name="user.uPwd"/><br>
    <input type="submit" value="提交"><br>
</form>
@RequestMapping(value = "/saveAccount")
public String saveAccount(Account account){
    System.out.println(account);
    return "success";
}

自定义参数类型

<%--将数据封装在实体类中,类中存在list和map--%>
<form action="param/saveAccount" method="post">
    用户名:<input type="text" name="list[0].uName"><br>
    年龄:<input type="text" name="list[0].uPwd"><br>
    用户名:<input type="text" name="map['one'].uName"><br>
    年龄:<input type="text" name="map['one'].uPwd"><br>
    <input type="submit">
</form>
@RequestMapping(value = "/saveUser")
public String save(Users users){
    System.out.println(users);
    return "success";
}

获取原生servletAPI

@RequestMapping("/testServlet")
public String testServlet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    System.out.println("request");
    HttpSession session = request.getSession();
    System.out.println(session);

    ServletContext servletContext = session.getServletContext();
    System.out.println(servletContext);

    System.out.println(response);
    return "success";
}

自定义类型转换

页面提交的任何数据都是string类型
请求时会自动类型转换:string->Integer/double/date
但遇到格式不同时,需要自定义类型转换
package com.zh.utils;

import org.springframework.core.convert.converter.Converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 自定义类型转换:
 * 把字符转换成日期
 */
public class StringToDateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String source) {
//       判断
        if (source==null){
            throw new RuntimeException("请您传入数据");
        }
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

        try {
            return df.parse(source);
        } catch (ParseException e) {
            throw new RuntimeException("数据类型转换出现错误");
        }
    }
}
 <!--配置自定义类型转换器-->
    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.zh.utils.StringToDateConverter"/>
            </set>
        </property>
    </bean>

异常处理器

@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/testException")
    public String testExceptions() throws Exception {
    try {
        //模拟异常
        int a = 10 / 0;
    } catch (Exception e) {
        //打印异常信息
        e.printStackTrace();
        //抛出自定义提示信息
        throw new SysException("查询所有用户出现错误....");
    }
    return "success";
}
}

1.编写自定义异常类

package com.zh.exception;

//自定义异常类
public class SysException extends Exception{

    //存储提示信息
    private String message;

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public SysException(String message) {
        this.message = message;
    }

    public SysException() {
    }
}

2.编写异常处理器

package com.zh.exception;

import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//异常处理器
public class SysExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception ex) {
      //获取到异常对象
        SysException e=null;
        if (ex instanceof SysException){
            e=(SysException)ex;
        }else {
            e=new SysException("系统正在维护");
        }
        //创建modelAndView
        ModelAndView mv = new ModelAndView();
        mv.addObject("errorMsg",e.getMessage());
        mv.setViewName("error");
        return mv;
    }
}

3.配置异常处理器(跳转到提示页面)

  <!--配置异常处理器-->
<bean id="sysExceptionResolver" class="com.zh.exception.SysExceptionResolver"></bean>

文件上传

1.传统方式文件上传

<form action="user/testFileUpLoad1" method="post" enctype="multipart/form-data">
    请输入:<input type="text">
    <!--name必须跟控制器方法参数一致-->
    选择文件:<input type="file" name="upload"/><br/>
    <input type="submit">
</form>
/**
 * 传统方式文件上传:
 * 文件上传的必要前提:
 * 1.form表单的enctype取值必须时:multipart/form-data
 * 默认值是:application/x-www.form-urlencoded
 * 2.method必须为post请求
 * 3.提供一个文本域
 * 借助第三方组件实现文件上传
 * commons-fileupload-1.3.1.jar
 * commons-io-2.4.jar
 */
    @RequestMapping("/testFileUpLoad1")
    public String testFileUpLoad1(HttpServletRequest request) throws Exception {
        System.out.println("javaweb方式执行文件上传");
        //使用fileupload组件完成文件上
        // 上传的位置
        String path = request.getSession().getServletContext().getRealPath("/uploads/");
        //判断该文件路径是否存在
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
//解析request对象,获取上传文件项
        DiskFileItemFactory factory = new DiskFileItemFactory();//磁盘文件项
        ServletFileUpload upload = new ServletFileUpload(factory);
//解析request
        List<FileItem> items = upload.parseRequest(request);

        //遍历
        for (FileItem item : items) {
            System.out.println("item=>" + item);
            //判断当前item对象是否是上传文件项
            if (item.isFormField()) {
                //普通文件项
            } else {
                //上传文件项
                //获取上传文件名
                String fileName = item.getName();
                String uuid = UUID.randomUUID().toString().replace("-", "");
                fileName = uuid + "_" + fileName;
                //完成文件上传
                System.out.println("fileName"+fileName);
                item.write(new File(path, fileName));
                //删除临时文件
                item.delete();

            }
        }
        return "success";
    }

2.springmvc方式文件上传

<form action="user/testFileUpLoad2" method="post" enctype="multipart/form-data">
    <!--name必须跟控制器方法参数一致-->
    选择文件:<input type="file" name="upload"/><br/>
    <input type="submit">
</form>
//springMvc方式文件上传
@RequestMapping("/testFileUpLoad2")
public String testFileUpLoad(HttpServletRequest request, MultipartFile upload) throws IOException {

    System.out.println("springmvc执行文件上传");
    // 上传的位置
    String path = request.getSession().getServletContext().getRealPath("/uploads/");
    //判断该文件路径是否存在
    File file = new File(path);
    if (!file.exists()) {
        file.mkdirs();
    }
    String fileName = upload.getOriginalFilename();//获取文件名
    String uuid = UUID.randomUUID().toString().replace("-", "");
    fileName = uuid+"_"+fileName;
    //完成文件上传
    upload.transferTo(new File(path,fileName));
    return "success";
}

3.跨服务器文件上传

<form action="user/testFileUpLoad3" method="post" enctype="multipart/form-data">
    <!--name必须跟控制器方法参数一致-->
    选择文件:<input type="file" name="upload"/><br/>
    <input type="submit">
</form>
@RequestMapping("/testFileUpLoad3")
public String testFileUpLoad3(MultipartFile upload) throws IOException {
    System.out.println("跨服务器文件上传");

    //定义上传文件服务器路径
    String path="http://persionzh.top:8080/images/";
    //获取文件名
    String fileName = upload.getOriginalFilename();//获取文件名
    //将文件设为唯一值
    String uuid = UUID.randomUUID().toString().replace("-", "");
    fileName = uuid+"_"+fileName;
    //创建客户端对象
    Client client = Client.create();
    //和图片服务器进行连接
    WebResource webResource = client.resource(path + fileName);
   //上传文件
    webResource.put(upload.getBytes());
    return "success";
}

Response

返回视图

@RequestMapping("/testString")
public String testString(Model model) {
    User user = new User("hello", "nihao");
    model.addAttribute("users", user);
    return "success";
}

无返回值

 @RequestMapping("/testVoid")
    public void testVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //转发:一次请求
//    request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
        //重定向:两次请求
//    response.sendRedirect(request.getContextPath()+"/index.jsp");
//    System.out.println(request.getContextPath());//获取虚拟路径/item2
        //直接响应
        //解决中文乱码
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().print("你好");
        return;

使用关键字进行转发/重定向

  //使用关键字进行转发/重定向
    @RequestMapping("/testForwardOrRequest")
    public String testForwardOrRequest() {
        //转发
        return "forward:/WEB-INF/pages/success.jsp";
        //重定向
//        return "redirect:/index.jsp";//使用redirect时不需要加虚拟路径名
    }

返回字符串

<script>
    $(function () {
        $("#btn").click(function () {
            //发送ajax请求
            $.ajax({
                //编写json格式,设置属性和值
                url: "response/testAjax",
                contentType: "application/json;charset=UTF-8",
                data:'{"uName":"zhtest","uPwd":"465456"}',
                datatype: "json",
                type: "post",
                success: function (data) {
                    //data服务器端响应的json数据,进行解析
                    alert(data);
                    alert(data.uPwd);
                    alert(data.uName)
                }
            })
        })
    })
</script>
//模拟异步请求
    @RequestMapping("/testAjax")
    @ResponseBody
    public User testAjax(@RequestBody User user) {//获取请求体
        System.out.println("textajax执行了");

        //客户端发送ajax的请求,传的是json字符串,后端把json字符串封装到user对象中
        System.out.println("user=>" + user);
        //做响应,模拟查询数据库
        user.setuName("haha");
        user.setuPwd("zfhjdji");
        //响应;
        return user;
    }

ModelAndView

@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {
    User user = new User("zh", "23");
    //创建modelAndView对象
    ModelAndView mv = new ModelAndView();
    //添加属性到request域,相当于model.addAttribute()
    mv.addObject("users", user);
    //跳转到指定视图,相当于return "success";
    mv.setViewName("success");
    return mv;
}

拦截器

@RequestMapping("/testInterception")
public String testInterception() {
    System.out.println("testInterception方法执行了");
    return "success";
}

1.编写拦截器类,实现HandleInterceptor接口

/**
 * 自定义拦截器
 */
public class MyInterception implements HandlerInterceptor {
    /**
     * 预处理:controller方法执行前
     * return true:放行,执行下一个拦截器,如果没有,执行controller中的方法
     * return false不放行
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterception执行了.....前1111");
        //跳到指定页面
//                request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
        return true;
    }

    /**
     * 后处理方法:controller方法执行后,success.jsp执行前
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterception执行了.....后1111");
//        request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
    }

    /**
     * success.jsp页面执行后,该方法执行
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterception执行了.....最后1111");
    }
}
public class MyInterception2  implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterception执行了.....前2222");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterception执行了.....后2222");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterception执行了.....最后2222");
    }
}

2.配置拦截器

<!--配置拦截器-->
    <mvc:interceptors>
<!--        配置具体拦截器-->
        <mvc:interceptor>
<!--            要拦截的方法-->
            <mvc:mapping path="/user/*"/>
<!--            不要拦截的方法-->
<!--            <mvc:exclude-mapping path=""/>-->
            <!--配置拦截器对象-->
            <bean class="com.zh.interception.MyInterception"/>
        </mvc:interceptor>
<!--        配置第二个拦截器-->
        <mvc:interceptor>
            <mvc:mapping path="/user/**"/>
            <bean class="com.zh.interception.MyInterception2"/>
        </mvc:interceptor>
    </mvc:interceptors>

静态资源过滤

 <!-- 前端控制器,过滤静态资源-->
    <mvc:resources mapping="/css/**" location="/css/"/>
    <mvc:resources mapping="/images/**" location="/images/"/>
    <mvc:resources mapping="/js/**" location="/js/"/>
<!--启用默认Servlet-->
 <mvc:default-servlet-handler/> 

SpringMvc执行流程

posted @ 2021-04-26 11:43  Zh'Blog  阅读(73)  评论(0编辑  收藏  举报