SpringMVC课程学习笔记-day05

1.Controller接收客户端传的参数

1)参数是基本数据类型/包装类型/String

@RequestMapping("test")

public String test(int age){...}

public String test(long id){...}

public String test(boolean flag){...}

public String test(Long id){...}

public String test(String name){...}

 

注意参数名字要和客户端传的参数名一致,否则需要使用@RequestParam来指定参数名

 

2)参数是数组类型

@RequestMapping("test")

public String test(int[] age){...}

public String test(long[] id){...}

public String test(boolean[] flag){...}

public String test(Long[] id){...}

public String test(String[] name){...}

 

注意客户端传值类似于这样:

name=tom&name=lisi

 

 

注意客户端传值还可以使用json的方式

@RequestMapping("/index")

@ResponseBody

public String index(@RequestBody String[] arr){...}

 

$("#btn").on("click",function(){

var arr = [];

arr.push("hello");

arr.push("world");

$.ajax({

type:"post",

url:"test/index",

contentType:"application/json",  //发送数据的数据类型.

data:JSON.stringify(arr),        //发送的数据

dataType:"json",                 //接收的返回数据的类型

success:function(data){

console.log("data = "+data);

}

});

});

 

 

 

 

 

3)参数是类类型(例如实体类Uesr、Student等)

@RequestMapping("test")

public String test(User user){...}

 

注意客户端传值类似于这样:

username=tom&password=123&dob=2017-10-21

 

注意:

1.username/password/dob必须是User中存在的property

2.日期类型的转换

 

4)参数是类类型的数组

例如:

@RequestMapping("/test")

public String test(@RequestBody User[] users){...}

 

$("#btn").on("click",function(){

var arr = [];

var json1 = {username:"tom",password:"123",dob:"1999-10-27"};

var json2 = {username:"zss",password:"456",dob:"2000-10-27"};

arr.push(json1);

arr.push(json2);

$.ajax({

type:"post",

url:"/test",

contentType:"application/json",

data:JSON.stringify(arr),

dataType:"json",

success:function(data){

console.log("data = "+data);

}

});

});

 

 

 

 

5)List/Set集合

例如1:如果是set集合,直接把List换成Set即可,其他不用改

@RequestMapping("/index")

@ResponseBody

public String index(@RequestBody List<String> list){...}

 

$("#btn").on("click",function(){

var arr = [];

arr.push("hello");

arr.push("world");

$.ajax({

type:"post",

url:"test/index",

contentType:"application/json",

data:JSON.stringify(arr),

dataType:"json",

success:function(data){

console.log("data = "+data);

}

});

});

 

例如2:如果是set集合,直接把List换成Set即可,其他不用改

@RequestMapping("/index")

@ResponseBody

public String index(@RequestBody List<User> list){....}

 

$("#btn").on("click",function(){

var arr = [];

var json1 = {username:"tom",password:"123",dob:"1999-10-27"};

var json2 = {username:"zss",password:"456",dob:"2000-10-27"};

arr.push(json1);

arr.push(json2);

$.ajax({

type:"post",

url:"test/index",

contentType:"application/json",

data:JSON.stringify(arr),

dataType:"json",

success:function(data){

console.log("data = "+data);

}

});

});

 

6)Map集合

例如:

@RequestMapping("/index")

@ResponseBody

public String index(@RequestBody Map<String,User> map){...}

 

$("#btn").on("click",function(){

var map = {};

var json1 = {username:"tom",password:"123",dob:"1999-10-27"};

var json2 = {username:"zss",password:"456",dob:"2000-10-27"};

map[json1.username] = json1;

map[json2.username] = json2;

$.ajax({

type:"post",

url:"test/index",

contentType:"application/json",

data:JSON.stringify(map),

dataType:"json",

success:function(data){

console.log("data = "+data);

}

});

});

 

 

7)以上任何类型遇到特殊情况下,都可以使用自定义类型转换器:

spring提供的转换器接口:

public interface Converter<S, T> {

T convert(S source);

}

可以让我们把任意类型S转换为T类型,但是转换的代码需要我们来提供给spring

 

编写完成后需要在spring中注册,例如:

 

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

 

<bean name="formatService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">

<property name="converters">

<set>

<!-- 自己编写的类型转换器,可以有多个 -->

<bean class="com.briup.web.converter.StringToDateConverter"></bean>

</set>

</property>

</bean>

 

 

2.SpringMVC中的跳转

1.因为在Controller中的功能处理方法上可以获得到request和response,所以可以像之前servlet中一样,进行服务器内部跳转和客户端重定向

例如:

@Controller

@RequestMapping("/dispatcher")

public class DispatcherController {

@RequestMapping("/b")

public String testB(){

System.out.println("testB");

return "index";

}        

 

@RequestMapping("/c")

public String testC(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{

System.out.println("testC");

//服务器内部跳转到一个页面

//request.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(request, response);

 

//服务器内部跳转到一个功能处理方法

//request.getRequestDispatcher("/dispatcher/b").forward(request, response);

 

//客户端重定向到另一个功能处理方法

response.sendRedirect(request.getContextPath()+"/dispatcher/b");

 

return null;

}        

 

}

 

 

2.Controller中可以使用字符串表示服务器内部跳转和客户端重定向

例如:

@Controller

@RequestMapping("/dispatcher")

public class DispatcherController {

 

@RequestMapping("/a")

public String testA(){

System.out.println("testA");

//服务器内部跳转到另一个功能处理方法

//return "forward:/dispatcher/b";

 

//客户端重定向到另一个功能处理方法

//return "redirect:/dispatcher/b";

 

//服务器内部跳转到一个页面

return "index";

}

 

@RequestMapping("/b")

public String testB(){

System.out.println("testB");

return "index";

}

}

 

 

3.Controller中使用ModelAndView进行跳转和重定向

@Controller

@RequestMapping("/dispatcher")

public class DispatcherController {

@RequestMapping("/b")

public String testB(){

System.out.println("testB");

return "index";

}        

 

@RequestMapping("/d")

public ModelAndView testD() throws ServletException, IOException{

System.out.println("testD");

 

//服务器内部跳转到另一个功能处理方法

//ModelAndView mv = new ModelAndView("forward:/dispatcher/b");

 

//客户端重定向到另一个功能处理方法

//ModelAndView mv = new ModelAndView("redirect:/dispatcher/b");

 

//服务器内部跳转到一个页面

ModelAndView mv = new ModelAndView("index");

 

return mv;

}        

 

}

 

 

 

 

3.SpringMVC中的数据验证

通常在项目中使用较多的是前端校验,比如页面中js校验。对于安全要求较高的建议在服务端同时校验

 

SpringMVC使用hibernate的实现的校验框架validation,所以需要导入相关依赖的jar包

classmate-1.1.0.jar

hibernate-validator-5.1.3.Final.jar

jboss-logging-3.1.4.GA.jar

validation-api-1.1.0.Final.jar

 

数据校验之后,如果有错误信息,那么需要使用spring提供的标签库中的标签在页面中显示校验信息

<%@taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>

 

例如:

valid.jsp页面主要代码:

<sf:form method="post" modelAttribute="user">

<sf:label path="name">用户名:</sf:label>

<sf:input path="name"/>

<sf:errors path="name" cssStyle="color:red"></sf:errors><br>

 

<sf:label path="age"> 年   龄:</sf:label>

<sf:input path="age"/>

<sf:errors path="age" cssStyle="color:red"></sf:errors><br>

 

<sf:label path="dob"> 生   日:</sf:label> 

<sf:input path="dob"/>

<sf:errors path="dob" cssStyle="color:red"></sf:errors><br>

 

<input type="submit" value="提交"/>

</sf:form>

 

注意:

1.需要访问一个Controller再跳转到这个页面,同时需要向模型中添加一个名字叫user的对象(这就是之前说的命令/表单对象),否则跳转到这个页面的时候会报错

2.表单中没有这种action属性值,那么默认把数据提交给当前页面,但是提交方式是post

3.input标签中的path属性的值对应的是表单对象中的属性

4.Controller中映射的url为:/Valid/add , 如果是get方式访问这个url那么就把valid.jsp显示给用户,如果是post方式访问这个url,就表示要提交表单的数据。

5.在Controller中,在需要验证的参数前面加入@Valid注解

6.方法参数列表中,加入BindingResult对象,用来接收验证的错误信息,并根据这个进行不同情况的跳转

7.在被验证的表单对象所属类中,给需要验证的属性上加入指定注解

 

 

 

Controller中代码:

 

@Controller

@RequestMapping("/valid")

public class ValidController {

 

@RequestMapping(value="/add", method = {RequestMethod.GET})

public String showAddPage(Model model){

if(!model.containsAttribute("teacher")){

model.addAttribute("teacher", new Teacher());

}

return "valid";

}

 

@RequestMapping(value="/add",method = {RequestMethod.POST})

public String addTeacher(@Valid Teacher teacher,BindingResult bindingResult){

//如果验证数据中有错误信息,将保存在bindingResult对象中

if(bindingResult.hasErrors()){

List<ObjectError> errorList = bindingResult.getAllErrors();            

for(ObjectError error : errorList){                

System.out.println(error.getDefaultMessage());            

}

//验证不通过在跳到valid页面,因为页面上有显示错误的标签

return "valid";

}

 

//没有错误则跳到test页面

return "test";

}

 

}

 

User类中代码:

public class User {

 

private long id;

@Size(min=5,max=8)

private String name;

private Integer age;

private Date dob;

 

get/set

}

 

 

常用的数据校验的注解

 

@Null                值只能为null

@NotNull        值不能为null

@NotEmpty        值不为null且不为空

@NotBlank        值不为null且不为空(先去除首尾空格)

@Pattern        正则表达式验证

@Size                限制长度在x和y之间

 

@Max                最大值

@Min                最小值

 

@Future                必须是一个将来的日期(和现在比)

@Past                必须是一个过去的日期(和现在比)

 

@Email                校验email格式

 

注意:日期属性上要加@DateTimeFormat(pattern="yyyy-MM-dd"),否则页面传的字符串是不能自动转为为日期的

 

 

 

4.SpringMVC中的异常处理

在SpringMVC中可以把异常统一进行处理,只需加入以下配置:

 

<!-- Spring提供的默认的异常解析器,也可以自定义 -->

<!-- 可以在jsp目录下新建一个error目录,然后放入显示错误页面 -->

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">

    <!-- 定义默认的异常处理页面,当该异常类型的注册时使用 --> 

<!-- value="error" 表示跳转的逻辑视图名字 -->

    <property name="defaultErrorView" value="error/error"></property> 

 

    <!-- 定义异常处理页面用来获取异常信息的变量名,默认名为exception --> 

    <property name="exceptionAttribute" value="ex"></property> 

 

    <!-- 定义需要特殊处理的异常,用简单类名或全限定名作为key,异常页名的逻辑视图名作为value --> 

    <property name="exceptionMappings"> 

        <props> 

            <prop key="IOException">error/error_io</prop> 

            <prop key="java.sql.SQLException">error/error_sql</prop> 

        </props> 

    </property>

</bean>

 

 

Controller中代码:

@RequestMapping("/test")

public String test()throws Exception{

 

//int a = 1/0;

//System.out.println(a);

 

int a = 1;

if(a==1){

throw new IOException("不好了,出错了!");

}

 

return "test";

}

 

页面中:

1.如果使用jsp的脚本显示信息

<!-- 因为spring中修改了异常的默认名字,所以这里是ex -->

<% Exception ex = (Exception)request.getAttribute("ex"); %>

<H2>Exception: <%= ex.getMessage()%></H2>

<P/>

<% ex.printStackTrace(new java.io.PrintWriter(out)); %>

 

2.如果是EL显示错误信息

<div>${ex }</div>

<div>${ex.message }</div>

 

 

 

异常处理也可以使用注解的形式,注意这个@ExceptionHandler是要加在需要异常处理的Controller中(推荐使用上面的那种配置方式)

 

@Controller 

public class XxxxController { 

 

@RequestMapping("/test")

public String test()throws Exception{

//                int a = 1/0;

//                System.out.println(a);

 

int a = 1;

if(a==1){

throw new IOException("你说呢?");

}

return "test";

}

 

@ExceptionHandler(value={IOException.class,SQLException.class}) 

public String exp(Exception ex,HttpServletRequest request) { 

request.setAttribute("ex", ex); 

return "error_io"; 

}

 

 

 

5.SpringMVC中上传

使用上传功能需要引入俩个jar包:

commons-fileupload-1.2.2.jar

commons-io-2.0.1.jar

 

利用spring中提供的MultipartFile接口实现上传功能

MultipartFile中几个重要的方法:

getName : 获取表单中文件组件的名字(上传框的名字)

getOriginalFilename : 获取上传文件的原名(上传文件名字)

transferTo(File newFile);把上传的文件转存到指定文件中(把上传的文件写入到一个指定的位置)

 

 

spring配置文件中加入以下配置:

<!-- SpringMVC上传文件时,需要配置MultipartResolver处理器 -->

<!-- 注意:bean的名字不要改,一定要叫multipartResolver -->

<bean name="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

    <property name="defaultEncoding" value="UTF-8"/>

    <!-- 指定所上传文件的总大小不能超过指定字节大小 -->

    <property name="maxUploadSize" value="20000000"/>

</bean>

 

 

jsp页面代码:

<form action="upload/test" method="post" enctype="multipart/form-data">

<input type="file" name="file"><br>

<input type="file" name="file"><br>

<input type="submit" value="上传">

</form>

 

 

Controller中的代码:

@Controller

@RequestMapping("/upload")

public class UploadController {

 

@RequestMapping("/show")

public String showUploadPage(){

return "upload";

}

 

@RequestMapping("/test")

public String upload(@RequestParam("file") MultipartFile[] files, HttpServletRequest request) {

if (files != null && files.length > 0) {

for (MultipartFile file : files) {

// 保存文件

saveFile(request, file);

}

}

// 重定向

return "redirect:/upload/show";

}

 

private void saveFile(HttpServletRequest request, MultipartFile file) {

// 判断文件是否为空

if (!file.isEmpty()) {

try {

//保存的文件路径

//需要的话可以给文件名上加时间戳

String filePath = request.getServletContext().getRealPath("/") + "upload/"

+ file.getOriginalFilename();

File newFile = new File(filePath);

//文件所在目录不存在就创建

if (!newFile.getParentFile().exists()){

newFile.getParentFile().mkdirs();

}

 

// 转存文件

file.transferTo(newFile);

} catch (Exception e) {

e.printStackTrace();

}

}

 

}

 

}

 

 

注意:在上传文件的同时,还可以接收其他正常的单个的值,例如username、age等,同时也可以把这些单个的值自动封装成User对象

 

6.SpringMVC中下载

SpringMVC的下只需要自己设置response信息中的各个部分就可以,可以使用之前学习过的ResponseEntity<T>来完成

 

@RequestMapping("/show")

public String showDownLoadPage(){

return "download";

}

 

@RequestMapping("/test")

public ResponseEntity<byte[]> test(String fileName,HttpServletRequest request) throws IOException {

//获得下载文件所在路径 可以指向系统中的任意一个有权访问的路径

String downLoadPath = request.getServletContext().getRealPath("/download");

 

//创建要下载的文件对象

File file = new File(downLoadPath,fileName);

 

//处理一下要下载的文件名字,解决中文乱码

String downFileName = new String(fileName.getBytes("UTF-8"), "iso-8859-1");

 

//创建响应头信息的对象

HttpHeaders headers = new HttpHeaders();

//设置下载的响应头信息,通过浏览器响应正文的内容是用户要下载的,不用浏览器解析

headers.setContentDispositionFormData("attachment", downFileName);

headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

 

//通过响应内容、响应头信息、响应状态来构建一个响应对象并返回

return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);

}

 

页面代码:

<a href="download/test?fileName=测试.txt">点击下载</a>

 

7.ajax上传文件

在上面普通上传的例子中进行修改即可

1)spring中配置上传的解析器

<bean name="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

    <property name="defaultEncoding" value="UTF-8"/>

    <property name="maxUploadSize" value="20000000"/>

</bean>

 

2)页面中引入jquery以及ajax上传的插件

ajax上传的插件有很多,这里使用的一个插件为:ajaxfileupload.js

 

注意引入的先后顺序不能乱

<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>

<script type="text/javascript" src="js/ajaxfileupload.js"></script>

 

 

3)jsp页面代码及其对应js代码

<script type="text/javascript">

$(function(){

$("input:button").on("click",function(){

if(!$("input:file").val()){

alert("请选择上传文件");

return;

}

ajaxFileUpload();

});

});

 

function ajaxFileUpload(){

$.ajaxFileUpload(

{

url: 'ajax_upload/test',

secureuri: false,

fileElementId: 'myfile',

dataType: 'text',

success: function (data){

$("input:file").val("");

$("#sp").html(data).css("color","green");

},

error: function (data){

$("#sp").html(data).css("color","red");

}

}

);

}

</script>

 

 

<body>

<!-- ajax上传不需要表单 -->

<!-- 这个上传框的id值一定要写,需要和js中的设置对应 -->

<input id="myfile" type="file" name="myfile"><br>

<input type="button" value="上传"><br>

<span id="sp"></span>

</body>

 

 

 

4)Controller中功能处理函数的代码

@Controller

@RequestMapping("/ajax_upload")

public class AjaxUploadController {

 

@RequestMapping("/show")

public String show(){

return "ajax_upload";

}

 

@RequestMapping(value="/test",method=RequestMethod.POST)

@ResponseBody

public String upload(@RequestParam(value="myfile",required=false) MultipartFile[] files, HttpServletRequest request) throws Exception {

if (files != null && files.length > 0) {

for (MultipartFile file : files) {

saveFile(request, file);

}

}

//这里要解决中文乱码问题

return new String("上传成功".getBytes("utf-8"),"iso-8859-1");

}

 

private void saveFile(HttpServletRequest request, MultipartFile file) {

if (!file.isEmpty()) {

try {

String filePath = request.getServletContext().getRealPath("/") + "upload/"+ file.getOriginalFilename();

 

File newFile = new File(filePath);

if (!newFile.getParentFile().exists()){

newFile.getParentFile().mkdirs();

}

 

file.transferTo(newFile);

} catch (Exception e) {

e.printStackTrace();

}

}

 

}

 

}

 

 

8.SSM框架的搭建

注意:

1.SpringMVC和Spring

不需要什么特殊的配置就可以结合

 

2.MyBatis和Spring

1)需要引入额外的jar包:mybatis-spring-1.3.2.jar

2)配置数据源

3)把MyBatis中的SqlSessionFactory配置给Spring管理

4)在spring中配置需要扫描的MyBatis映射接口所在包的位置

 

3.Spring中配置SqlSessionFactory

1)可以在MyBatis的mybatis-config.xml中把MyBatis的信息配好,然后再让spring读取这个mybatis-config.xml文件

2)可以删除mybatis-config.xml文件,然后MyBatis的信息都配置到Spring中

 

4.spring配置文件中的重要信息

可以写在外部的资源文件中,然后再使用spring的标签读出来使用

例如:

<context:property-placeholder location="classpath:db.properties"/>

取值使用的形式:${key}

${driverClassName}

 

5.事务配置

1)事务的开启和提交需要配置在service层方法的俩端

2)配置事务需要三步

配置事务管理器

使用jdbc的事务管理器

配置事务拦截器

使用tx前缀的标签

spring的aop配置(把事务管理织入到指定的切入点)

使用aop前缀的标签

 

6.日志配置

1)使用之前MyBatis的日志文件即可

2)在log4j.properties文件中可以屏蔽掉spring日志(输出太多了...)

#ALL DEBUG INFO WARM ERROR FATAL OFF

log4j.logger.org.springframework = ERROR

 

7.web.xml文件配置

1)配置spring读取的配置文件

2)配置编码过滤

3)配置前端控制器

 

8.SpringMVC的容器和Spring核心容器的关系

1)使用xml或者注解进行配置,springMVC或者spring读取配置信息之后,会把配置的对象(就是spring中的bean)放到容器中进行管理

2)服务器启动的时候,SpirngMVC中的前端控制器会读取配置文件,把相关配置的对象放到自己产生的容器中进行管理(需要在web.xml配置)

3)服务器启动的时候spring也会读取配置文件,把相关配置的对象放到自己产生的容器中进行管理(需要在web.xml配置)

4)SpirngMVC创建容器中所管理的Bean一般是只对SpringMVC有效,如Controller、HandlerMapping、HandlerAdapter等等(因为它一般只读取SpringMVC的配置文件)

5)Spirng创建容器中所管理的Bean一般是对于整个应用程序共享的,一般如DAO层、Service层Bean。(因为它一般只读取service层和dao层的配置文件)

6)SpirngMVC创建的容器 【继承了】 Spirng创建的容器

7)子容器可以从父容器中拿出bean来使用,但是父容器不能从子容器中拿bean来使用。所以在Controller中可以注入service层的实现类对象,Controller在SpringMVC创建的容器中,service是在Spring创建的容器中。

 

 

9.具体实例参照SSM项目

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值