CommonsMultipartFile cannot be resolved to a type - spring

After upgrading spring from older version, to Spring 6.0.4
I noticed this file has moved:
from here (Spring docs 4.3.x for CommonsMultipartFile
web on 6.0.4 doesn't have commons anymore like 4.3.x did
where did this file move?
I tried including this in my pom, didn't help
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
UPDATE
reducing the version of spring-web from 6.0.0 to 5.3.25 resolves the issue
BUT 5.3.25 has vulnerabilities
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<!-- version>${spring.version}</version !-->
<!-- some issue CommonsMultipartFile is missing starting with v 6.0.0 !-->
<version> version>
</dependency>

As per https://github.com/spring-projects/spring-framework/wiki/Upgrading-to-Spring-Framework-6.x in Spring 6
Several outdated Servlet-based integrations have been dropped: e.g. Apache Commons FileUpload (org.springframework.web.multipart.commons.CommonsMultipartResolver)
...
We recommend org.springframework.web.multipart.support.StandardServletMultipartResolver for multipart file uploads
Obviously CommonsMultipartFile is also gone.
You can remove the commons-fileupload dependency from your project and in your controllers you can use MultipartFile that has almost the same methods as CommonsMultipartFile did, or MultipartHttpServletRequest:
#RestController
class MyController {
#PostMapping(path = "/upload)
public ResponseEntity<SomeResult> upload(... , #RequestPart MultipartFile file1) {
...
}
#PostMapping(path = "/upload2")
public ResponseEntity<SomeResult> upload2(MultipartHttpServletRequest request,
...) {
MultipartFile multipartFile = request.getFile("file1");
InputStream inputStream = multipartFile.getInputStream();
...
}
}

Related

Spring boot - springdoc custom url for swagger-ui

I need to use a specific url for Swagger-ui. I have tried to use the property "springdoc.swagger-ui.path" but it only redirects.
application.propperties:
springdoc.swagger-ui.path=/helloWorld/swagger
Url in browser: http://localhost:8181/helloWorld/swagger
but the url changes to the following when hits enter button:
http://localhost:8181/manager/swagger-ui/index.html?configUrl=/manager/swagger/swagger.json/swagger-config
the question is, how can i make the path be only http://localhost:8181/helloWorld/swagger/index.html or http://localhost:8181/helloWorld/swagger once i've hit enter (I need the word "swagger-ui" and configUrl disappear)?
I`m uisng Springdoc and even tried with springfox
Pom.xml
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.5.2</version>
</dependency>
application.propperties:
springdoc.api-docs.path=/helloWorld/swagger/swagger.json
springdoc.swagger-ui.path=/helloWorld/swagger
I guess it's version dependent regarding the answer.
if you're using 2.8.0 and above, you could use following dependencies:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
And create a controller which will just redirect to the main swagger page, like this:
#Controller
public class SwaggerController {
#RequestMapping("/")
public String index() {
return "redirect:swagger-ui.html";
}
}
But if you use 2.6.1 or like that you can personalize your swagger configuration java class extending WebMvcConfigurerAdapter and overwriting the addViewController, like this:
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addRedirectViewController(MAIN_URL, SWAGGER_UI_URL).setContextRelative(true);
registry.addRedirectViewController(MAIN_URL + "/", SWAGGER_UI_URL).setContextRelative(true);
}
That's it. Both approaches used the same dependencies but with different versions.

SpringBoot with Jakarta Validation Api not validating with #Valid Annotation

i have a question to Spring boot and the dependency jakarta-validation-api.
Actually i have a simple DTO which holds some properties. But this properties are not being validated when I call the REST-function within the #Valid annotation.
Can someone find my error?
A snippet of my pom.mxml dependencies:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.0-M1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
<version>3.0.0</version>
</dependency>
My DTO class:
import jakarta.validation.Valid;
#Data
public class TestDTO implements Serializable {
private static final long serialVersionUID = -1362258531757232654L;
#NotEmpty(message = "Id could not be empty or null.")
#Size(min = 36, max = 36, message = "Id must contains exactly out of 36 characters.")
private String id;
#Min(value = 1, message = "Page size cannot be null or <= 0.")
private Integer page;
}
And also a snippet of the REST-Resource class where the DTO is been used in the body:
#PostMapping(path = "/")
public Integer testValidation(#Valid #RequestBody TestDTO body) {
LOGGER.info(body);
return 1;
}
Actually i would think that when I call the Post-REST method that it will be validated before it will go into the method body, but actually it goes into the method body without has been validated before.
Is it due to "jakarta" dependency instead of "javax"?
Hope you can help me :)
From what I understand in the Spring Boot 3.0.0 M1 Release Notes, Spring Boot 2.X does not support Jakarta EE, but support will come with Spring Boot 3.X.
For Spring Boot 2.X you should stick with javax.
For Spring Boot 3.X you should stick with jakarta.
In my case(spring boot 2.4.*).
I remove jakarta.validation-api dependencies,then it works.
use javax.*
not jakarta.*

Spring Data REST Endpoints Not Generating In Swagger UI

I've implemented a controller using #BasePathAwareController which also takes advantage of Spring Data REST (for finds to expose sort/size etc.)
along with some custom endpoints (for updates etc.). The application is working as expected and the endpoints Spring
Data REST generates are working as expected and I can see the self links appear in the responses, however, i can't see
these endpoints in Swagger UI. I can just see my custom endpoints
defined in my Controller.
According to this post I need to use Swagger 3.0.0-SNAPSHOT with #EnableSwagger2WebMvc
Here's my configurations:
My app.yml:
spring:
data:
rest:
basePath: /api/v1
My POM file:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/>
</parent>
<properties>
<springfox.swagger.version>3.0.0-SNAPSHOT</springfox.swagger.version>
</properties>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox.swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox.swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-data-rest</artifactId>
<version>${springfox.swagger.version}</version>
</dependency>
Swagger Config File:
#Configuration
#Import(SpringDataRestConfiguration.class)
#EnableSwagger2WebMvc
public class SwaggerConfig {
#Bean
public Docket api(ServletContext servletContext) {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("my.package.name"))
.paths(PathSelectors.any())
.build().apiInfo(apiEndPointsInfo());
}
private ApiInfo apiEndPointsInfo() {
return new ApiInfoBuilder().title("My App REST API's")
.description("My App REST API's")
.version("1.0").build();
}
}
My repo:
#RepositoryRestResource(exported=true, collectionResourceRel="group", path="group")
public interface GroupRepository extends JpaRepository<Group, Long>, JpaSpecificationExecutor<Group> {
}
Why can't i see the default endpoints that Spring Data REST produces?
I found the issue to my problem. I wasn't aware that Spring Data REST doesn't expose the generated endpoints under the controller package name I had specified here:
.apis(RequestHandlerSelectors.basePackage("my.package.name"))
so when I changed the above line to:
.apis(RequestHandlerSelectors.any())
and I could see the JPA respository endpoints.

Swagger Apache CXF JAX-RS Maven

I am having trouble using swagger with Apache CXF, JAX-RS services.
beans.xml:
<bean class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer"/>
<bean id="apiListingResourceJSON" class="com.wordnik.swagger.jaxrs.listing.ApiListingResourceJSON"/>
<bean id="apiDeclarationProvider" class="com.wordnik.swagger.jaxrs.listing.ApiDeclarationProvider"/>
Example use:
#Path("/")
#Api(value="/", description="VenturoSoft eMustering Services")
public class Service {
final static Logger logger = Logger.getLogger(Service.class);
#GET
#Path("/echo/{input}")
#Produces(MediaType.TEXT_PLAIN_VALUE)
#Consumes(MediaType.TEXT_PLAIN_VALUE)
#ApiOperation(value = "Get Ping", response = String.class)
public String ping(#PathParam("input") String input) {
return PingImpl.ping(input);
}
Pom.xml:
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-jaxrs_2.10</artifactId>
<version>1.3.12</version>
</dependency>
<dependency>
<groupId>com.mangofactory</groupId>
<artifactId>swagger-springmvc</artifactId>
<version>1.0.2</version>
</dependency>
Run:
mvn tomcat7:run-war
But when I load:
http://localhost:13000/jaxrs-service/api
I get no response.
http://localhost:13000/jaxrs-service/echo/echoSomething
Works as desired.
You're looking at some very old dependencies. From your code, it looks like you're using JAXRS. If that's the case, the latest dependencies should be:
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
<version>1.5.4</version>
</dependency>
Please follow the JAXRS sample here:
https://github.com/swagger-api/swagger-samples/tree/master/java/java-jaxrs-cxf
Which should show you how to correctly configure the server.

Hibernate Validator 5.1.1 is not working in Web application

I am using Spring 4.0 and latest Spring Security in my Web application. I want to use the Hibernate validation 5.1.1 Final. But It's not working. The same code works in my JUNIT but not in the web application.
The code which works:
#Test
public void testUserAuthenticationRequestValidation(){
try{
UserAuthenticationRequest req=new UserAuthenticationRequest().addUserName("bla").addPasswd("passw");
Validator validation=Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<UserAuthenticationRequest>> constraintViolations= validation.validate(req);
Assert.assertTrue("There are some errors", constraintViolations.size()>0);
System.out.println(constraintViolations);
}catch(Exception ex){
ex.printStackTrace();
Assert.fail();
}
But if I try to use the same code in my web application, it doesn't work, In the below code, I am expecting contraintViolation set not to be empty because I intentionally left both the username & password empty but I always find it empty.
#Override
public UserDetails retrieveUser(String username,
UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
LOGGER.debug("About to check authentication for username: {}", username);
final UserAuthenticationRequest userData = new UserAuthenticationRequest()
.addUserName(username).addPasswd(
authentication.getCredentials().toString());
Validator validation = Validation.buildDefaultValidatorFactory()
.getValidator();
Set<ConstraintViolation<UserAuthenticationRequest>> constraintViolations = validation
.validate(userData);
LOGGER.info("Constraints Violations: {}", constraintViolations);
LOGGER.info("Obejct: username: {} password: {}",
userData.getUsername(), userData.getPasswd());
UserDetailVO userDetailVO = new UserDetailVO(
userInfoService.authenticate(userData));
return userDetailVO;
}
So far I have also tried in vain initializing the validation bean as shown below and injecting in my Class as well as shown below:
#Configuration
#ComponentScan({ "com.sell.mystuff.web.security",
"com.sell.mystuff.web.service" })
#ImportResource({ "classpath*:spring/common-context.xml" })
public class CommonAppContext {
#Bean(name = "javaxValidator")
public Validator getValidator() {
return Validation.buildDefaultValidatorFactory().getValidator();
}
}
I have even tried to explicitly initialized in the validation bean as shown above but nothing seems to be working.
Below is my partial POM.xml file related to validation api:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.1.Final</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>5.1.1.Final</version>
</dependency>
Do you have the validator bean configured?
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
This will bootstrap Bean Validation 1.0 or 1.1, depending on which version of Hibernate Validator you have on the classpath. See also http://docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html
Even if you plan to manually call the validation, you should do it by retrieving the configured factory bean, since this will guarantee proper caching of the factory.
I got this working by adding a later version of javax.el
e.g.
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
BTW I didn't need to define a LocalValidatorFactoryBean in my spring mvc config.

Resources