spring mvc

1、什么是springMVC
springMVC基于java实现的MVC的设计模式,通过把model,view,controller分离,将web层进行解耦,将复杂的逻辑清晰化,简化代码开发,方便开发人员之间的配合.

2、Spring MVC框架特点
在这里插入图片描述
3、spring MVC的请求处理流程
网上借鉴的图片
【1、用户向服务器发出请求,请求被SpringMVC 前端控制器 DispatcherServlet 捕获;
2、DispatcherServlet收到请求调用HandlerMapping处理器映射器()。
3、DispatcherServlet 对请求 URL 进行解析,得到请求资源标识符(URI)。然后根据该 URI,调用HandlerMapping 获得该 Handler 配置的所有相关的对象(包括 Handler 对象以及 Handler 对象对应的拦截 器),最后以 HandlerExecutionChain 对象的形式返回;
4、DispatcherServlet 根据获得的 Handler,选择一个合弁的 HandlerAdapter;(附注:如果成功获得HandlerAdapter 后,此时将开始执行拦截器的 preHandler(true或者false) 方法)
5、提取 Request 中的模型数据,填充 Handler 入参,开始执行 Handler(Controller)。 在填充 Handler的 入参过程中,根据你的配置,SpringMVC 将帮你做一些额外的工作:
5.1 HttpMessageConveter: 将请 求消息(如 Json、xml 等数据)转换成一个对象,将对象转换为指定的响应信息。
5.2 数据转换:对请求消息进行数据转换。如 String 转换成 Integer、Double 等。
5.3 数据根式化:对请求消息进行数据格式 化。 如将字符串转换成格式化数字或格式化日期等。
5.4数据验证: 验证数据的有效性(长度、格式 等),验证结果存储到 BindingResult 或 Error 中。
6、Handler 执行完成后,向HandlerAdapte返回一个 ModelAndView 对象;
7、HandlerAdapter将根据返回的 ModelAndView(必须是已经注册到 SpringMVC 容器中的ViewResolver)返回给 DispatcherServlet;
8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
9、ViewReslover解析后返回具体View。
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。DispatcherServlet响应用户。】
4、Spring MVC体系结构介绍:
在这里插入图片描述在这里插入图片描述
5、使用SpringMVC实现页面输出
步骤:
1、下载jar文件并导入工程
spring-web-3.2.13.RELEASE.jar
spring-webmvc-3.2.13.RELEASE.jar
2、配置文件
在web.xml中配置Servlet
创建Spring MVC的配置文件
3、创建Controller-处理请求的控制器
BeanNameUrlHandlerMapping
4、创建View-jsp
5、部署运行

//导入依赖
<properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <maven.compiler.source>1.7</maven.compiler.source>
     <maven.compiler.target>1.7</maven.compiler.target>
    <spring.version>3.2.4.RELEASE</spring.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>1.7.4</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.7.4</version>
    </dependency>
  </dependencies>

方法一:使用配置文件的方式
web.xml配置
在这里插入图片描述
spring-mvc.xml
在这里插入图片描述
创建Controller:继承AbstractController,重写handleRequestInternal()
在这里插入图片描述
方法二:使用注解的方式
web.xml配置
在这里插入图片描述
spring-mvc.xml
在这里插入图片描述
在这里插入图片描述
创建Controller @Controller @RequestMapping
在这里插入图片描述在这里插入图片描述
注释:1、@Controller:标注一个普通的JavaBean成为可以处理请求的控制器 @RequestMapping:通过请求URL进行映射
2、类名前面也可以加@RequestMapping(),如@RequestMapping(“/user.do”),结合上述的方法,路径就变为了/user/login.do,但这种方式容易发生404路径错误
在这里插入图片描述
在这里插入图片描述
spring mvc 零散知识点
1.项目添加字符转码的配置

<filter>
        <filter-name>encodingFilter</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>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

2.项目controller 省去了.do的操作 具体配置web.xml配置代码

<servlet-mapping>
        <servlet-name>mvc</servlet-name>
        <url-pattern>/</url-pattern>
</servlet-mapping>

代码上的配置
@RequestMapping(value = “/show”, method = RequestMethod.POST)

3.方法中转发或重定向的写法

// return "redirect:/show.jsp";
// return "forward:/show.jsp"; ==return "/show";

注意事项
.jsp必须在页面名称的后面,否则404

4.springmvc对jsp页面的静态资源做了权限的限制, 直接在jsp页面中访问静态资源出现404的问题
<mvc:resources location="/static/" mapping="/static/**"/>

5.springmvc的局部异常的配置, 特定只能在当前配置的类中生效.
5.1实现HandlerExceptionResolver接口
implement HandlerExceptionResolver
重写方法

public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object arg2,            Exception ex) {        System.out.println("局部异常处理方法1:" + ex);        return new ModelAndView("/err");    }
5.2使用注解的方法
 @ExceptionHandler
    public ModelAndView resolveException(Exception ex){
        System.out.println("局部异常处理方法2:" + ex);
        return new ModelAndView("/err");
    }

6.全局异常配置,对所有异常进行统一处理

<!-- 全局异常配置 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <prop key="java.lang.RuntimeException">err</prop>
        </props>
    </property>
</bean>

7.整合项目
与之前不同点:web.xml代码配置

<!-- 加载spring-mybatis的配置文件 -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring-mybatis.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

8.rest风格的url参数参数
地址栏风格://http://localhost:8080/ssm/show/1/admin

@RequestMapping(value = "/show/{paramId}/{paramName}", method = RequestMethod.GET)
public String view(@PathVariable("paramId") Integer id,@PathVariable("paramName") String name, HttpServletRequest request){
    System.out.println("页面的数据:"+id+"\t"+name);
    List<Dept> list = deptService.findDeptList();
    for (Dept dept : list) {
        if(dept.getId()==id){
            request.setAttribute("dept", dept);
            break;
        }
    }
    return "/ok";
}

在这里插入图片描述
9、@DateTimeFormat
将后台的date类型的数据执行格式化操作

10.jsr 303的验证
10.1添加依赖:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.1.3.Final</version>
</dependency>
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>1.1.0.Final</version>
</dependency>
<dependency>
    <groupId>org.jboss.logging</groupId>
    <artifactId>jboss-logging</artifactId>
    <version>3.1.1.GA</version>
</dependency>

10.2验证规则
@NotNull(message = “用户名不能为空!”)
@Length(min = 6, max = 20, message = “用户名的长度必须在6-20之间”)
在这里插入图片描述
10.3在验证的对象前添加@Valid 注解
BindingResult 用于检测验证中是否存在错误提示,有错误提示跳转到提交页面显示错误信息
在这里插入图片描述
10.4显示错误信息
在这里插入图片描述
11.文件上传

<bean id="multipartResolver"
     class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
     <property name="defaultEncoding"  value="UTF-8" />
     <property name="maxUploadSize"  value="5000000" />
</bean>
表单
<form action="doupdate" method="post" enctype="multipart/form-data">
        <p>
            <input type="text" name="name">
        </p>
        <p>
            <input type="file" name="file">
        </p>
        <input type="submit" value="上传">
    </form>
控制器
@RequestMapping(value = "/doupdate", method = RequestMethod.POST)
    public String myupload(HttpServletRequest request, @RequestParam("file") MultipartFile file, String name) {
        System.out.println(name);
        if (file != null) {
            // 上传的文件路径
            // c://mydoc
            String path = request.getSession().getServletContext().getContextPath();
            // a.txt
            String filename = file.getOriginalFilename();
            // c://mydoc/a.txt
            File myFile = new File(path, filename);
            System.out.println(myFile.getAbsolutePath());
            if (!myFile.getParentFile().exists()) {
                // 创建文件夹
                myFile.getParentFile().mkdir();
            }
            try {
                // 开始文件上传
                file.transferTo(myFile);
            } catch (IllegalStateException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return "ok";
    }

12.@ModelAttribute 从后端向前端页面控件中绑定数据
13.页面获取采用springmvc的标签, 定位到modelAttribute中的对象名称
标签 path属性 属性的值必须是java中属性名称, 就能完成后台模型数据绑定到前台控件

//控制器
//从后端向前端页面控件中绑定数据@ModelAttribute("user")
    @RequestMapping(value = "/toupdate", method = RequestMethod.GET)
    public String toupdate(@ModelAttribute("user") User user) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        user.setId(1);
        user.setName("张三");
        user.setAddress("徐州");
        user.setSex(0);
        user.setAge(20);
        try {
            user.setBirthday(sdf.parse("2000-01-01"));
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Dept d = new Dept();
        d.setDid(1);
        d.setDname("开发");
        user.setDept(d);
        return "update";
    }

//前端:
<%--
    spring表单
    <fm:form action="doupdate" method="post" modelAttribute="user">
        编号:<fm:input path="id" />
        <br />
        名称:<fm:input path="name" />
        <br />
        年龄:<fm:input path="age" />
        <br />
        <fm:radiobutton path="sex" value="0" /><fm:radiobutton path="sex" value="1" /><br />
        地址:<fm:textarea path="address" /><br />
        部门:<fm:input path="dept.did" /><fm:input path="dept.dname" /><br />
        生日:<fm:input path="birthday"/>
        <input type="submit" value="修改" />
        <div style="color: red;">
            <fm:errors path="*" />
        </div>
    </fm:form>
     --%>
    
    普通表单
    <form id="user" action="doupdate" method="post">
        编号:<input id="id" name="id" type="text"/>
        <br />
        名称:<input id="name" name="name" type="text"/>
        <br />
        年龄:<input id="age" name="age" type="text"/>
        <br />
        <input id="sex1" name="sex" type="radio" value="0"/><input id="sex2" name="sex" type="radio" value="1"/><br />
        地址:<textarea id="address" name="address"></textarea><br />
        部门:<input id="dept.did" name="dept.did" type="text"/><input id="dept.dname" name="dept.dname" type="text"/><br />
        生日:<input id="birthday" name="birthday" type="text" />
        <input type="submit" value="修改" />
        <div style="color: red;">
            
        </div>
    </form>

在这里插入图片描述
14、ajax(前端和之前几乎不发生变化,后台变化如下:)
在这里插入图片描述
在这里插入图片描述
ajax嵌套:
在这里插入图片描述
在这里插入图片描述

页面:
var auctionHtml="";
$.post("findInTime",null,function(result){
    var obj = $.parseJSON(result);
    for(var i = 0;i<obj.length;i++){
        var g = obj[i];
        auctionHtml+=" <ul class=\"rows\">\n" +
            "            <li><a href=\"国书\" title=\"\">"+g.auctionName+"</a></li>\n" +
            "            <li>"+g.auctionStartTime+"</li>\n" +
            "            <li>"+g.auctionEndTime+"</li>\n" +
            "            <li>"+g.auctionStartPrice+"</li>"+
            "           <li class=\"borderno blue record\">\n";
        $.ajax({
            url:"findRecordList",
            type:"post",
            async:false,//如果不写,下面的数据出不来
            data:"id="+g.auctionId,
            success:function(result){
                var record = $.parseJSON(result);
                for(var i = 0;i<record.length;i++){
                    var r = record[i];
                    auctionHtml+= "<p>"+r.auctionuser.userName+"&nbsp;"+r.auctionPrice+"</p>\n" ;
                }
                auctionHtml+="</li>\n";
            }
        })
        auctionHtml+=" <div class=\"cl\"></div>\n" +
            "        </ul>";
    }
    $("#saleNow").html(auctionHtml);
});

效果图:
在这里插入图片描述
15、验证码
在这里插入图片描述

//Number.jsp
<%@ page contentType="image/jpeg"
   import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*"
   pageEncoding="utf-8"%>
<%!Color getRandColor(int fc, int bc) {//给定范围获得随机颜色  
      Random random = new Random();
      if (fc > 255)
         fc = 255;
      if (bc > 255)
         bc = 255;
      int r = fc + random.nextInt(bc - fc);
      int g = fc + random.nextInt(bc - fc);
      int b = fc + random.nextInt(bc - fc);
      return new Color(r, g, b);
   }
%>
<%
   //设置页面不缓存  
   response.setHeader("Pragma", "No-cache");
   response.setHeader("Cache-Control", "no-cache");
   response.setDateHeader("Expires", 0);
   // 在内存中创建图象  
   int width = 60, height = 20;
   BufferedImage image = new BufferedImage(width, height,
         BufferedImage.TYPE_INT_RGB);
   // 获取图形上下文  
   Graphics g = image.getGraphics();
   //生成随机类  
   Random random = new Random();
   // 设定背景色  
   g.setColor(getRandColor(200, 250));
   g.fillRect(0, 0, width, height);
   //设定字体  
   g.setFont(new Font("Times New Roman", Font.PLAIN, 18));
   //画边框  
   //g.setColor(new Color());  
   //g.drawRect(0,0,width-1,height-1);  
   // 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到  
   g.setColor(getRandColor(160, 200));
   for (int i = 0; i < 155; i++) {
      int x = random.nextInt(width);
      int y = random.nextInt(height);
      int xl = random.nextInt(12);
      int yl = random.nextInt(12);
      g.drawLine(x, y, x + xl, y + yl);
   }
   // 取随机产生的认证码(4位数字)  
   String sRand = "";
   for (int i = 0; i < 4; i++) {
      String rand = String.valueOf(random.nextInt(10));
      sRand += rand;
      // 将认证码显示到图象中  
      g.setColor(new Color(20 + random.nextInt(110), 20 + random
            .nextInt(110), 20 + random.nextInt(110)));//调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成  
      g.drawString(rand, 13 * i + 6, 16);
   }
   // 将认证码存入SESSION  
   session.setAttribute("numrand", sRand);
   // 图象生效  
   g.dispose();  
   // 输出图象到页面  
   ImageIO.write(image, "JPEG", response.getOutputStream());  
   out.clear();  
   out = pageContext.pushBody();   
%>

验证码存在session里的,后面要到session里取出来
在这里插入图片描述
jsp页面
在这里插入图片描述
16、短消息验证结合Redis存储
1、注册云通信
2、讲本地jar包打入本地仓库里去
在这里插入图片描述
命令:

mvn install:install-file -Dfile=sms-java-sdk-2.6.3.jar -DgroupId=com.zb -DartifactId=sms-java-sdk -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true

3、导入依赖

<!--云通信短消息验证-->
    <dependency>
      <groupId>com.zb</groupId>
      <artifactId>sms-java-sdk</artifactId>
      <version>1.0</version>
    </dependency>
<!--redis-->
    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.1.0</version>
    </dependency>

4、添加工具类

@Component
public class SMSService {
   
   public void send(String to, String templated, String[]datas){
      //https://www.yuntongxun.com/member/main
      CCPRestSmsSDK sdk = new CCPRestSmsSDK();
      //生产环境请求地址:app.cloopen.com
      sdk.init("app.cloopen.com", "8883");//请求端口
      //主账号,登陆云通讯网站后,可在控制台首页看到开发者主账号ACCOUNT SID和主账号令牌AUTH TOKEN
      sdk.setAccount("8a216da870e2267e01712ff8a629299d", "0a6b572fbe6048519cb0e9ceb653b176");
      sdk.setAppId("8a216da870e2267e01712ff8a68029a3");
      HashMap result = sdk.sendTemplateSMS(to, templated, datas);
      System.out.println(result);
   }
   //测试
   public static void main(String[] args) {
      SMSService sms = new SMSService();
      int code = (int)(Math.random()*10000);
      System.out.println(code);
      //templated模板
      sms.send("15851997193", "1", new String[]{code+"","1"});
   }
}

5、控制器(结合Redis):

@RequestMapping("/sendmsg")
@ResponseBody
public String mySend(String phone ){
    Jedis jedis = new Jedis("127.0.0.1", 6379);
    jedis.auth("ok");
    int genterCode = (int)(Math.random()*10000);
    System.out.println(genterCode);
    SMSService sms = new SMSService();
    sms.send(phone, "1", new String[]{genterCode+"","1"});
    String key = "phone_"+phone;
    jedis.set(key,genterCode+"");
    jedis.expire(key,60);
    return "ok";
}


@RequestMapping("/validate")
@ResponseBody
public String validate(String phone , String inCode,String name, String password, HttpSession session){
    Auctionuser auctionuser = as.userLogin(name,password);
    session.setAttribute("user",auctionuser);
    Jedis jedis = new Jedis("127.0.0.1", 6379);
    jedis.auth("ok");
    String key = "phone_"+phone;
    if(jedis.exists(key)){
        String redisCode = jedis.get(key);
        if(auctionuser!=null&&auctionuser.getUserIsadmin()!=1&&redisCode.equals(inCode)){
            return "ok";
        }else{
            return "error";
        }
    }else{
        return "input";
    }
}
<script type="text/javascript" src="statics/js/jquery-1.12.4.js"></script>
<script type="text/javascript">
    var mytime ;
    $(function() {
        $("#send").on("click",function(){
            var phone = $("#phone").val();
            $.post('sendmsg','phone='+phone,function(result){
                if(result=="ok"){
                    mytime=setInterval("mt()",1000);//定时函数,每一秒钟调用mt()
                }
            });
        });


        $("#sbt").click(function () {
            var phone = $("#phone").val();
            var inCode = $("#code").val();
            var name = $("#name").val();
            var password = $("#password").val();
            $.ajax({
                url:"validate",
                type:"post",
                data:"phone="+phone+"&inCode="+inCode+"&name="+name+"&password="+password,
                success:function (result) {
                    if(result=="input"){
                        $("#smsMsg").html("验证码已超时");
                    }else if(result=="error"){
                        $("#smsMsg").html("验证码输入不正确");
                    }else if(result=="ok"){
                        location.href="commonAuctionList.jsp";
                    }
                }
            });
        })
    });
    var mi=60;
    function mt(){//倒计时函数
        if(mi!=1){
            mi=mi-1;
            $("#msg").html(mi+"秒");
        }else{
            clearInterval(mytime);
            mi=60;
            $("#msg").html("<input type=\"button\" id=\"send\" value=\"发送\" />");
        }
    }
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值