java之STS使用和相关目录解说、springBoot微服务项目、前后端发送和接收参数的方式、文件图片视频上传
springboot官网:https://spring.iospringboot的使用:eclipse+插件sts、直接官网下载STS编辑器、INteliJ Ide;***使用STS编辑器开发:配置jdk(环境变量);配置maven(环境变量),在sts中preference-》搜索maven-〉installation-》add添加新的maven,然后打勾的切换一下代替...
终端启动tomcat:https://mp.csdn.net/editor/html/86714807
springboot官网:https://spring.io
springboot的使用:eclipse+插件sts、直接官网下载STS编辑器、INteliJ Ide;
***使用STS编辑器开发的基础配置:配置jdk(环境变量);配置maven(环境变量),在sts中preference-》搜索maven-〉installation-》add添加新的maven,然后打勾的切换一下代替内置的maven,userSeting中设置maven的setting.xml的路径;
STS中创建springboot项目:springboot中自带了Maven
创建:file-》new-》spring starter project
运行:选中项目-》右键-》Run As-》Spring Boot App
STS中创建Maven项目和打包项目:
创建:file-》new-》 project-》Maven文件夹下面的Maven project-》一路next,添加Artifact ID,然后finish。
打包项目:选中项目右键-》Run as-》Maven install;打包成功后再target中会出现一个该文件夹(包含WEB-INF和META-INF)和.war文件。
sts配置tomcat:一般为sts或者eclispe、intell idea配置tomcat都是为了本地测试方便。
1.sts-》preferences-->server-->Runtime Environments点击add-》选中tomcat版本-》next-》在browse...中找到本地tomcat的目录后点击next,或者是finish即可。
2.选中项目右击-》properties-》java build path-》 Libraries-》点击 Add Library-->server runtime-->选择tomcat-->finish。
修改sts中的maven:
1.sts-》preferences-->maven-》installations-》add添加maven(默认选中的第一个是自带的,取消掉前面的勾)
2.sts-》preferences-->maven-》User settings,点击User Settings选项,配置用户settings文件。在maven文件下的conf中的setting.xml。还要配置Local Repository。
jar包:执行SpringBootApplication的run方法,启动IOC容器,然后创建嵌入式Servlet容器
war包: 先是启动Servlet服务器,服务器启动Springboot应用(springBootServletInitizer),然后启动IOC容器
Java Web 应用中有两个目录及其下面的东西通过 URL 是无法访问的。一个是 WEB-INF 目录,另一个是 META-INF 目录。
WEB-INF是Java的WEB应用的安全目录。所谓安全就是客户端无法访问,只有服务端可以访问的目录。如果想在页面中直接访问其中的文件,必须通过 web.xml 文件对要访问的文件进行相应映射才能访问。
/WEB-INF/web.xml
Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则。
/WEB-INF/classes/
包含了站点所有用的 class 文件,包括 servlet class 和非servlet class,他们不能包含在 .jar文件中。/WEB-INF/lib/
存放web应用需要的各种JAR文件,放置仅在这个应用中要求使用的jar文件,如数据库驱动jar文件。/WEB-INF/src/
源码目录,按照包名结构放置各个java文件。/WEB-INF/database.properties
数据库配置文件/WEB-INF/tags/
存放了自定义标签文件,该目录并不一定为 tags,可以根据自己的喜好和习惯为自己的标签文件库命名,当使用自定义的标签文件库名称时,在使用标签文件时就必须声明正确的标签文件库路径。例如:当自定义标签文件库名称为 simpleTags 时,在使用 simpleTags 目录下的标签文件时,就必须在 jsp 文件头声明为:<%@ taglibprefix="tags" tagdir="/WEB-INF /simpleTags" % >。
META-INF
相当于一个信息包,目录中的文件和目录获得Java 2平台的认可与解释,用来配置应用程序、扩展程序、类加载器和服务、 manifest.mf文件,在用jar打包时自动生成。
******STS创建普通maven项目步骤******
file-》new-》 project-》Maven文件夹下面的Maven project-》一路next,添加Artifact ID,然后finish。
src文件夹报错解决:
maven项目必须有以下4个文件:
/src/main/java 项目的源代码
/src/main/resources 项目需要用到的资源
/src/test/java 项目的测试源代码
/src/test/resources 测试需要用到的资源,
按照如下步骤添加缺少的文件 :
java build path->source->add Folder->
添加文件成功后,需要修改文件output folder 。test的两个文件夹要对应到target/test-classes下。
到此错误就消失了。
启动服务器:widow-》show view-》other-》Servicer-》servicers。
选中项目右键Run as-》run on server;Deploy path路径下面会多出项目名文件夹:
打包:maven inatall后,在target中就会多出一个lambo001文件夹和lambo001.war文件。
wtpwebapps是eclipse和sts默认的部署路径;webapps是tomcat默认的部署路径。war包放到webapp中,重启tomcat会自动解压成同名的文件夹,就可以访问了。
******springBoot项目介绍***************
**src/main/resources:
static静态资源(js css 图片 音频 视频)
templates:模板(模板引擎freemarker,thymeleaf),默认不支持jsp
application.properties:配置文件(相当于application.yml);
可以在application.properties中配置端口;
pom.xml是maven的配置配置文件;
springBoot内置了tomcat,不需要打包成war包;
springBoot将各应用/三方框架设置成一个场景start,用到的时候只需要引入场景即可,springboot自动吧所有依赖全部注入。
在application.properties中加上debug=true执行程序就会吧自动开启的自动装配和没开启的自动装配全部打印出来。
自动配置是基于约定的,但在配置文件中可以修改。
springBoot默认只认识两个配置文件:application.properties和application.yml;这两个功能一样;
yml 规定冒号后面的值必须有空格;yml默认可以不写引号,双引号中的转义符会转义,单引号中不会转义;
在yml文件中绑定属性需要在类文件中添加注解@Component @ConfigurationProper(prefix="student"),student是yml文件中的
@Value("name")可以注入属性值,但是需要在类中每一个属性前注入;@ConfigurationProper(prefix="student")的优先级高于@value("name"),但是两者没有的可以互补。
@propertysource:默认会加载application.properties和application.yml文件,如果不用这两个文件,就要用PropertySource(value={"classpath:conf.properties"})指定加载。但这种注解只能加载properties文件,不能加载yml。
@ImportResource:spring的配置文件 默认会被spring boot自动配置好;如果自己要写配置文件,是不会被识别的。这时候就要使用这个注解指定配置文件的路径,在入口程序的类中写@ImportResource(locations={"classpath:spring.xml"})。但是不推荐自己写配置文件,现在流行的是注解配置,创建一个配置类,需要加上@Configuration ,@Bean就相当于配置文件中的<bean>,方法名相当于id。
占位符表达式::${random.int}随机数
多环境切换:1.如果要切换,在properties文件中设置spring.profiles.active=test;springboot默认会读取主配置文件application.properties;application-dev.properties;application-test.properties;
2.可以在yml中配置;
3.动态切换环境:方法一:通过命令行方式:Run Configuration-》argument->program argument下写命令:--spring.profiles.active=dev;或者同构虚拟机VM设置-Dspring.profiles.active=dev;
配置文件的位置问题:application.properties和application.yml可以存放在以下几个文件夹中:file:项目根目录/config、file:项目根目录、classpath:项目根目录/config、classpath:项目根目录。如果有冲突,则优先级从前往后,如果不冲突则互补。
项目外的配置文件:在application.properties中配置项目名,server.serverlet.context-parth=/boot;也可以在项目之外配置:方法是先在外部创建一个application.properties,然后Run Configuration-》argument->program argument下写命令:--spring.config.location=文件存放的路径;通过命令行调用外部配置文件:java -jar jar包地址 --spring.config.location=applications.properties的地址。项目运行参数:Run Configuration-》argument->program argument下写命令:--server.port=8888 ;或者通过命令:java -jar jar包地址 --server.port=8888;
优先级:命令行参数》yml
springBoot日志处理:日志框架UCL、JUL、slf4j、logback、log4j;springboot默认支持的有slf4j、logback;
springboot默认帮我们配置好了,直接使用就可以了;
日志的级别:TRACE<DEBUG<INFO<ERROR<FATAL<OFF
springboot默认的日志级别是info,只打印info级别只之后的信息,也可以在配置文件中配置日志级别logging.level.主配置类多所在的包=日志级别;
吧日志保存在文件中:要配置logging.file=保存日志文件的位置,(相对于文件的根路径),也可以设置绝对路径.文件夹用logging.path=文件夹位置,并且默认的文件名叫spring.log;
修改日志的格式:1.日志显示在控制台,logging.pattern.console=%d{yyyy-MM-dd } [%thread] %-5level %logger{50} -%msg %n;2.日志显示在文件中,logging.pattern.file=%d{yyyy-MM-dd } [%thread] %-5level %logger{50} -%msg %n。
springboot处理Web静态资源:
@RequestMapping("/请求的路径")
请求的时候不需要写项目名,如果要加项目名需要在配置文件中配置一下。
springboot是一个jar包,静态资源就不是存放在webapps中,
WebMvcAutoConfiguration类指定静态资源的存放位置,addResourceHandlers()指定springboot将静态资源引入静态资源,从webjars目录开始,如localhost:8080.webjars/jquery。springboot将这写静态资源直接以jar文件的方式引入。spring boot
将一些目录结构设置成静态资源存放目录,静态资源直接放入这些目录即可。classpath:/META-INF/resources、classpath:/resources、classpath:/static、classpath:/static。访问的时候不需要写前缀,直接写静态资源的文件名,就是不需要加resources、static、static。
也可以自己配置静态资源路径:spring.resources.static-locations=自定义的位置classpath:/res/,classpath:/myimge/,那么静态资源就可以放到自定义的位置了;自定义生效后,以前的约定就不能用了。
添加欢迎页:welcomPageHandleMapping()---->getIndexHtml()-->location ;任意一个静态资源目录中的index.html就一个默认的欢迎页。网页标签的logo是固定名字favicon.ico;吧这个ico文件放到任何一个静态资源目录中。
webjars.org网站有引入静态资源的方式。
模板引擎thymeleaf:动态资源不支持jsp;推荐使用模板引擎;网页=模板+数据;在maven中添加场景;
thymeleaf的代码要写在classpath:/templates/目录中,只要文件的后置是.html的就可以了。
springBoot整合外置tomcat:如果要整合jsp,只能用war包,所以要需要外置的tomcat;在pom.xml中重新配置tomcat,<scope>provide</scope>;重新建立基本的web项目目录结构,webapps/WEB-INF,webapps/inde.jsp;跟以前的部署tomcat一样。
下载地址:
https://docshome.gitbooks.io/springboot/content/
安装springboot:https://www.cnblogs.com/sea-stream/p/11601100.html
springBoot=spring(项目管理)+springmvc(控制器)进一步封装。
约定:src/main/java下面必须要有一个全局的入口类,要放在所有子包之上,Application全局入口类,只能出现一次。
在src/main/resource文件夹下要有application.yml文件,这个是springboot的配置文件。
springboot项目默认没有应用名,如果需要在yml文件中可以指定应用名。
springboot默认内嵌有tomcat,不需要外部设置tomcat,默认端口8080,可能会冲突,在yml文件中修改。
*****微服务项目******
***MyBatis-Plus:
lombok插件的安装:https://blog.csdn.net/lsqingfeng/article/details/89842258
lombok可以自动生成set、get、toString方法;使用前要安装lombok插件,还要在pom.xml中引入。在类中加注解:@Data;
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
插入时自动更新字段:创建一个类实现MetaObjectHandler这个接口。
乐观锁:加一个字段version;
逻辑删除(假删),物理删除(真删除);加一个字段deleted;
条件构造器:在数据库操作的时候,可以构造条件。
lamda表达式可以提升sql语句的优先级。
代码生成器;
@RestController:相当于@Responsbody+@Controller;返回值都是jason;
****数据库设计
数据库优化的主要方式:sql优化,数据库设计。
数据库优化:微服务中分库设计;分表(横向分表:(id策略、hash id)主要解决单表数量过大的问题,纵向分表:()解决单表列多的问题,单列内容过多的问题,提升查询效率);设计冗余列:避免过多的表关联;
58到家军规,沈剑;阿里巴巴开发手册;
dependencyManageement版本管理;dependency依赖;
跨域:浏览器从一个域名的网页去请求另一个域名的资源,域名、端口、协议任何一个不一样都是跨域。
跨域的解决方案:在Controller类上直接加上@CrossOrigin;
swagger配置文件:生成api;swaager访问地址:http://localhost:8888/demo/swagger-ui.html demo是自己配置的路径,默认的是http://localhost:8888/swagger-ui.html,端口是自己的。
有时候不让访问会弹出一个框提示一大段文字Unable to infer base url.。。。。。,在启动类中加入@EnableSwagger2注解;
统一返回数据格式;sucess,code,message,data。
***配置日志https://www.cnblogs.com/bigben0123/p/7895696.html
默认级别是INFO;application.properties中配置日志级别:logging.level.root=WARN;
在resources包中创建logback-spring.xml就会自动被读取到,这样就不需要在application.properties中配置日志级别了;
logback系统日志的配置:安装彩色日志插件:grep-console;
默认的命名规则,并且放在 src/main/resources下;
如果你即想完全掌控日志配置,但又不想用 logback.xml 作为 Logback 配置的名字, application.yml 可以通过 logging.config 属性指定自定义的名字:
logging.config=classpath:logging-config.xml
虽然一般并不需要改变配置文件的名字,但是如果你想针对不同运行时 Profile 使用不同的日志配置,这个功能会很有用。
一般不需要这个属性,而是直接在 logback-spring.xml 中使用 springProfile 配置,不需要 logging.config 指定不同环境使用不同配置文件。 springProfile 配置在下面介绍。
根节点包含的属性:
scan:当此属性设置为 true 时,配置文件如果发生改变,将会被重新加载,默认值为 true 。
scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当 scan 为 true 时,此属性生效。默认的时间间隔为1分钟。
debug:当此属性设置为 true 时,将打印出 logback 内部日志信息,实时查看 logback 运行状态。默认值为 false 。
根节点 <configuration> 有5个子节点:
子节点一 <root>
root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性。
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能设置为INHERITED或者同义词NULL。默认是DEBUG。
可以包含零个或多个元素,标识这个appender将会添加到这个loger。
子节点二: <contextName> 设置上下文名称
每个logger都关联到logger上下文,默认上下文名称为“default”。但可以使用设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改,可以通过 %contextName 来打印日志上下文名称,一般来说我们不用这个属性,可有可无。
<contextName>logback</contextName>
子节点三: <property> 设置变量
用来定义变量值的标签, 有两个属性,name和value;其中name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。
子节点四: <appender>
appender用来格式化日志输出节点,有俩个属性name和class,class用来指定哪种输出策略,常用就是控制台输出策略和文件输出策略。
可以看到 layout 和 encoder ,都可以将事件转换为格式化后的日志记录,但是控制台输出使用 layout ,文件输出使用 encoder 。
***springboot中的注解
@SpringBootAplication 标识入口类,将其所在包和其子包全部装入spring容器中。只能出现一次。这个注解是许多个注解组合而成的。等价于@SpringBootConfiguration(标志注解,标志这是入口类)、@EnableAutoConfigration(核心注解,自动配置spring以及引入的第三方技术)、@ComponentScan(组件扫描注解,默认扫描秒入口类所在的包,以及他的子包)
元注解:就是修饰注解的注解,@Doucment、@Inherited、@Retention(指定注解的生效时机)、@Target(指定注解的修饰范)围。
application中main函数的作用:启动内嵌tomcat服务器,
springapplication.run(application.class,args)参数一:入口类的对象,目的是让@EnableAutoConfigration自动配置print时将@ComponentScan扫描到注解创建对象一并放入工厂。参数二是main函数的参数,这个参数通过指定外部虚拟机参数形式覆盖应用内部默认参数。
@RestController (相当于@controller和@responseBody的结合)用在类上,所有的控制器上,作用是将类中所有控制器方法的返回值转换为json并响应到前端。
@controller 表示控制器
@responseBody 将返回值转换成json
***配置文件拆分:
将公共配置防止主配置文件中,将不同配置文件中放入不同环境的配置文件中;application.yml公共(在主配置文件中要激活响应的配置文件,spring:profiles:active:dev或者prod) application-dev.yml 开发 application-prod.yml 生产
SpringBoot banner:创建一个banner.txt
***spirng boot工厂特性之创建对象
单个自定义对象:@Component通用组件对象注解 @Service业务层注解 @Controller控制器注解 @Repository创建DAO组件
一次性创建多个组件对象把汗复杂对象:@Configuration 配置注解 修饰范围:用在类上,作用相当于以前的spring.xml配置文件,管理对象的创建。
@Bean 相当于spring.xml中的Bean标签,用来创建这个对象在工厂的一个实例。
@PathVariable是spring3.0的一个新功能:接收请求路径中占位符的值;通过 @PathVariable 可以将URL中占位符参数{xxx}绑定到处理器类的方法形参中@PathVariable(“xxx“)
****springboot获取前端参数的几种常用注解
获取参数的几种常用注解:https://blog.csdn.net/qq_20957669/article/details/89227840
@PathVariable:接收请求路径中占位符的值.一般我们使用url/{param}这种形式,也就是一般我们使用的GET,DELETE,PUT方法会使用到的,我们可以获取URL后所跟的参数。
@RequestParam:使用该注解来获取多个参数,请求的url参数中的name必须要和@RequestParam("name")一致,@RequestParam接收的是key-value 里面的参数.
@RequestBody:接收json对象字符串,而不是json对象,使用前需要用JSON.stringify(data)的方式就能将对象变成字符串。RequestBody 接收的是请求体里面的数据。
@CookieValue来获取Cookie值。
@RequestHeader("mytoken")获取请求头中的mytoken信息。
******前后端发送和接收参数的方式
* 当我们的content-type是application/x-www-form-urlencoded的时候,
* 前台传递的参数是可以传到后台的@RequestParam和request.getParameter都可以,事实上,这两种都是一样的,
* 但是当我再前台设置的content-type是application/json的时候,后台就无法接收到参数,两种都不行。
* 如果是二进制数据传输,像文件上传等,需要设置content-Type multipart/form-data.
***方式一 POST map接接收
// 发起登录请求
this.$http.post('/login',{username:"lambo",password:"12345678"})
后端:
@RequestMapping("/login")
public R login(@RequestBody Map<String, String> person) { }
***方式五 POST 后台用字符串接收,然后用JSONObject把字符串转换成JSON对象;
请求:
const rest=await this.$http.post('userlist',{params:this.quereyInfo})
后台:
@RequestMapping("/userlist")
public R userlist(@RequestBody String data) {
JSONObject jsonObject=JSONObject.fromObject(data);
System.out.println(jsonObject.get("params"));//获取具体的参数
QueryWrapper<User> queryWrapper=new QueryWrapper<>();
queryWrapper.eq("age", 18);
List<User> users=userMapper.selectList(queryWrapper);
return R.ok().data("userlist",users);
}
注意:读取字符串正常,解析的时候出错的解决办法:要把接收到的字符串处理成标准的json字符串格式。
public R selectUser0(@RequestBody String jsonObject) {
int i = jsonObject.indexOf("{");
jsonObject = jsonObject.substring(i);
JSONObject da=JSONObject.fromObject(jsonObject.trim());
System.out.println(da);
JSONObject js= da.getJSONObject("params");
String id= js.getString("id");
Long ids=Long.valueOf(id);
User user = userMapper.selectById(ids);
return R.ok().data("selectById",user);
}
或者直接用JSONObject接收也行;
public R userlist( HttpServletRequest request,@RequestBody JSONObject jsonObject) {
JSONObject js=(JSONObject) jsonObject.get("params");
String nameStr=js.getString("name")
System.out.println("更新"+jsonObject.get("params")+" ");
return R.ok().data("userlist","");
}
1.使用javaBean对象接收参数
import lombok.Data; @Data//自动生成get、set等方法 public class Person { String username; String password; }
@RequestMapping("/regist") public String regist(Person person){ String username= person.getUsername(); String password =person.getPassword(); System.out.println("result is:"+username+password); return "注册"; }
2.@RequestHeader接收header中的参数
@RequestMapping("/regist") public String regist(@RequestHeader("mytoken") String mytoken){ System.out.println("tokenis:"mytoken); return "注册"; }
3.用@RequestParam Map<String, String> person 接收参数
@RequestMapping("/regist") public String regist(@RequestParam Map<String, String> person){ String username=person.get("username");//username是前端的参数,要一致 String password =person.get("password");//password是前端参数 System.out.println("result is:"+username); return "注册成功"; }
4.@RequestParam获取多个参数,并且校验,默认是校验参数,
@RequestMapping("/regist") //标红的username和password是前端传的参数,required==false表示不需要校验参数,不写的话,默认需要校验参数 public String regist(@RequestParam("username",required = false) String myusername,@RequestParam("password") String mypassword){ System.out.println("result is:" +myusername + mypassword); return "注册成功"; }
5.@PathVariable接收参数,这种是用占位符的形式接收参数,只能用于get方式,xxx/参数一/参数二(http://localhost:8080/regist/lambo/123)
@RequestMapping("/regist/{username}/{password}") public String regist(@PathVariable("username") String myusername,@PathVariable("password") String mypassword){ System.out.println("result is:" +myusername + mypassword); return "注册成功"; }
6.HttpServletRequest接收参数
@RequestMapping("/regist") public String regist(HttpServletRequest request){ //username和password是前端传的参数 String myusername=request.getParameter("username"); String mypassword=request.getParameter("password"); System.out.println("result is:" +myusername+mypassword); return "注册成功"; }
7.直接用前端参数名接收 http://localhost:8080/regist?username=lambo
@RequestMapping("/regist") //username要和前端参数名字一致 public String regist(String username){ System.out.println("result is:" +username); return "注册成功"; }
8.用JSONObject接收前端传递的json字符串。注意:java后台接收参数必须用@RequestBody修饰,前端请求的参数必须是json字符串;一般header用application/json,如果header是application/x-www-form-urlencoded,后台接收到数据是经过URL编码的,要转化成原生的json字符串再处理。
@RequestMapping("/regist") public String regist(@RequestBody JSONObject jsonstr){ System.out.println( jsonstr.get("username"));//获取具体的参数 return "注册成功"; }
9.用Map接收前端传递的json字符串。注意:java后台接收参数必须用@RequestBody修饰,前端请求的参数必须是json字符串;一般header用application/json,如果header是application/x-www-form-urlencoded,后台接收到数据是经过URL编码的,要转化成原生的json字符串再处理。
@RequestMapping("/login") public String login(@RequestBody Map<String, String> person){ System.out.println("username is:"+person.get("username")); return "登录"; }
10.用String接收前端传递的json字符串。注意:java后台接收参数必须用@RequestBody修饰,前端请求的参数必须是json字符串;一般header用application/json,如果header是application/x-www-form-urlencoded,后台接收到数据是经过URL编码的,要转化成原生的json字符串再处理。
@RequestMapping("/loginout") public String loginout(@RequestBody String jsonstrdata){ JSONObject jsonObject=JSONObject.fromObject(jsonstrdata); System.out.println(jsonObject.get("username")); return "退出"; }
postman中几种发送请求的方式:
Header | Body | response |
application/json: | raw | 传递的参数是json字符串(普通字符串也可以), java后台必须用@RequestBody修饰接收参数, 接收到的数据形式是json字符串。 |
application/json: | form-data | 传递的参数是键值对形式, java后台不能用@RequestBody修饰接收参数。 |
application/json: | x-www-form-urlencoded | 传递的参数是键值对形式, java后台可以用也可以不用@RequestBody修饰接收参数。 接收到的数据形式:username=lambo003 解析数据的时候不方便。 |
application/x-www-form-urlencoded | raw | 传递的参数是json字符串(普通字符串也可以), java后台必须用@RequestBody修饰接收参数。 接收到的数据形式是经过url编码的(如%7B%22username%22%3A%22lambo%22%2C%22password%22%3A%2212345678%22%7D=); 注意:返回的数据用JSONObject jsonObject=JSONObject.fromObject(jsonstrdata)处理会报错,需要先把接收到的数据先处理成json字符串,在用json反序列化。 |
application/x-www-form-urlencoded | form-data | 传递的参数是键值对形式, java后台不能用@RequestBody修饰接收参数。 |
application/x-www-form-urlencoded | x-www-form-urlencoded | 传递的参数是键值对形式, java后台可以用也可以不用@RequestBody修饰接收参数。 接收到的数据形式:username=lambo003 解析数据的时候不方便。 |
***图片上传前后端示意:
图片上传前端可以采用两种方式:
- formData
- base64
*elementui上传
相关属性说明:https://segmentfault.com/a/1190000017297187?utm_source=tag-newest
1、action变量为后端图片接口的地址
2、beforeUpload方法是指的上传之前触发的函数,可以用来做前端文件格式判断,文件大小判断
3、on-change方法是指每次选择文件都会触发函数,可以用来前端删除和添加照片
4、list-type属性指的是照片picture-card展示的方式
5、name指的是上传的文件字段名,这是后端确认文件流的字段名,可以随便写
6、data属性指的是上传时附带的额外参数,这是指的其他参数
7、limit属性指的是上传文件的个数极限。
8、multiple属性指的是可以每次多选文件,true为多选,false为单选
9、auto-upload属性指的是自动上传的,true为可以自动上传,false为不可以自动上传
10、on-preview方法指的是查看缩略图的方法
11、on-remove方法指的是删除文件的方法
12、ref绑定dom元素
<el-upload multipart class="upload-demo"
:multiple="true"
action="http://localhost:8889/demo/uploadimage" 请求的后台地址
:on-preview="handlePreview"
:on-remove="handleRemove"
:file-list="filelists"
list-type="picture" 列表显示的类型
:headers="headerObj" //图片上传组件的请求头
ref="uploadref" //当前el-upload引用
:before-upload="beforeAvatarUpload"
:on-change="fileChange" //文件列表发生变化时调用
name="files"//这个是要传的文件,和后台对应@RequestParam("files") MultipartFile[] file
:data="externaldata" //额外传递的参数,后台用@RequestParam Map<String,String> map接收
:auto-upload="false" //关闭自动上传,改为人为上传
>
<el-button size="small" type="primary">选取图片</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过 500kb</div>
</el-upload>
<el-button size="small" type="primary" @click="uploadsubmit">点击上传</el-button>
<script type="text/javascript">
export default{
data(){
return {
externaldata: { age: 11 },}
},
created(){
},
methods:{
}
}
</script>
spring 后台代码接收elemnetui上传的图片文件和其他数据:
//上传图片----elementui传递的数据
@RequestMapping("/uploadimage")
// @ResponseBody
public R uploadimage(@RequestParam Map<String,String> map,@RequestParam("files") MultipartFile[] file,HttpServletRequest request) {
// /Users/HaokeMaster/Desktop/ncimage
try{
String age = map.get("age").toString();
System.out.println("额外的参数"+age);
}catch (Exception e){
}
MultipartFile fil=file[0];
if (fil.isEmpty()) {
System.out.println("文件为空空");
}
String fileName = fil.getOriginalFilename(); // 文件名
String suffixName = fileName.substring(fileName.lastIndexOf(".")); // 后缀名
String filePath = "/Users/HaokeMaster/Desktop/ncimage/"; // 上传后的路径
fileName = UUID.randomUUID() + suffixName; // 新文件名
//创建新文件夹
File dest = new File(filePath + fileName);
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
try {
fil.transferTo(dest);//把文件流保存到目标文件夹
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("上传图片传过来的参数"+file+fileName);
//这里还要把接收到文件新的存储路径存到数据库表中
return R.ok().data("goodslist",1);
}
********elementui通过http-request覆盖原来的上传逻辑,用new FormData()携带数据;
<el-upload multipart class="upload-demo" :multiple="true" :on-preview="handlePreview" :on-remove="handleRemove" :file-list="filelists" list-type="picture" :headers="headerObj" ref="uploadref" :before-upload="beforeAvatarUpload" :on-change="fileChange" name="files" :data="externaldata" :auto-upload="false"
:http-request="uploadformdatafile" //覆盖原来的上传逻辑
>
<el-button size="small" type="primary">选取图片</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
<el-button size="small" type="primary" @click="uploadsubmit">点击上传</el-button>
fileChange(file){
//当文件发生变化时执行此方法
console.log(file)
},
//提交请求
async uploadsubmit(file) {
console.log(file)
this.$refs.uploadref.submit();
},
//http-request覆盖原来的请求逻辑
uploadformdatafile(params){
console.log(params.file)
let formData = new FormData();
// 向 formData 对象中添加文件
formData.append('file',params.file);
formData.append('age',11);
this.$http.post('uploadimage',formData,{headers:{'Content-type':'multipart/form-data'}})
},
springboot后台:
//上传图片----使用formdata传递的数据
@RequestMapping("/uploadimage")
// @ResponseBody
public R uploadimage(@RequestParam Map<String,String> map,@RequestParam("files") MultipartFile[] file,HttpServletRequest request) {
// /Users/HaokeMaster/Desktop/ncimage
//获取文件以外的数据
MultipartHttpServletRequest params=((MultipartHttpServletRequest) request);
String age=params.getParameter("age");
//获取文件数据
List<MultipartFile> files = ((MultipartHttpServletRequest) request)
.getFiles("file");
MultipartFile fil = null;
BufferedOutputStream stream = null;
for (int i = 0; i < files.size(); ++i) {
fil = files.get(i);
String fileName = fil.getOriginalFilename(); // 文件名
String suffixName = fileName.substring(fileName.lastIndexOf(".")); // 后缀名
String filePath = "/Users/HaokeMaster/Desktop/ncimage/"; // 上传后的路径
fileName = UUID.randomUUID() + suffixName; // 新文件名
File dest = new File(filePath + fileName);//存储文件的路径
if (!fil.isEmpty()) {
try {
byte[] bytes = fil.getBytes();
stream = new BufferedOutputStream(new FileOutputStream(dest));
stream.write(bytes);
stream.close();
} catch (Exception e) {
stream = null;
}
} else {
}
}
System.out.println("上传图片传过来的参数"+file+"其他参数"+age);
//这里还要把接收到文件新的存储路径存到数据库表中
return R.ok().data("goodslist",1);
}
*原始的input框上传图片
前端:
<form action="http://localhost:8889/demo/uploadimage" method="post" enctype="multipart/form-data">
<label>上传图片</label>
<input type="file" name="file"/>
<input type="submit" value="上传"/>
</form>
方式一:springboot后台代码fil.transferTo(dest)的方式吧接收的流文件存储到目标文件夹,
//上传图片
@RequestMapping("/uploadimage")
// @ResponseBody
public R uploadimage(@RequestParam Map<String,String> map,@RequestParam("file") MultipartFile[] file,HttpServletRequest request) {
// /Users/HaokeMaster/Desktop/ncimage
MultipartFile fil=file[0];
if (fil.isEmpty()) {
System.out.println("文件为空空");
}
String fileName = fil.getOriginalFilename(); // 文件名
String suffixName = fileName.substring(fileName.lastIndexOf(".")); // 后缀名
String filePath = "/Users/HaokeMaster/Desktop/ncimage/"; // 上传后的路径,这里举例子上传到本地的一个文件夹,实际运用中数据库存路径,实体数据存到服务器上的文件夹中
fileName = UUID.randomUUID() + suffixName; // 新文件名
//创建新文件夹
File dest = new File(filePath + fileName);
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
try {
fil.transferTo(dest);//把文件流保存到目标文件夹
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("上传图片传过来的参数"+file);
//这里还要把文件的接收的文件存储路径保存到数据库表中
return R.ok().data("goodslist",fileName);
}
方式二:springboot后台用MultipartFile接收流文件并存储到指定路径,
//上传图片----base64上传
@RequestMapping("/uploadimage")
// @ResponseBody
public R uploadimage(@RequestParam Map<String,String> map,@RequestParam("file") MultipartFile[] file,HttpServletRequest request) {
// /Users/HaokeMaster/Desktop/ncimage/
MultipartFile fil=file[0];
String fileName = fil.getOriginalFilename(); // 文件名
String suffixName = fileName.substring(fileName.lastIndexOf(".")); // 后缀名
String filePath = "/Users/HaokeMaster/Desktop/ncimage/"; // 上传后的路径
fileName = UUID.randomUUID() + suffixName; // 新文件名
File dest = new File(filePath + fileName);//存储文件的路径
if (!fil.isEmpty()) {
System.out.println("文件为空空");
}
try {
//把fil写入到指定路径
BufferedOutputStream out = new BufferedOutputStream(
new FileOutputStream(dest));
out.write(fil.getBytes());
out.flush();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("上传图片传过来的参数"+file);
//这里还要把接收到文件新的存储路径存到数据库表中
return R.ok().data("goodslist",filePath + fileName);
}
方式三:用httprequest接收流
<form action="http://localhost:8889/demo/uploadimage" method="post" enctype="multipart/form-data" mutiple="multiple">
<label>上传图片</label>
<input type="file" name="file"/>
<input type="file" name="file"/>
<input type="submit" value="上传"/>
</form>
//上传图片----表单文件上传多文件
@RequestMapping("/uploadimage")
// @ResponseBody
public R uploadimage(HttpServletRequest request) {
// /Users/HaokeMaster/Desktop/ncimage
MultipartHttpServletRequest params=((MultipartHttpServletRequest) request);
List<MultipartFile> files = ((MultipartHttpServletRequest) request)
.getFiles("file");
// String name=params.getParameter("name");
// System.out.println("name:"+name);
// String id=params.getParameter("id");
// System.out.println("id:"+id);
System.out.println("传过来的"+files.get(0).getOriginalFilename());
MultipartFile file = null;
BufferedOutputStream stream = null;
for (int i = 0; i < files.size(); ++i) {
file = files.get(i);
String fileName = file.getOriginalFilename(); // 文件名
String suffixName = fileName.substring(fileName.lastIndexOf(".")); // 后缀名
String filePath = "/Users/HaokeMaster/Desktop/ncimage/"; // 上传后的路径
fileName = UUID.randomUUID() + suffixName; // 新文件名
File dest = new File(filePath + fileName);//存储文件的路径
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
stream = new BufferedOutputStream(new FileOutputStream(dest));
stream.write(bytes);
stream.close();
} catch (Exception e) {
stream = null;
}
} else {
}
}
//这里还要把接收到文件新的存储路径存到数据库表中
return R.ok().data("goodslist",1);
}
方式四:springboot接收base64数据;
前端把文件数据转成base64方法一:
<form> <input type="file" id="myImage" name="myImage"/>
<input type="button" οnclick="uploadFile();" value="上传">
</form>
//通过FileReader.readAsDataURL获取base64数据
function uploadFile(file){
var f = document.getElementById("myImage").files[0];
var reader = new FileReader(); //新建一个FileReader
reader.readAsDataURL(f); // 读取文件base64数据
reader.onload = function(e){ //数据读取完成产生onload事件
var data = e.target.result; //获取数据
if (data.lastIndexOf('data:base64') != -1) {
data = data.replace('data:base64', 'data:image/jpeg;base64');
} else if (data.lastIndexOf('data:,') != -1) {
data = data.replace('data:,', 'data:image/jpeg;base64,');
}
if(isCanvasSupported()){
//这里是上传,发送网络请求
}else{
alert("您的浏览器不支持");
}
};
reader.onerror = function(){
console.log("上传失败了 ");
}
}
可以使用 canvas的toDataUrl转换成base64编码的图片数据进行上传,具体获取方式如下:
<canvas id="mycanvas"></canvas>
<img src="" id="img">
// 调用 convertImageToBase64(image的路径地址)
function convertImageToBase64(image的路径地址) {
var imgObj = new Image();
// 先设置图片跨域属性
imgObj.setAttribute("crossOrigin",'anonymous')
// 再给image赋值src属性,先后顺序不能颠倒
imgObj.src = image;
// 当图片加载完成后,绘制图片到canvas
imgObj.onload = function () {
var canvas = document.getElementById("mycanvas");
var ctx = canvas.getContext('2d');
//上面没有canvas元素的话这里也可以创建一个
// let canvas = document.createElement('canvas')
// 设置canvas宽高等于图片实际宽高
canvas.width = this.width;
canvas.height = this.height;
ctx.drawImage(this, 0, 0);//这里的this指的是当前imgObj对象
// 将图片转成base64格式
var img = canvas.toDataURL("image/jpeg", 0.5); // toDataUrl可以接收2个参数,参数一:图片类型,参数二: 图片质量0-1(不传默认为0.92)
document.getElementById('img').setAttribute("src", img) // 将base64格式图片显示到页面上
}
}
springboot后台接收base64字符串并解析:
//上传图片----接收base64字符串
@RequestMapping("/uploadimage")
// @ResponseBody
public R uploadimage(String base64Data) {
// /Users/HaokeMaster/Desktop/ncimage
String dataPrix = ""; //base64格式前头
String data = "";//实体部分数据
if(base64Data==null||"".equals(base64Data)){
//数据为空
}else {
String [] d = base64Data.split("base64,");//将字符串分成数组
if(d != null && d.length == 2){
dataPrix = d[0];
data = d[1];
}else {
// "上传失败,数据不合法","401"
}
}
String suffix = "";//图片后缀,用以识别哪种格式数据
//data:image/jpeg;base64,base64编码的jpeg图片数据
if("data:image/jpeg;".equalsIgnoreCase(dataPrix)){
suffix = ".jpg";
}else if("data:image/x-icon;".equalsIgnoreCase(dataPrix)){
//data:image/x-icon;base64,base64编码的icon图片数据
suffix = ".ico";
}else if("data:image/gif;".equalsIgnoreCase(dataPrix)){
//data:image/gif;base64,base64编码的gif图片数据
suffix = ".gif";
}else if("data:image/png;".equalsIgnoreCase(dataPrix)){
//data:image/png;base64,base64编码的png图片数据
suffix = ".png";
}else {
}
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
String tempFileName=uuid+suffix;
String imgFilePath = "/Users/HaokeMaster/Desktop/ncimage/"+tempFileName;//新生成的图片
// BASE64Decoder decoder = new BASE64Decoder();//base64解析,这个需要导入框架
// byte[] b = decoder.decodeBuffer(data);
try {
//Base64解码
byte[] b = Base64Utils.decodeFromString(data);//spring自带的base64解析
for(int i=0;i<b.length;++i) {
if(b[i]<0) {
//调整异常数据
b[i]+=256;
}
}
OutputStream out = new FileOutputStream(imgFilePath);
out.write(b);
out.flush();
out.close();
}catch (Exception e) {
}
//这里还要把接收到文件新的存储路径存到数据库表中
return R.ok().data("goodslist",1);
}
方式五:前端传递的是new Formdata()类型的数据;
<form >
<label>上传图片</label>
<input type="file" @change="getFile($event)" name="files" />
<input type="file" @change="getFile1($event)" name="file1" />
<input type="submit" value="上传" />
<button @click="submit($event)">提交</button>
</form>
<script type="text/javascript">
export default{
data(){
return {
file:{}//存储上传的文件数据
}
},
created(){
},
methods:{
}
}
</script>
//获取上传的文件
getFile(event) {
this.file = event.target.files[0];//这是取的第一个文件
console.log(this.file);
},
//提交发送给后台
async submit(event) {
console.log(this.file)
event.preventDefault();//取消默认行为
//创建 formData 对象
let formData = new FormData();
// 向 formData 对象中添加文件
formData.append('file',this.file);//文件数据
formData.append('age',11);//其他数据
发送请求的方法一:
// this.$http.post("uploadimage", formData)
// .then(function(reh){
// console.log('rehsdddddd===>>>', reh);
// })
// .catch(function(err){
// console.log('err=ssss=>>', err);
// })
发送请求的方法二:
const rest = await this.$http.post('uploadimage',formData)
},
springboot后台:
//上传图片----使用formdata传递的数据
@RequestMapping("/uploadimage")
// @ResponseBody
public R uploadimage(@RequestParam Map<String,String> map,@RequestParam("files") MultipartFile[] file,HttpServletRequest request) {
// /Users/HaokeMaster/Desktop/ncimage
//获取文件以外的数据
MultipartHttpServletRequest params=((MultipartHttpServletRequest) request);
String age=params.getParameter("age");
//获取文件数据
List<MultipartFile> files = ((MultipartHttpServletRequest) request)
.getFiles("file");
MultipartFile fil = null;
BufferedOutputStream stream = null;
for (int i = 0; i < files.size(); ++i) {
fil = files.get(i);
String fileName = fil.getOriginalFilename(); // 文件名
String suffixName = fileName.substring(fileName.lastIndexOf(".")); // 后缀名
String filePath = "/Users/HaokeMaster/Desktop/ncimage/"; // 上传后的路径
fileName = UUID.randomUUID() + suffixName; // 新文件名
File dest = new File(filePath + fileName);//存储文件的路径
if (!fil.isEmpty()) {
try {
byte[] bytes = fil.getBytes();
stream = new BufferedOutputStream(new FileOutputStream(dest));
stream.write(bytes);
stream.close();
} catch (Exception e) {
stream = null;
}
} else {
}
}
System.out.println("上传图片传过来的参数"+file+"其他参数"+age);
//这里还要把接收到文件新的存储路径存到数据库表中
return R.ok().data("goodslist",1);
}
====ios上的图片文件上传====要根据后台返回的数据类型来调整前端response的使用类型,如resposne,responseJson,responseData,responseDecodable,resposneString,response(:queue)
SpringBoot后台可以使用@RequestParam("file") MultipartFile[] file或者 HttpServletRequest request作为参数接收前端的数据
Alamofire:Uploading Multipart Form Data表单上传URL
func uploadFormdataWithfileURL(){
let fileURL = Bundle.main.url(forResource: "lunbothree", withExtension: "png")//图片的URL
let data = UIImage.init(named: "003")?.pngData()//图片的Data数据
AF.upload(multipartFormData: { multipartFormData in
/*
fileURL:上传的文件路径,URL类型
withName:后台接收文件的字段名
fileName:文件的原始名称,后台接收到就是这个名称
mimeType:文件类型
*/
multipartFormData.append(fileURL!, withName: "file",fileName:"lunbo.png",mimeType: "image/png")// URL上传图片
}, to: urlstr)
.responseString{ response in
print("\(response.value)")
}
}
SpringBoot后台:
//@RequestParam("file") MultipartFile file 和 HttpServletRequest request都可以接收表单数据,如果使用@RequestParam("file") MultipartFile file的话,就要和Alammofire传递的withName一致
@RequestMapping("/uploadimage")
public String uploadimage(@RequestParam("file") MultipartFile file,HttpServletRequest request) {
//Alamofire: multipartFormData.append(fileURL!, withName: "file",fileName:"lunbo.png",mimeType: "image/png")
//file对应withName; file.getOriginalFilename()原始文件名对应fileName;
MultipartFile fil=file;
System.out.println("上传图片传过来的参数"+file+fil.getOriginalFilename());
if (fil.isEmpty()) {
System.out.println("文件为空空");
}
String fileName = fil.getOriginalFilename(); // 原始的文件名,对应的是ios端的fileName
String suffixName = fileName.substring(fileName.lastIndexOf(".")); // 后缀名
String filePath = "/Users/HaokeMaster/Desktop/ncimage/"; // 存储的路径
fileName = UUID.randomUUID() + suffixName; // 新文件名
//创建新文件夹
File dest = new File(filePath + fileName);
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
try {
fil.transferTo(dest);//把文件流保存到目标文件夹
} catch (IOException e) {
e.printStackTrace();
}
//这里还要把接收到文件新的存储路径存到数据库表中
return "上传成功";
}
或者
@RequestMapping("/uploadimage")
public String uploadimage(@RequestParam("file") MultipartFile[] file, HttpServletRequest request) {
//获取文件数据列表
//从MultipartHttpServletRequest中获取file
List<MultipartFile> files = ((MultipartHttpServletRequest) request)
.getFiles("file");
//直接使用@RequestParam("file") MultipartFile[] file中的file,和上面的功能是一样的
// List<MultipartFile> files = Arrays.asList(file.clone());
MultipartFile fil = null;
BufferedOutputStream stream = null;
for (int i = 0; i < files.size(); ++i) {
fil = files.get(i);
String fileName = fil.getOriginalFilename(); // 文件名
String suffixName = fileName.substring(fileName.lastIndexOf(".")); // 后缀名
String filePath = "/Users/HaokeMaster/Desktop/ncimage/"; // 上传后的路径
fileName = UUID.randomUUID() + suffixName; // 新文件名
File dest = new File(filePath + fileName);//存储文件的路径
if (!fil.isEmpty()) {
try {
byte[] bytes = fil.getBytes();
stream = new BufferedOutputStream(new FileOutputStream(dest));
stream.write(bytes);
stream.close();
} catch (Exception e) {
stream = null;
}
} else {
}
}
System.out.println("上传图片传过来的参数"+file+"名字"+fil.getOriginalFilename()+"其他参数"+files.size());
//这里还要把接收到文件新的存储路径存到数据库表中
return "上传成功";
}
Alamofire:Uploading Multipart Form Data表单上传Data
func uploadFormdataWithdata(){
let data = UIImage.init(named: "003")?.pngData()//图片的Data数据
AF.upload(multipartFormData: { multipartFormData in
/*
fileURL:上传的文件路径,URL类型
withName:后台接收文件的字段名
fileName:文件的原始名称,后台接收到就是这个名称
mimeType:文件类型
*/
multipartFormData.append(data!, withName: "file",fileName:"lunbo.png",mimeType: "image/png")//Data上传图片\
multipartFormData.append(data, withName: "file")//这个在后台就获取不到原始的名称
}, to: urlstr)
.responseString{ response in
print("\(response.value)")
}
}
SpringBoot后台:
//@RequestParam("file") MultipartFile file 和 HttpServletRequest request都可以接收表单数据,如果使用@RequestParam("file") MultipartFile file的话,就要和Alammofire传递的withName一致
@RequestMapping("/uploadimage")
public String uploadimage(@RequestParam("file") MultipartFile file,HttpServletRequest request) {
//Alamofire: multipartFormData.append(fileURL!, withName: "file",fileName:"lunbo.png",mimeType: "image/png")
//file对应withName; file.getOriginalFilename()原始文件名对应fileName;
MultipartFile fil=file;
System.out.println("上传图片传过来的参数");
if (fil.isEmpty()) {
System.out.println("文件为空空");
}
String fileName = fil.getOriginalFilename(); // 原始的文件名,对应的是ios端的fileName,如果Alamafire没有传递fileName,这里就获取不到
String suffixName = fileName.substring(fileName.lastIndexOf(".")); // 后缀名
String filePath = "/Users/HaokeMaster/Desktop/ncimage/"; // 存储的路径
fileName = UUID.randomUUID() + suffixName; // 新文件名
//创建新文件夹
File dest = new File(filePath + fileName);
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
try {
fil.transferTo(dest);//把文件流保存到目标文件夹
} catch (IOException e) {
e.printStackTrace();
}
//这里还要把接收到文件新的存储路径存到数据库表中
return "上传成功";
}
Alamofire:Uploading Multipart Form Data表单上传多张图片,有Data、URL类型
func uploadFormdataWithMuti(){
let data = (UIImage.init(named: "003")?.pngData())!//图片的Data数据
let fileURL = Bundle.main.url(forResource: "lunbothree", withExtension: "png")!//图片的URL
AF.upload(multipartFormData: { multipartFormData in
/*
fileURL:上传的文件路径,URL类型
withName:后台接收文件的字段名
fileName:文件的原始名称,后台接收到就是这个名称
mimeType:文件类型
*/
multipartFormData.append(data, withName: "file",fileName:"lunbo.png",mimeType: "image/png")//图片的Data数据
multipartFormData.append(fileURL, withName: "file",fileName:"lunbo1.png",mimeType: "image/png")//图片的URL
}, to: urlstr)
.responseString{ response in
print("\(String(describing: response.value))")
}
}
SpringBoot后台:
//@RequestParam("file") MultipartFile file 和 HttpServletRequest request都可以接收表单数据,如果使用@RequestParam("file") MultipartFile file的话,就要和Alammofire传递的withName一致
@RequestMapping("/uploadimage")
public String uploadimage(@RequestParam("file") MultipartFile[] file, HttpServletRequest request) {
//获取文件数据列表
//从MultipartHttpServletRequest中获取file
List<MultipartFile> files = ((MultipartHttpServletRequest) request)
.getFiles("file");
//直接使用@RequestParam("file") MultipartFile[] file中的file,和上面的功能是一样的
// List<MultipartFile> files = Arrays.asList(file.clone());
MultipartFile fil = null;
BufferedOutputStream stream = null;
//files.size()就是图片的个数
for (int i = 0; i < files.size(); ++i) {
fil = files.get(i);
String fileName = fil.getOriginalFilename(); // 文件名
String suffixName = fileName.substring(fileName.lastIndexOf(".")); // 后缀名
String filePath = "/Users/HaokeMaster/Desktop/ncimage/"; // 上传后的路径
fileName = UUID.randomUUID() + suffixName; // 新文件名
File dest = new File(filePath + fileName);//存储文件的路径
if (!fil.isEmpty()) {
try {
byte[] bytes = fil.getBytes();
stream = new BufferedOutputStream(new FileOutputStream(dest));
stream.write(bytes);
stream.close();
} catch (Exception e) {
stream = null;
}
} else {
}
}
System.out.println("上传图片传过来的参数"+file+"名字"+fil.getOriginalFilename()+"其他参数"+files.size());
//这里还要把接收到文件新的存储路径存到数据库表中
return "上传成功";
}
Alamofire:Uploading Multipart Form Data表单上传多张图片,有Data、URL、其他数据类型
func uploadFormdataWithMuti(){
let data = (UIImage.init(named: "003")?.pngData())!
let dict=["age":"18"]
let dictdata = (try? JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted))!
let fileURL = Bundle.main.url(forResource: "lunbothree", withExtension: "png")!
AF.upload(multipartFormData: { multipartFormData in
/*
fileURL:上传的文件路径,URL类型
withName:后台接收文件的字段名
fileName:文件的原始名称,后台接收到就是这个名称
mimeType:文件类型
*/
multipartFormData.append(data, withName: "file",fileName:"lunbo.png",mimeType: "image/png")
multipartFormData.append(fileURL, withName: "file",fileName:"lunbo1.png",mimeType: "image/png")
multipartFormData.append(dictdata, withName: "age")//携带其他数据,这个数据必须能转化成NSData
}, to: urlstr)
.responseString{ response in
print("\(String(describing: response.value))")
}
}
SpringBoot后台:
@RequestMapping("/uploadimage")
public String uploadimage( HttpServletRequest request) {
//获取文件以外的数据,获取非图片文件类型的数据必须要用request,使用@RequestParam("file") MultipartFile[] file无法获取其他类型的数据,只能获取图片文件数据
MultipartHttpServletRequest params=((MultipartHttpServletRequest) request);
String age=params.getParameter("age");
//获取文件数据列表
//从MultipartHttpServletRequest中获取file
List<MultipartFile> files = ((MultipartHttpServletRequest) request)
.getFiles("file");
MultipartFile fil = null;
BufferedOutputStream stream = null;
//files.size()只包含图片文件的个数,不包含其他类型的数据
for (int i = 0; i < files.size(); ++i) {
fil = files.get(i);
String fileName = fil.getOriginalFilename(); // 文件名
String suffixName = fileName.substring(fileName.lastIndexOf(".")); // 后缀名
String filePath = "/Users/HaokeMaster/Desktop/ncimage/"; // 上传后的路径
fileName = UUID.randomUUID() + suffixName; // 新文件名
File dest = new File(filePath + fileName);//存储文件的路径
if (!fil.isEmpty()) {
try {
byte[] bytes = fil.getBytes();
stream = new BufferedOutputStream(new FileOutputStream(dest));
stream.write(bytes);
stream.close();
} catch (Exception e) {
stream = null;
}
} else {
}
}
System.out.println("上传图片传过来的参数"+"名字"+fil.getOriginalFilename()+"其他参数"+files.size()+age);
//这里还要把接收到文件新的存储路径存到数据库表中
return "上传成功";
}
Uploading Data上传NSData数据,这里传递其他参数要用url拼接的形式
func uploadData(){
let data = UIImage.init(named: "003")?.pngData()
AF.upload(data!, to: "http://localhost:8080/uploadimage?age=18").responseString{response in
debugPrint(response)
}
}
SpringBoot后台:
@RequestMapping("/uploadimage")
public String uploadimage(InputStream stream,HttpServletRequest request) throws IOException {
//age是"http://localhost:8080/uploadimage?age=18"中的参数
String age=request.getParameter("age");
System.out.println("上传图片传过来的参数"+stream+" age="+age);
BufferedOutputStream outstream = null;
String filePath = "/Users/HaokeMaster/Desktop/ncimage/"; // 上传后的路径
String fileName = UUID.randomUUID() + ".png"; // 新文件名
File dest = new File(filePath + fileName);//存储文件的路径
outstream = new BufferedOutputStream(new FileOutputStream(dest));
outstream.write(stream.readAllBytes()); //stream.readAllBytes()是从输入的流读取字节
stream.close();
return "上传成功";
}
Uploading a File上传一个URL
func uploadFile(){
let fileURL = Bundle.main.url(forResource: "lunbothree", withExtension: "png")
AF.upload(fileURL!, to:"http://localhost:8080/uploadimage?age=18").responseString{ response in
debugPrint(response)
}
}
SpringBoot后台:
@RequestMapping("/uploadimage")
public String uploadimage(InputStream stream,HttpServletRequest request) throws IOException {
//age是"http://localhost:8080/uploadimage?age=18"中的参数
String age=request.getParameter("age");
System.out.println("上传图片传过来的参数"+stream+" age="+age);
BufferedOutputStream outstream = null;
String filePath = "/Users/HaokeMaster/Desktop/ncimage/"; // 上传后的路径
String fileName = UUID.randomUUID() + ".png"; // 新文件名
File dest = new File(filePath + fileName);//存储文件的路径
outstream = new BufferedOutputStream(new FileOutputStream(dest));
outstream.write(stream.readAllBytes()); //stream.readAllBytes()是从输入的流读取字节
stream.close();
return "上传成功";
}
***视频上传和图片上传是一个道理,
springboot中上传文件大小限制:在application.properties中加入:
#单个文件最大大小
spring.servlet.multipart.max-file-size=200MB
#所有上传文件最大大小
spring.servlet.multipart.max-request-size=200MB
更多推荐
所有评论(0)