SpringMVC入门学习总结(二)

写在前面

上一篇主要写了入门级别的SpringMVC程序(http://blog.csdn.net/qq_18242391/article/details/52951825),里面的后台控制器都要实现controller接口或其他控制器接口,才能接受请求,完成相应的逻辑操作。首先来熟悉下其工作流程,这是官方的一个流程图。

这里写图片描述

同时SpringMVC也提供了用注解来实现相应的逻辑操作,这种强大的数据绑定功能,让其使用起来非常方便,用普通类加注解就可以实现数据收集功能。话不多说,下面来看正文。

正文开始,常用知识点总结

  • @Controller 这个注解一般用在要请求的类上,也就是相当后端控制器

  • @RequestMapping 用来定义访问的URL,也就是前面Spring配置文件bean标签中的name属性

@Controller
public class Demo1 {

    @RequestMapping(value = "/hello")
    public String helloMethod(Model model){

        System.out.println("Demo1::helloMethod");
        model.addAttribute("message", "SpringMVC注解");

        return "/success.jsp";
    }

}

这是一个简单的控制器,该类为一个普通类,方法也是随便定义,http请求主要匹配的是@RequestMapping 中的value值,hello后缀可以省略.。 model携封装的是key-value值,接下来看Spring.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans 
      xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:context="http://www.springframework.org/schema/context"
      xmlns:aop="http://www.springframework.org/schema/aop"
      xmlns:tx="http://www.springframework.org/schema/tx"
      xmlns:mvc="http://www.springframework.org/schema/mvc"

      xsi:schemaLocation="

      http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd

      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd

      ">


      <!-- Action控制器 -->
      <context:component-scan base-package="cn.itcast.javaee.springmvc.helloannotation"/>   



      <!-- 基于注解的映射器(可选) -->
      <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>

      <!-- 基于注解的适配器(可选) -->
      <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>

      <!-- 视图解析器(可选) -->
      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>

</beans>

context:component-scan 表示扫描相应包下的注解,扫描到了,就执行相应类文件。

当然别忘了配置web.xml和写前端jsp页面,这里就不写了,通过浏览器访问到的URL,响应结果如下:

这里写图片描述

一个Action中,可以写多个类似的业务控制方法

  • 通过模块根路径 + 功能子路径 = 访问模块下子功能的路径
@Controller
@RequestMapping(value="/user")
public class UserAction{
    @RequestMapping(value="/add")
    public String add(Model model) throws Exception{
        System.out.println("HelloAction::add()");
        model.addAttribute("message","增加用户");
        return "/success.jsp";
    }
    @RequestMapping(value="/find")
    public String find(Model model) throws Exception{
        System.out.println("HelloAction::find()");
        model.addAttribute("message","查询用户");
        return "/success.jsp";
    }   
}

@RequestMapping(value=”/user”) 这个相当于struts2里面的namespace

在业务控制方法中写入普通变量收集参数

可以在业务控制方法中,以参数形式收集客户端参数,springmvc采用的是方法参数形式,如下

@Controller
@RequestMapping(value="/user")
public class UserAction{
    @RequestMapping(value="/add")
    public String add(Model model,int id,String name,Double sal) throws Exception{
        System.out.println("HelloAction::add()");
        System.out.println(id + ":" + name + ":" + sal);
        model.addAttribute("message","增加用户");
        return "/success.jsp";
    }   
}

限定某个业务控制方法

有时候前端注册的信息只想用POST方式提交表单,或者登陆时只想用GET方式提交,我们可以这样

@Controller
@RequestMapping(value="/user")
public class UserAction{
    @RequestMapping(value="/add",method=RequestMethod.POST)
    public String add(Model model,int id,String name,double sal) throws Exception{
        System.out.println("HelloAction::add()::POST");
        System.out.println(id + ":" + name + ":" + sal);
        model.addAttribute("message","增加用户");
        return "/success.jsp";
    }   
}

method=RequestMethod.POST 限定了请求只能用POST方式,而不能用GET方式,否则会报如下错误

这里写图片描述

这里表明了 只能用method中限定的方式访问服务器。 提下,平时我们都不写method,这里GET和POST请求都支持。

传统web参数的支持

我们可以在业务控制方法中书写传统web参数,实现传统的业务请求响应操作

@Controller
@RequestMapping(value="/user")
public class UserAction{
    @RequestMapping(value="/add",method=RequestMethod.POST)
    public void add(HttpServletRequest request,HttpServletResponse response) throws Exception{
        System.out.println("HelloAction::add()::POST");
        int id = Integer.parseInt(request.getParameter("id"));
        String name = request.getParameter("name");
        double sal = Double.parseDouble(request.getParameter("sal"));
        System.out.println(id + ":" + name + ":" + sal);
        request.getSession().setAttribute("id",id);
        request.getSession().setAttribute("name",name);
        request.getSession().setAttribute("sal",sal);
        response.sendRedirect(request.getContextPath()+"/register.jsp");
    }   
}

不过这种方式就不推荐了,耦合了,毕竟我们用框架就不提倡用传统的方式来做这种请求操作。

用模型变量收集参数

顺便一提,可以使用@InitBind 来解决字符串转日期类型的问题

    <form action="${pageContext.request.contextPath}/user/add.action" method="POST">
        编号:<input type="text" name="id" value="${id}"/><br/>
        姓名:<input type="text" name="name" value="${name}"/><br/>
        薪水:<input type="text" name="sal" value="${sal}"/><br/>
        入职时间:<input type="text" name="hiredate" value='<fmt:formatDate value="${hiredate}" type="date"/>'/><br/>
        <input type="submit" value="注册"/>
    </form>

@Controller
@RequestMapping(value = "/user")
public class UserAction {
    @InitBinder
    protected void initBinder(HttpServletRequest request,ServletRequestDataBinder binder) throws Exception {
        binder.registerCustomEditor(
                Date.class, 
                new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
    }
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String add(int id, String name, double sal, Date hiredate,
            Model model) throws Exception {
        System.out.println("HelloAction::add()::POST");
        model.addAttribute("id", id);
        model.addAttribute("name", name);
        model.addAttribute("sal", sal);
        model.addAttribute("hiredate", hiredate);
        return "/register.jsp";
    }
}

在业务控制方法中写入bean,model模型收集参数

  • 可以在业务控制方法中书写1个模型来收集客户端的参数
  • 模型中的属性名必须和客户端参数名一一对应
  • 这里说的模型不是Model对象,Model是向视图中封装的数据
@Controller
@RequestMapping(value = "/user")
public class UserAction {
    @InitBinder
    protected void initBinder(HttpServletRequest request,ServletRequestDataBinder binder) throws Exception {
        binder.registerCustomEditor(
                Date.class, 
                new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
    }
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String add(User user,Model model) throws Exception {
        System.out.println("HelloAction::add()::POST");
        model.addAttribute("user",user);
        return "/register.jsp";
    }
}

在业务控制方法中收集数组参数

//批量删除用户
@Controller
@RequestMapping(value="/user")
public class UserAction {
    @RequestMapping(value="/delete")
    public String deleteMethod(int[] ids,Model model) throws Exception{
        System.out.println("UserAction::deleteMethod()");
        System.out.println("需要删除的id为:");
        for(int id : ids){
            System.out.print(id+" ");
        }
        model.addAttribute("message","批量删除成功");
        return "/success.jsp";
    }
}

//前端
<form action="${pageContext.request.contextPath}/user/delete.action" method="POST">
        <table border="2" align="center">
            <tr>
                <th>编号</th>
                <th>姓名</th>
            </tr>
            <tr>
                <td><input type="checkbox" name="ids" value="1"/></td>
                <td>哈哈</td>
            </tr>
            <tr>
                <td><input type="checkbox" name="ids" value="2"/></td>
                <td>呵呵</td>
            </tr>
            <tr>
                <td><input type="checkbox" name="ids" value="3"/></td>
                <td>嘻嘻</td>
            </tr>
            <tr>
                <td><input type="checkbox" name="ids" value="4"/></td>
                <td>笨笨</td>
            </tr>
            <tr>
                <td><input type="checkbox" name="ids" value="5"/></td>
                <td>聪聪</td>
            </tr>
            <tr>
                <td>
                    <input type="submit" value="删除"/>
                </td>
            </tr>
        </table>
    </form>

这种方式常用于收集checkbox的方式提交的数据

在业务控制方法中收集List参数

批量注册用户
UserAction.java
@Controller
@RequestMapping(value="/user")
public class UserAction {
    @RequestMapping(value="/addAll")
    public String addAll(Bean bean,Model model) throws Exception{
        for(User user : bean.getUserList()){
            System.out.println(user.getName()+":"+user.getGender());
        }
        model.addAttribute("message","批量增加用户成功");
        return "/success.jsp";
    }
}
    Bean.java
public class Bean {
    private List<User> userList = new ArrayList<User>();
    public Bean(){}
    public List<User> getUserList() {
        return userList;
    }
    public void setUserList(List<User> userList) {
        this.userList = userList;
    }
}
    registerAll.java
    <form action="${pageContext.request.contextPath}/user/addAll.action" method="POST"> 

        姓名:<input type="text" name="userList[0].name" value="哈哈"/>
        性别:<input type="text" name="userList[0].gender" value="男"/>
        <hr/>

        姓名:<input type="text" name="userList[1].name" value="呵呵"/>
        性别:<input type="text" name="userList[1].gender" value="男"/>
        <hr/>

        姓名:<input type="text" name="userList[2].name" value="嘻嘻"/>
        性别:<input type="text" name="userList[2].gender" value="女"/>
        <hr/>

        <input type="submit" value="批量注册"/>

    </form>

结果的转发和重定向

在转发情况下,共享request域对象,会将参数从第一个业务控制方法传入第二个业务控制方法,反之,重定向则不行。

//删除id=10号的用户,再查询用户
@Controller
@RequestMapping(value="/user")
public class UserAction {

    @RequestMapping(value="/delete")
    public String delete(int id) throws Exception{
        System.out.println("删除用户->" + id);
        //转发到find()
        return "forward:/user/find.action";
        //重定向到find()
        //return "redirect:/user/find.action";
    }

    @RequestMapping(value="/find")
    public String find(int id) throws Exception{
        System.out.println("查询用户->" + id);
        return "/success.jsp";
    }

}

例子

异步发送表单数据到JavaBean,并响应JSON文本返回

bean2json.jsp
    <form>
        编号:<input type="text" name="id" value="1"/><br/>
        姓名:<input type="text" name="name" value="哈哈"/><br/>
        薪水:<input type="text" name="sal" value="5000"/><br/>
        <input type="button" value="异步提交注册"/>
    </form>

    <script type="text/javascript">
        $(":button").click(function(){
            var url = "${pageContext.request.contextPath}/user/add.action";
            var sendData = {
                "id":1,
                "name":"哈哈",
                "sal":5000
            };
            $.post(url,sendData,function(backData,textStatus,ajax){
                alert(ajax.responseText);
            });
        });
    </script>
    User.java
public class User {
    private Integer id;
    private String name;
    private Double sal;
    public User(){}
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Double getSal() {
        return sal;
    }
    public void setSal(Double sal) {
        this.sal = sal;
    }
}
UserAction.java
@Controller
@RequestMapping(value="/user")
public class UserAction {

    @RequestMapping(value="/add")
    public @ResponseBody User add(User user) throws Exception{
        System.out.println(user.getId()+":"+user.getName()+":"+user.getSal());
        return user;
    }

}
spring.xml
      <!-- Action控制器 -->
      <context:component-scan base-package="cn.itcast.javaee.springmvc.app25"/>     


      <!-- 配适器 -->
      <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
            <property name="messageConverters">
                <list>
                    <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
                </list>
            </property>
      </bean>

可以看到这里配置文件中的适配器主要将控制器中的返回值,转化为json并传给前端响应。

SpringMVC工作流总结

  • 1 客户端发出http请求,只要请求形式符合web.xml文件中配置的*.action的话,就由 DispatcherServlet来处理。

  • 2 DispatcherServlet再将http请求委托给映射器的对象来将http请求交给对应的Action来处理。

  • 3 映射器根据客户的http请求,再对比

  • 4 适配器负责找到Action中业务方法。

  • 5 执行Action中的业务方法,最终返回一个名叫ModelAndView 的对象,其中封装了向视图发送的数据和视图的逻辑名。

  • 6 ModelAndView对象随着响应到DispatcherServlet中了 。

  • 7 这时DispatcherServlet收到了ModelAndView对象,它也不知道视图逻辑名是何意,又得委托一个名叫视图解析器的对象去具体解析ModelAndView对象中的内容。

  • 8 将视图解析器解析后的内容,再次交由DispatcherServlet核心控制器,这时核心控制器再将请求转发到具体的视图页面,取出数据,再显示给用户。

这里写图片描述

最后

从前面的例子可以看见,我们在使用springmvc的注解时非常灵活,通常可以自己定制自己的业务控制器,不比Struts2,必须用特定接口和规范,来完成业务逻辑,当然SpringMVC的知识点还有很多,这只是微不足道的冰山一角,以后知道了再继续补充。 咳咳,由于本人能力有限,还只是刚刚学习,很多地方不懂,总结只能写这些最基础的东西,相信通过不断的学习,总有一天能写出有技术含量的文章的,哈哈,人生还是得乐观点,作为一名伟大的程序员,这是一份值得骄傲的事业,要努力干下去,让代码将梦想照进现实哈。上张我最喜欢的naruto作为文章的结束吧。。。。

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值