ファイルをアップロードするための簡単なコントローラーを作成しました。
@RestEndpoint
public class ImageController {
@Autowired
GridFsTemplate mTemplate;
@RequestMapping(value = "images", method = RequestMethod.POST)
public @ResponseBody String testPhoto(@RequestParam String name, @RequestParam String directory, @RequestParam MultipartFile file) throws IOException {
if(!file.isEmpty()){
final byte[] bytes = file.getBytes();
InputStream inputStream = new ByteArrayInputStream(bytes);
mTemplate.store(inputStream, "name");
return "uploaded photo";
}
return "failed";
}
}
@RestEndpoint
注釈は次のとおりです。
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
public @interface RestEndpoint
{
String value() default "";
}
私のContextCOnfigurationクラスは次のとおりです。
@Configuration
@EnableWebMvc
@ComponentScan(
basePackages = "com.questter.site",
useDefaultFilters = false,
includeFilters =
@ComponentScan.Filter({RestEndpoint.class, RestEndpointAdvice.class})
)
public class RestServletContextConfiguration extends WebMvcConfigurerAdapter {
@Bean
public CommonsMultipartResolver multiPartResolver(){
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
return resolver;
}
...
}
- - 更新しました - -
web.xml
ファイル:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>Spring Application</display-name>
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspf</url-pattern>
<page-encoding>UTF-8</page-encoding>
<scripting-invalid>true</scripting-invalid>
<include-prelude>/WEB-INF/jsp/base.jspf</include-prelude>
<trim-directive-whitespaces>true</trim-directive-whitespaces>
<default-content-type>text/html</default-content-type>
</jsp-property-group>
</jsp-config>
<!--<context-param>-->
<!--<param-name>spring.profiles.active</param-name>-->
<!--<param-value>development</param-value>-->
<!--</context-param>-->
<session-config>
<session-timeout>30</session-timeout>
<cookie-config>
<http-only>true</http-only>
</cookie-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
<distributable />
</web-app>
- - 更新しました - -
public class Bootstrap implements WebApplicationInitializer
{
@Override
public void onStartup(ServletContext container) throws ServletException
{
container.getServletRegistration("default").addMapping("/resource/*");
AnnotationConfigWebApplicationContext rootContext =
new AnnotationConfigWebApplicationContext();
rootContext.register(RootContextConfiguration.class);
container.addListener(new ContextLoaderListener(rootContext));
AnnotationConfigWebApplicationContext webContext =
new AnnotationConfigWebApplicationContext();
webContext.register(WebServletContextConfiguration.class);
ServletRegistration.Dynamic dispatcher = container.addServlet(
"springWebDispatcher", new DispatcherServlet(webContext)
);
dispatcher.setLoadOnStartup(1);
dispatcher.setMultipartConfig(new MultipartConfigElement(
null, 20_971_520L, 41_943_040L, 512_000
));
dispatcher.addMapping("/");
AnnotationConfigWebApplicationContext restContext =
new AnnotationConfigWebApplicationContext();
restContext.register(RestServletContextConfiguration.class);
DispatcherServlet servlet = new DispatcherServlet(restContext);
servlet.setDispatchOptionsRequest(true);
dispatcher = container.addServlet(
"springRestDispatcher", servlet
);
dispatcher.setLoadOnStartup(2);
dispatcher.addMapping("/rest/*");
rootContext.refresh();
DbBootstrap dbBootstrap = rootContext.getBean(DbBootstrap.class);
dbBootstrap.init();
}
}
(postmanを使用して)POSTリクエストを実行すると、次のようになります。
HTTP Status 500 - Request processing failed; nested exception is Java.lang.IllegalArgumentException:Expected MultipartHttpServletRequest: is a MultipartResolver configured
私はstackoverflowについていくつかの同様の質問を調べましたが、どの答えも役に立ちませんでした。
Springバージョンは:4.0.4
どんな助けでも大歓迎です(もちろん親指を立てて)。
ありがとう
彼らがこれを行った理由はわかりませんが、コンテキスト内のMultipartResolver
BeanにはmultipartResolver
という名前を付ける必要があります。 @Bean
メソッドの名前を次のように変更します
public CommonsMultipartResolver multipartResolver(){ // lowercase 'P'
または、明示的に名前を付けます
@Bean(name = "multipartResolver")
public CommonsMultipartResolver canBeCalledAnything(){
allowCasualMultipartParsing="true"
context.xml内のコンテキストタグで、それは私のために働いています
マルチパート構成が見つからないという例外から簡単です。 multipartResolver beanを提供しましたが。
問題は、SpringSecurityフィルターの前にMultipartFilterを指定しているときに、multipartResolverを取得しようとすることです。 = Beanですが、見つかりません。 Beanの名前/ IDがmultipartResolverではなくfilterMultipartResolverであると想定しているためです。
どうぞよろしくお願いします。次のようにBeanの構成を変更してください-
@Bean
public CommonsMultipartResolver filterMultipartResolver(){
CommonsMultipartResolver resolver = new
CommonsMultipartResolver();
return resolver;
}
または
@Bean(name = "filterMultipartResolver")
public CommonsMultipartResolver multiPartResolver(){
CommonsMultipartResolver resolver = new
CommonsMultipartResolver();
return resolver;
}
R. ALiAshikによる答えは私のために働いた。
以下は、私が取り組んでいるプロジェクトのpom.xmlの関連部分です。
<properties> <springframework.version>5.0.2.RELEASE</springframework.version> <springsecurity.version>5.0.0.RELEASE</springsecurity.version> <hibernate.version>5.2.17.Final</hibernate.version> <mysql.connector.version>8.0.11</mysql.connector.version>
永続的な認証が設定されたカスタムログインページがあるので、次のものも必要でした。
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
@Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
insertFilters(servletContext, new MultipartFilter());
}
}
しかし、実際のクリンチャーは、R。ALiAshikが指摘したようにこれでした。
@Bean(name = "filterMultipartResolver")
public CommonsMultipartResolver multiPartResolver(){
CommonsMultipartResolver resolver = new
CommonsMultipartResolver();
return resolver;
}
コンテキストに関連する参考資料は次のとおりです。 Class MultipartFilter
そして、関連するテキストは次のとおりです。
Looks up the MultipartResolver in Spring's root web application context. Supports a "multipartResolverBeanName" filter init-param in web.xml; the default bean name is "filterMultipartResolver". Looks up the MultipartResolver on each request, to avoid initialization order issues (when using ContextLoaderServlet, the root application context will get initialized after this filter).