微信小程序填坑之路之springmvc-注解版(三)

  • • 发表于 8年前
  • • 作者 toBeMN
  • • 4865 人浏览
  • • 1 条评论
  • • 最后编辑时间 8年前
  • • 来自 [技 术]

原创声明:本文为作者原创,未经允许不得转载,经授权转载需注明作者和出处

传统的setter注入,都需要在springmvc配置文件中配置bean等操作,随着项目的扩展,整个配置文件就不敢看了,显得紊乱且效率低下,我们在开发的时候还需要配置文件和action之间来回切换,很不方便。于是注解应运而生,它充分的利用了Java的反射机,减少配置工作,直接在action类中进行设置,遵循了高内聚低耦合的设计模式,让代码跟美观,让开发更高效。

现在重点解析的不在是配置文件,而是Action类,web.xml的配置与上一篇“xml版配置”中web.xml配置一样。

UserAction类

package action;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class UserAction{
    @RequestMapping(value="/login.mn")
    public String login(){
        return "login";
    }
    @RequestMapping(method=RequestMethod.POST,"/logout")
    public String logout(){
        return "logout";
    }
}

在类上方添加注解@Controller,对应的方法上添加注解@RequestMapping,即可通过localhost:8080/springMVC(项目名)/login.mn访问到对应的方法中,上面的例子返回逻辑视图路径。
(value值和方法名没有关联,可以不一样)


光标停留在@RequestMapping左括号后,按Alt+/可看出该注解可使用的参数有4个,并且都是数组。
就此,我们可以得知:
value={"/login.mn","","",""}可以让多个请求访问该方法
method={RequestMethod.POST,RequestMethod.GET,...}可以让该方法接受不同的请求类型

@RequestMapping需要注意的有四点:
1.如果使用参数“只有”value,可以省略value=,直接写上地址。
2.各个参数位置不固定
3.不写method,默认get,post方法都可访问(建议写上,因为get是通过地址后携带参数的方法传值过来的,为防止有人提交恶意数据,需要传值的请求请写上method=RequestMethod.POST)
4.value的值可以省略后缀.mn,但页面上的请求路径是不能省略的

这样简单的Action类就配置完了
然后在springmvc.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:mvc="http://www.springframework.org/schema/mvc"
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <!-- Action,让springioc容器去扫描带@Controller的类,base-package:扫描指定包
    需要添加 xmlns:context="http://www.springframework.org/schema/context"和
    http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd"
    -->
    <context:component-scan base-package="action"/>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

在之前springmvc.xml配置文件的基础上,在头部信息中添加xmlns:context="http://www.springframework.org/schema/context"
及其对应的约束文件http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.0.xsd

之后配置<context:component-scan base-package="action"/>,让springioc容器去扫描带@Controller的类(UserAction.java),base-package是指定要扫描的包(我写的UserAction.java在action包中)

login.jsp和logout.jsp文件只是简单的写上“登录成功,退出成功”
配置结束,运行:


第二个运行结果失败的原因是因为设置了只接受post请求,而在地址栏直接访问默认是get

如果在类方法上也添加了@RequestMapping,则请求地址就是 类级@RequestMapping+方法级@RequestMapping

package action;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/user")
public class UserAction{
    @RequestMapping(value="/login.mn")
    public String login(){
        return "login";
    }
    @RequestMapping(value="/logout")
    public String logout(){
        return "logout";
    }
}

结果:

Action扩展

表单与后台的交互(普通参数)

user.jsp

<body>
    <form action="${pageContext.request.contextPath }/user/login.mn" method="POST">
        姓名:<input type="text" name="username"/><br/>
        年龄:<input type="text" name="age" /><br/>
        <input type="submit" value="登录"/>
    </form>
</body>

success.jsp页面只有一局EL表达式用来输出后台传过来的值

<body>
    ${msg }
</body>

UserAction.java

package action;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/user")
public class UserAction{
    @RequestMapping("/login")
    public String login(Model model,String username,int age){
        model.addAttribute("msg","姓名:"+username+"年龄:"+age);
        return "success";
    }
}

在没有学习更多注解的情况下,使用model(跟ModelAndView不是一个东西)传值给前台,之后的参数username,age必须与前台表单中的name一致,才能够正确的传值

结果:

点击登录

表单与后台的交互(数组参数)

user.jsp

<form action="${pageContext.request.contextPath }/user/login.mn" method="POST">
    <input type="text" name="list" value="to"/><br/>
    <input type="text" name="list" value="Be"/><br/>
    <input type="text" name="list" value="M"/><br/>
    <input type="text" name="list" value="N"/><br/>
    <input type="submit" value="提交" />
</form>

name全都一样

UserAction.java

@Controller
@RequestMapping("/user")
public class UserAction{
    @RequestMapping("/login")
    public String login(String[] list,Model model){
        String str="";
        for(int i=0;i<list.length;i++){
            str+=list[i];
        }
        model.addAttribute("msg",str);
        return "success";
    }
}

用数组接收

结果

表单与后台的交互(对象参数)

普通的参数缺陷很明显,如果页面传来十几个参数,那Action也得用十几个参数来取值,所以使用对象封装很有必要

需要添加实体类

package bean;
public class User {
    private String username;
    private int age;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

注意不要写带参数的构造函数,否则会报500错
Could not instantiate bean class [bean.User]: No default constructor found

user.jsp

<form action="${pageContext.request.contextPath }/user/login.mn" method="POST">
    姓名:<input type="text" name="username"/><br/>
    年龄:<input type="text" name="age" /><br/>
    <input type="submit" value="登录"/>
</form>

注意name值的改变!

UserAction.java

@Controller
@RequestMapping("/user")
public class UserAction{
    @RequestMapping("/login")
    public String login(Model model,User user){
        model.addAttribute("msg","姓名:"+user.getUsername()+"年龄:"+user.getAge());
        return "success";
    }
}

结果与上面例子一致

表单POST请求中文乱码

上面的例子当输入中文时会出现乱码

点击登录

这是为什么,看了看页面编码

没有错也,在看tomcat编码

还是没有错,那是什么问题
原来排除页面编码,tomcat编码的问题,还需要在web.xml文件中配置spring提供的针对于post请求的设置编码格式的过滤器(注意是针对post,所以请求如果带有参数请使用post)

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

我的编码格式统一是utf-8
最后访问结果:

请求转发

(直接使用 数组参数 的例子)
修改Action类

@Controller
@RequestMapping("/user")
public class UserAction{
    @RequestMapping("/login")
    public String login(){
        System.out.println("我是第一个被请求的");
        return "forward:/user/newLogin.mn";
    }
    @RequestMapping("/newLogin")
    public String newLogin(String[] list,Model model){
        System.out.println("我是第二个被请求的");
        String str="";
        for(int i=0;i<list.length;i++){
            str+=list[i];
        }
        model.addAttribute("msg",str);
        return "success";
    }
}

使用forward:+新请求路径即可转移

结果:
页面显示与 数组参数 例子相同
查看控制台

可知两个方法都经过了

下一帖子,将会讲述小程序与本框架后台之间的json数据交互,good good study,day day up

分享到:
1条评论
Ctrl+Enter
作者

toBeMN

toBeMN

APP:3 帖子:24 回复:59 积分:3193

已加入社区[2940]天

梦想成为全栈的男人

作者详情》
Top