spring mvc restful能上传多大文件

spring mvc restful能上传多大文件,第1张

SpringMVC本身对Restful支持非常好。它的@RequestMapping、@RequestParam、@PathVariable、@ResponseBody注解很好的支持了REST。18.2CreatingRESTfulservices1.@RequestMappingSpringusesthe@RequestMappingmethodannotationtodefinetheURITemplatefortherequest.类似于struts的action-mapping。可以指定POST或者GET。2.@PathVariableThe@PathVariablemethodparameterannotationisusedtoindicatethatamethodparametershouldbeboundtothevalueofaURItemplatevariable.用于抽取URL中的信息作为参数。(注意,不包括请求字符串,那是@RequestParam做的事情。)@RequestMapping("/owners/{ownerId}",method=RequestMethod.GET)publicStringfindOwner(@PathVariableStringownerId,Modelmodel){//}如果变量名与pathVariable名不一致,那么需要指定:@RequestMapping("/owners/{ownerId}",method=RequestMethod.GET)publicStringfindOwner(@PathVariable("ownerId")StringtheOwner,Modelmodel){//implementationomitted}Tipmethodparametersthataredecoratedwiththe@PathVariableannotationcanbeofanysimpletypesuchasint,long,DateSpringautomaticallyconvertstotheappropriatetypeandthrowsaTypeMismatchExceptionifthetypeisnotcorrect.3.@RequestParam官方文档居然没有对这个注解进行说明,估计是遗漏了(真不应该啊)。这个注解跟@PathVariable功能差不多,只是参数值的来源不一样而已。它的取值来源是请求参数(querystring或者post表单字段)。对了,因为它的来源可以是POST字段,所以它支持更丰富和复杂的类型信息。比如文件对象:@RequestMapping("/imageUpload")publicStringprocessImageUpload(@RequestParam("name")Stringname,@RequestParam("description")Stringdescription,@RequestParam("image")MultipartFileimage)throwsIOException{this.imageDatabase.storeImage(name,image.getInputStream(),(int)image.getSize(),description)return"redirect:imageList"}还可以设置defaultValue:@RequestMapping("/imageUpload")publicStringprocessImageUpload(@RequestParam(value="name",defaultValue="arganzheng")Stringname,@RequestParam("description")Stringdescription,@RequestParam("image")MultipartFileimage)throwsIOException{this.imageDatabase.storeImage(name,image.getInputStream(),(int)image.getSize(),description)return"redirect:imageList"}4.@RequestBody和@ResponseBody这两个注解其实用到了Spring的一个非常灵活的设计——HttpMessageConverter18.3.2HTTPMessageConversion与@RequestParam不同,@RequestBody和@ResponseBody是针对整个HTTP请求或者返回消息的。前者只是针对HTTP请求消息中的一个name=value键值对(名称很贴切)。HtppMessageConverter负责将HTTP请求消息(HTTPrequestmessage)转化为对象,或者将对象转化为HTTP响应体(HTTPresponsebody)。publicinterfaceHttpMessageConverter{//Indicatewhetherthegivenclassissupportedbythisconverter.booleansupports(Classclazz)//ReturnthelistofMediaTypeobjectssupportedbythisconverter.ListgetSupportedMediaTypes()//Readanobjectofthegiventypeformthegiveninputmessage,andreturnsit.Tread(Classclazz,HttpInputMessageinputMessage)throwsIOException,HttpMessageNotReadableException//Writeangivenobjecttothegivenoutputmessage.voidwrite(Tt,HttpOutputMessageoutputMessage)throwsIOException,HttpMessageNotWritableException}SpringMVC对HttpMessageConverter有多种默认实现,基本上不需要自己再自定义HttpMessageConverterStringHttpMessageConverter-convertsstringsFormHttpMessageConverter-convertsformdatato/fromaMultiValueMapByteArrayMessageConverter-convertsbytearraysSourceHttpMessageConverter-convertto/fromajavax.xml.transform.SourceRssChannelHttpMessageConverter-convertto/fromRSSfeedsMappingJacksonHttpMessageConverter-convertto/fromJSONusingJackson'sObjectMapperetc然而对于RESTful应用,用的最多的当然是MappingJacksonHttpMessageConverter。但是MappingJacksonHttpMessageConverter不是默认的HttpMessageConverter:publicclassAnnotationMethodHandlerAdapterextendsWebContentGeneratorimplementsHandlerAdapter,Ordered,BeanFactoryAware{publicAnnotationMethodHandlerAdapter(){//norestrictionofHTTPmethodsbydefaultsuper(false)//SeeSPR-7316StringHttpMessageConverterstringHttpMessageConverter=newStringHttpMessageConverter()stringHttpMessageConverter.setWriteAcceptCharset(false)this.messageConverters=newHttpMessageConverter[]{newByteArrayHttpMessageConverter(),stringHttpMessageConverter,newSourceHttpMessageConverter(),newXmlAwareFormHttpMessageConverter()}}}如上:默认的HttpMessageConverter是ByteArrayHttpMessageConverter、stringHttpMessageConverter、SourceHttpMessageConverter和XmlAwareFormHttpMessageConverter转换器。所以需要配置一下:text/plaincharset=GBK配置好了之后,就可以享受@Requestbody和@ResponseBody对JONS转换的便利之处了:@RequestMapping(value="api",method=RequestMethod.POST)@ResponseBodypublicbooleanaddApi(@RequestBodyApiapi,@RequestParam(value="afterApiId",required=false)IntegerafterApiId){Integerid=apiMetadataService.addApi(api)returnid>0}@RequestMapping(value="api/{apiId}",method=RequestMethod.GET)@ResponseBodypublicApigetApi(@PathVariable("apiId")intapiId){returnapiMetadataService.getApi(apiId,Version.primary)}一般情况下我们是不需要自定义HttpMessageConverter,不过对于Restful应用,有时候我们需要返回jsonp数据:packageme.arganzheng.study.springmvc.utilimportjava.io.IOExceptionimportjava.io.PrintStreamimportorg.codehaus.jackson.map.ObjectMapperimportorg.codehaus.jackson.map.annotate.JsonSerialize.Inclusionimportorg.springframework.http.HttpOutputMessageimportorg.springframework.http.converter.HttpMessageNotWritableExceptionimportorg.springframework.http.converter.json.MappingJacksonHttpMessageConverterimportorg.springframework.web.context.request.RequestAttributesimportorg.springframework.web.context.request.RequestContextHolderimportorg.springframework.web.context.request.ServletRequestAttributespublicclassMappingJsonpHttpMessageConverterextendsMappingJacksonHttpMessageConverter{publicMappingJsonpHttpMessageConverter(){ObjectMapperobjectMapper=newObjectMapper()objectMapper.setSerializationConfig(objectMapper.getSerializationConfig().withSerializationInclusion(Inclusion.NON_NULL))setObjectMapper(objectMapper)}@OverrideprotectedvoidwriteInternal(Objecto,HttpOutputMessageoutputMessage)throwsIOException,HttpMessageNotWritableException{StringjsonpCallback=nullRequestAttributesreqAttrs=RequestContextHolder.currentRequestAttributes()if(reqAttrsinstanceofServletRequestAttributes){jsonpCallback=((ServletRequestAttributes)reqAttrs).getRequest().getParameter("jsonpCallback")}if(jsonpCallback!=null){newPrintStream(outputMessage.getBody()).print(jsonpCallback+"(")}super.writeInternal(o,outputMessage)if(jsonpCallback!=null){newPrintStream(outputMessage.getBody()).println(")")}}}

在使用springmvc提供rest接口实现文件上传时,有时为了测试需要使用RestTemplate进行调用,那么在使用RestTemplate调用文件上传接口时有什么特别的地方呢?实际上只需要注意一点就行了,就是创建文件资源时需要使用org.springframework.core.io.FileSystemResource类,而不能直接使用Java.io.File对象。

Controller中的rest接口代码如下:

[java] view plain copy

@ResponseBody

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

public String upload(String fileName, MultipartFile jarFile) {

// 下面是测试代码

System.out.println(fileName)

String originalFilename = jarFile.getOriginalFilename()

System.out.println(originalFilename)

try {

String string = new String(jarFile.getBytes(), "UTF-8")

System.out.println(string)

} catch (UnsupportedEncodingException e) {

e.printStackTrace()

} catch (IOException e) {

e.printStackTrace()

}

// TODO 处理文件内容...

return "OK"

}

使用RestTemplate测试上传代码如下:

[java] view plain copy

@Test

public void testUpload() throws Exception {

String url = "http://127.0.0.1:8080/test/upload.do"

String filePath = "C:\\Users\\MikanMu\\Desktop\\test.txt"

RestTemplate rest = new RestTemplate()

FileSystemResource resource = new FileSystemResource(new File(filePath))

MultiValueMap<String, Object>param = new LinkedMultiValueMap<>()

param.add("jarFile", resource)

param.add("fileName", "test.txt")

String string = rest.postForObject(url, param, String.class)

System.out.println(string)

}

其中:

[java] view plain copy

String string = rest.postForObject(url, param, String.class)

可以换成:

[java] view plain copy

HttpEntity<MultiValueMap<String, Object>>httpEntity = new HttpEntity<MultiValueMap<String,Object>>(param)

ResponseEntity<String>responseEntity = rest.exchange(url, HttpMethod.POST, httpEntity, String.class)

System.out.println(responseEntity.getBody())

使用spring注解是可以实现rest服务的,具体实现参考以下步骤代码:

1、配置web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="3.0" 

xmlns="http://java.sun.com/xml/ns/javaee" 

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 

http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

  <display-name></display-name>

  <context-param>

        <!--rest配置文件的路径,貌似不配置也是加载这个地址,这个地方有点疑问,大家指点指点-->

   <param-name>contextConfigLocation</param-name>

   <param-value>/WEB-INF/rest-servlet.xml</param-value>

  </context-param>

  <listener>

   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

  </listener>

  <servlet>

        <!-- 配置一个Servlet,有这个Servlet统一调度页面的请求 -->

   <servlet-name>rest</servlet-name>

   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

   <load-on-startup>2</load-on-startup>

  </servlet>

  <servlet-mapping>

        <!-- 映射路径,不要写成了/*那样会拦截所有的访问,连JSP页面都访问不了 -->

   <servlet-name>rest</servlet-name>

   <url-pattern>/</url-pattern>

  </servlet-mapping>

  <welcome-file-list>

   <welcome-file>/index.jsp</welcome-file>

  </welcome-file-list>

</web-app> 2、配置rest-servlet.xml(这是spring的配置文件) <?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:jee="http://www.springframework.org/schema/jee"

xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"

xmlns:aop="http://www.springframework.org/schema/aop"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"

default-lazy-init="true">

  <description>Spring公共配置</description>

  <!--检测注解-->

  <context:component-scan base-package="com.liqiu" />

  <bean   class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />

  <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

<!-- 注册视图解析器,说白了就是根据返回值指定到某个页面 -->

  <bean id="viewResolver"   class="org.springframework.web.servlet.view.InternalResourceViewResolver">

    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />

    <property name="prefix" value="/"></property> <!--页面文件的路径,在根目录下-->

   </bean>

</beans> 3、Controller代码实现

package com.liqiu.controller

import java.io.IOException

import javax.servlet.http.HttpServletRequest

import javax.servlet.http.HttpServletResponse

import org.springframework.stereotype.Controller

import org.springframework.web.bind.annotation.PathVariable

import org.springframework.web.bind.annotation.RequestMapping

import org.springframework.web.bind.annotation.RequestMethod

@Controller

@RequestMapping("/simple")

public class SimpleController {

//映射路径/simple/index当访问这个路径时,执行这个方法

@RequestMapping("/index")

public String index(HttpServletRequest request ,HttpServletResponse response){

               //response,request会自动传进来

request.setAttribute("message", "Hello,This is a example of Spring3 RESTful!")

return "index.jsp"

}

//根据ID获取不同的内容,通过@PathVariable 获得属性

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

public String get(@PathVariable String id,HttpServletRequest request ,HttpServletResponse response) throws IOException{

request.setAttribute("message", "Hello,This is a example of Spring3 RESTful!<br/>ID:"+id+"")

//response.getWriter().write("You put id is : "+id)

return "index.jsp"

//return null

}

}

JSP页面

<%@ page language="java" pageEncoding="UTF-8"%>

<html>

  <head>

    <title>Spring3 RESTful</title>

   </head>

  

  <body>

    ${message}

   </body>

</html> 4、测试

在浏览器中输入:http://localhost:8080/SpringREST/simple/index/,就可以看到效果。

也可以在页面输入不同的参数,获得不同的内容,输入地址:http://localhost:8080/SpringREST/simple/88888,这次执行的就是get方法,通过注解获取ID值。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/tougao/11768479.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-18
下一篇2023-05-18

发表评论

登录后才能评论

评论列表(0条)

    保存