SpringMVC框架教程 JavaWeb开发(SSM框架第三部分)从介绍SpringMvc到使用SpringMvc让你掌握核心知识(值得收藏)

服务器端三层架构:表现层(SpringMVC)、业务层(Spring)、持久层(Mybatis)
表现层:拿到http请求的参数,传递给spring

在这里插入图片描述
SpringMVC:一种基于Java实现的MVC设计模型的请求驱动类型的轻量级框架
M(model):javaBean对象(将参数封装成JavaBean对象交给业务层处理)
V(view):jsp (向控制器提交数据,显示模型中的数据)
C(controller):servlet(根据视图提出的请求判断将请求交给那个模型处理,将处理后的结果交给对应的视图更新显示)

在Spring MVC框架中,从“Request(请求)”开始,依次进入“DispatcherServlet(核心分发器)” —> “HandlerMapping(处理器映射)” —> “Controller(控制器)” —> “ModelAndView(模型和视图)” —> “ViewResolver(视图解析器)” —> “View(视图)” —> “Response(响应)”结束,其中DispatcherServlet、HandlerMapping和ViewResolver 只需要在XML文件中配置即可,从而大大提高了开发的效率,特别是对于 HandlerMapping 框架为其提供了默认的配置。

1.HandlerMapping(处理器映射):通过映射找到哪个控制器执行哪个方法@RequestMapping(path=“”)再通过HandlerAdapter适配器执行方法
2.ViewResolver(视图解析器):找到哪个视图的显示

在这里插入图片描述

SpringMVC和struct2区别:
(1)共同:都是表现层框架,离不开ServletAPI, 请求的机制都是一个核心控制器
(2)不同:1.SpringMVC核心控制器是Servlet,Struct是Filter
2.SpringMVC是基于方法设计的,Struct是基于类设计的,前者效率较高
3.SpringMVC使用更简洁,支持JSR303,处理ajax请求更方便
4.Struct的OGNL表达式比SpringMVC开发效率高,执行效率比JSTL低,尤其Struct的表单标签,没有html效率高

mvc:annotation-driven/打开注解(处理器映射器、处理器适配器、视图解析器配置)
使用maven构建webapp项目,maven添加archetypeCatalog=internal,国外服务器太慢

RequestMapping:可用在类和方法上
@RequestMapping(path = “/start”,method = RequestMethod.GET,params = {“username”})
params指的是必须携带的参数 username=?
请求参数绑定
当你以表当post提交参数时,RequestMapping可以根据HandlerMapping寻找指定controller携带的javabean类对象参数将参数封装成一个bean对象返回(jsp表单指定属性name值要与bean对象属性名相同,当参数时包装对象时,应使用包装对象里的对象名加属性)

<form action="params/userVoadd" method="post">
    username<input type="text" name="user.username"></br>
    password<input type="password" name="user.password"></br>
    money<input type="text" name="user.money"></br>
    UserVoName<input type="text" name="userVoname"></br>
    UserVoPassword<input type="text" name="userVopassword"></br>
    <input type="submit" value="submit">
</form>

请求时参数转换器
(1)首先定义一个类继承Converter或者formatter类,
前者可用泛型表达参数转换类型<String,Integer>,后者使用,formatter转换源类型必须是String,对于Web应用Http发送的数据都是以String类型存储,使用formatter更合适

public class Convertors implements Converter<String,Date> {

    @Override
    public Date convert(String s) {
        if(s==null){
            throw new RuntimeException("请你传入数据!");
        }
        DateFormat df=new SimpleDateFormat("yyyy-MM-dd");

        try {
            return df.parse(s);
        } catch (ParseException e) {
            throw new RuntimeException("转换出错");
        }
    }
}

(2)在主文件中配置装换器

<bean class="org.springframework.context.support.ConversionServiceFactoryBean" id="conversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.dingxiang.utils.DateConvertor.Convertors"/>
            </set>
        </property>
    </bean>

(3)在注解中打开转换器

<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"/>

常用注解
(1)RequestParam=request.getParameter(“name”)(name和value属性基本等同,required表示是否必须)

用s来获取参数username
public String testRequestParam(@RequestParam(name = "username")String s){
        System.out.println(s);
        return "start";
    }

(2)RequestBody(获取请求体的内容,得到key=value&keyvalue…,gei方式不适用)

获取表单传递参数,用字符串接受
public String testRequestBody(@RequestBody String body){
        System.out.println(body);
        return "start";
    }

(3)PathVariable使用RESTful风格,即根据参数传递类型和参数数量选取不同的方法执行,

使用占位符{}直接传入参数
@RequestMapping("/testPathVariable/{id}")
    public String testPathVariable(@PathVariable(value = "id") String body){
        System.out.println(body);
        return "start";
    }

使用静态方法发送请求 浏览器插件测试各种请求方式
(4) RequestHeader(少用)

@RequestHeader(value = "User-Agent")

(5)CookieValue(少用)

@CookieValue(value = "JSESSIONID")

(6)ModelAttribute(方法、参数)首先执行
用于将多个参数封装到一个实体对象,从而简化数据绑定流程,自动暴露为模型数据,在视图展示时使用
两种方法,返回bean对象或者通过把bean对象加入到集合使用注解来读取

 @RequestMapping("/testModelAttribute")
    public String testModelAttribute(@ModelAttribute("1") User user){
        System.out.println("testModelAttribute");
        System.out.println(user.toString());
        return "start";
    }
    @ModelAttribute
    public void modelattribute(Map<String,User> map){
        User user=new User();
        user.setDate(new Date());
        user.setMoney(12.212);
        map.put("1",user);
    }
@RequestMapping("/testModelAttribute")
    public String testModelAttribute(User user){
        System.out.println("testModelAttribute");
        System.out.println(user.toString());
        return "start";
    }
    @ModelAttribute
    public User modelattribute(){
        User user=new User();
        user.setDate(new Date());
        user.setMoney(12.212);
        return user;
    }

(7)SessionAttribute
使用HttpSession的话需要servletAPI支持,存在耦合
value代表我们需要把什么样的对象放入session

@SessionAttributes(value = {"name"})

(8)不让前端控制器拦截资源文件
<mvc:resources mapping="/css/**" location="/css/**"/>

(9)ResponseBody 使用到了json转换器jackson,添加maven依赖
核心包:jackson-databind jackson-annatation jackson-core

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

jQuery Ajax实现前后台json数据传输并使用@RequestBody封装成对象传输到后台@ResponseBody封装成对象返回到jsp

$(function () {
            $('#ajax').click(function () {
                $.ajax({
                    url:'user/testAjax2',
                    contentType:'application/json; charset=UTF-8',
                    type:'post',
                    data:'{"username":"zoufuob","password":"12345"}',
                    dataType:'json',
                    error:function () {
                        alert("获取数据失败")
                    },
                    success:function (data) {
                        alert(data.username)
                        alert(data.password)
                    }
                })
            })
        })
//jackson把json String封装发哦user对象
@RequestMapping("/testAjax2")
    public @ResponseBody User testAjax2(@RequestBody User user){
        System.out.println("执行了testAjax2");
        System.out.println(user);
        //模拟查找修改数据库数据
        user.setUsername("wangdatao");
        user.setPassword("52zoufubo");
        return user;
    }

异常处理
(1)异常类 继承Exception
(2)异常解析类 实现接口HandlerExceptionResolver重写resolveException方法

public ModelAndView resolveException(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object o, Exception e) {
        //获取异常对象
        SysException exception=null;
        if(e instanceof SysException){
            exception= (SysException) e;
        }else{
            exception = new SysException("error");
        }
        //创建modelandview
        ModelAndView modelAndView=new ModelAndView();
        modelAndView.addObject("errorMsg",exception.getMsg());
        modelAndView.setViewName("error");
        return modelAndView;
    }

(3)配置异常处理器(配置异常解析类对象到spring)
在这里插入图片描述
文件上传
表单 enctype=“multipart/form-data”
1.文件上传
用MultipartFile对象作为Controller参数接收表单传入数据,通过transferTo方法上传文件

public String testUpload2(HttpServletRequest request, MultipartFile upload2)throws Exception{
        System.out.println("文件上传");
        String path=request.getSession().getServletContext().getRealPath("/uploads/");
        File file=new File(path);
        if(!file.exists()){
            file.mkdir();
        }
        String name=upload2.getOriginalFilename();
        String uuid=UUID.randomUUID().toString().replace("-","");
        name=uuid+"_"+name;
        upload2.transferTo(new File(path,name));
        return "success";
    }

2.跨服务器上传文件
(1)创建客户端对象
(2)与服务器建立连接
(3)传入数据

@RequestMapping("testUpload3")
    public String testUpload3(MultipartFile upload3) throws IOException {
        System.out.println("跨服务器文件上传");
        String path="http://localhost:8090/uploads/";
        String name=upload3.getOriginalFilename();
        String uuid=UUID.randomUUID().toString().replace("-","");
        name=uuid+"_"+name;
        //创建客户端对象
        Client client=Client.create();
        //与服务器进行连接
        WebResource resource=client.resource(path+name);
        //传文件
        resource.put(upload3.getBytes());
        return "success";
    }

拦截器
功能与过滤器基本相同,但是拦截器只能对用户请求的方法进行拦截,用在权限验证,判断用户是否登录,记录请求信息的日志
(1)拦截器类 实现接口HandlerInterceptor 可重写
preHandle(返回true时执行下一个拦截器,没有拦截器时执行Controller)
postHandle(该方法在控制器请求方法调用之后,视图解析之前进行执行)
afterHandle(在视图解析后执行)
(2)配置拦截器

<mvc:interceptors>
        <mvc:interceptor>
            <!--要拦截的方法-->
            <mvc:mapping path="/user/testInterceptor"/>
            <bean class="com.dingxiang.Interceptor.MyInterceptor" id="myInterceptor"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <!--要拦截的方法-->
            <mvc:mapping path="/user/testInterceptor"/>
            <bean class="com.dingxiang.Interceptor.MyInterceptor2" id="myInterceptor2"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/login/main"/>
            <bean class="com.dingxiang.Interceptor.loginInterceptor.LoginInterceptor" id="loginInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

数据验证
网页前端验证后还需要在服务器端对数据进行验证
1.Spring Validator接口
首先需要编写一个Vaidator类实现该接口,对数据进行验证的配置,相当于JSR303的注解配置验证信息;
然后再主配置文件中配置一个ReloadableResourceBundleMessageSource Bean并打开注解validator

<bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource" id="messageSource">
        <property name="basename" value="classpath:errorMessege"/>
    </bean>
<mvc:annotation-driven validator="validator"/>

2.JSR303 JSR-303 是 Java EE 6 中的一项子规范,叫做 Bean Validation JSR 303 用于对 Java Bean 中的字段的值进行验证。

  1. Bean Validation 中内置的 constraint
    @Null
    被注释的元素必须为 null
    @NotNull
    被注释的元素必须不为 null
    @AssertTrue
    被注释的元素必须为 true
    @AssertFalse
    被注释的元素必须为 false
    @Min(value)
    被注释的元素必须是一个数字,其值必须大于等于指定的最小值
    @Max(value)
    被注释的元素必须是一个数字,其值必须小于等于指定的最大值
    @DecimalMin(value)
    被注释的元素必须是一个数字,其值必须大于等于指定的最小值
    @DecimalMax(value)
    被注释的元素必须是一个数字,其值必须小于等于指定的最大值
    @Size(max, min)
    被注释的元素的大小必须在指定的范围内
    @Digits (integer, fraction)
    被注释的元素必须是一个数字,其值必须在可接受的范围内
    @Past
    被注释的元素必须是一个过去的日期
    @Future
    被注释的元素必须是一个将来的日期
    @Pattern(value)
    被注释的元素必须符合指定的正则表达式

  2. Hibernate Validator 附加的 constraint
    @Email
    被注释的元素必须是电子邮箱地址
    @Length
    被注释的字符串的大小必须在指定的范围内
    @NotEmpty
    被注释的字符串的必须非空
    @Range
    被注释的元素必须在合适的范围内
    与Validator不同的是需要配置一个LocalValidatorFactoryBean

 <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
        <property name="validationMessageSource" ref="messageSource"/>
    </bean>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值