Read file into spring controller. Using relative path - java

i want to read file from controller like this:
#Controller
public class HomeController {
#RequestMapping(value = {"/"}, method = RequestMethod.GET)
public String showHomePage(ModelMap model) throws IOException, SAXException, ParserConfigurationException {
List<User> users = XmlParser.parse("Sum_and_clients.xml");
return "home";
}
But when I start the server it wants download it from apache-tomcat\bin. Despite the fact that Sum_and_clients.xml is located near the HomeController.java. How change this absoulte tomcat path, to path in my project?

I solved my problem.
URL url = HomeController.class.getResource("Sum_and_clients.xml");
File file = new File(url.getPath())
This file should be placed into [{Your project name}\target\ {Your project name} \WEB-INF\classes\ {Your package to HomeController}

Related

Spring API return a file rather than String

I have the code below as an api endpoint. I want the json string to be displayed on browser when I access the endpoint.
However, when I access the endpoint, a file is downloaded. The file named api.json contains {"key": "myKey"}. I have no idea why it generates a file. Can I get some help?
Thanks!
#GetMapping(path="/getFields2", produces=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity getFieldssec(#Context HttpServletRequest httpServletRequest)
{
return ResponseEntity.ok("{\"key\": \"myKey\"}");
}
You can create a Spring Resource and return it
#GetMapping(path="/getFields2", produces=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Resource> getFieldssec(
#Context HttpServletRequest httpServletRequest) {
String text="{\"key\": \"myKey\"}";
Resource resource = new ByteArrayResource(text.getBytes());
return ResponseEntity.ok()
.contentLength(text.length())
.contentType(MediaType.APPLICATION_JSON)
.body(resource);
}

SpringBoot + Postman #RequestMapping value = "getImage/{imageName:.+}"

I an creating an endpoint with spring boot...i can upload image to folder and save it via postman everythink works good.
i have a problem with get method when i am adding the value #RequestMapping value = "getImage/{imageName:.+}" in postman i add http://localhost:8080/api/images/getImage/{burger+png}
is that corect ???
#RequestMapping(value = "api/images")
public class ImageController {
#Autowired
public ImageService imageService;
#PostMapping(value ="upload")
public ResponseEntity uploadImage(#RequestParam MultipartFile file){
return this.imageService.uploadToLocalFileSystem(file);
}
#GetMapping(
value = "getImage/{imageName:.+}",
produces = {MediaType.IMAGE_JPEG_VALUE,MediaType.IMAGE_GIF_VALUE,MediaType.IMAGE_PNG_VALUE}
)
public #ResponseBody byte[] getImageWithMediaType(#PathVariable(name = "imageName") String fileName) throws IOException {
return this.imageService.getImageWithMediaType(fileName);
}
}
what should be the correct request url ???
It seems like it's reaching the backend fine, but failing to find path. Usually API endpoints end with parameters with a slug or query param. You can try either of the following to see if it works:
http://localhost:8080/api/images/getImage/burger.png
http://localhost:8080/api/images/getImage?imageName=burger.png
Keep in mind, you want to make sure that file exists at the path it's mentioning at the very top of the trace in the JSON response. This may depend on how you uploaded the file and with what name.

Spring MVC test Mulitple file upload

I have controller, which handles multiple file upload:
#PostMapping("/import")
public void import(#RequestParam("files") MultipartFile[] files, HttpServletRequest request) {
assertUploadFilesNotEmpty(files);
...
}
And I want to test it
#Test
public void importTest() throws Exception {
MockMultipartFile file = new MockMultipartFile("file", "list.xlsx", MIME_TYPE_EXCEL, Files.readAllBytes(Paths.get(excelFile.getURI())));
mvc.perform(fileUpload("/import").file(file).contentType(MIME_TYPE_EXCEL)).andExpect(status().isOk());
}
Problem is that MockMvc, creates MockHttpRequest with multipartFiles as a name for param that holds uploaded files. And my controller expects those files will be in 'files' param.
Is it possible to tell spring that multiple files should be passed in request under given name?
Create two MockMultiPartFile instances with name files
Complete working example with added Json request body as well as multiple files below :
#PostMapping(consumes=MediaType.MULTIPART_FORM_DATA_VALUE)
public void addProduct(#RequestPart(value="addProductRequest") #Valid AddUpdateProductRequest request,
#RequestPart(value = "files") final List<MultipartFile> files) throws Exception{
request.setProductImages(files);
productService.createProduct(request);
}
#Test
public void testUpdateProduct() throws Exception {
AddUpdateProductRequest addProductRequest = prepareAddUpdateRequest();
final InputStream inputStreamFirstImage = Thread.currentThread().getContextClassLoader().getResourceAsStream("test_image.png");
final InputStream inputStreamSecondImage = Thread.currentThread().getContextClassLoader().getResourceAsStream("test_image2.png");
MockMultipartFile jsonBody = new MockMultipartFile("addProductRequest", "", "application/json", JsonUtils.toJson(addProductRequest).getBytes());
MockMultipartFile file1 = new MockMultipartFile("files", "test_image.png", "image/png", inputStreamFirstImage);
MockMultipartFile file2 = new MockMultipartFile("files", "test_image2.png", "image/png", inputStreamSecondImage);
ResultMatcher ok = MockMvcResultMatchers.status().isOk();
mockMvc.perform(MockMvcRequestBuilders.fileUpload("/add-product")
.file(file1)
.file(file2)
.file(jsonBody)
.contentType(MediaType.MULTIPART_FORM_DATA_VALUE))
.andDo(MockMvcResultHandlers.log())
.andExpect(ok)
.andExpect(content().string("success"));
}

Spring: refering the resources/static folder

I am developing a Rest API using Spring Boot and AngularJS in the client side, i am uploading files to /resources/static/upload with Spring using the RestController below and using them in the client side
#RestController
#CrossOrigin("*")
public class FilmController {
#Autowired
private FilmRepository filmRepository;
#RequestMapping(value = "/films", method = RequestMethod.POST)
public void saveFilm(#RequestParam("file") MultipartFile file) throws Exception {
File convFile = new File("src/main/resources/static/upload/"+file.getOriginalFilename());
convFile.createNewFile();
FileOutputStream fos = new FileOutputStream(convFile);
Blob blob = new SerialBlob(file.getBytes());
fos.write(file.getBytes());
fos.close();
System.out.println(convFile.getName());
filmRepository.save(new Film(convFile.getName(), blob));
}
#RequestMapping(value = "/films", method = RequestMethod.GET)
public List<Film> getAllFilms() {
return filmRepository.findAll();
}
}
Here is how i accessed the uploaded image "image.jpg"
<img src="http://localhost:8080/upload/image.jpg" />
But, when i ran mvn package and i launch my application jar file, i can't access the uploaded image in the client side, i get 404 not found.
Can someone explain how Spring store and refer to static resources and how can i resolve this problem.
I'm using absolute path to the directory and this works in both cases: when it's runing with mvn spring-boot:run and when it's running as java -jar app.jar.
For example, you could try to save uploads to /opt/upload (make sure that it exists and user has permissions to write into it):
File convFile = new File("/opt/upload/"+file.getOriginalFilename());
Also you should configure Spring to serve uploads from this directory:
#Configuration
#EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/upload/**")
.addResourceLocations("file:/opt/upload/");
}
}
More info about configuring resource handler: http://www.baeldung.com/spring-mvc-static-resources
First of all you cannot store in the folder structure you see in your IDE that is not how your code will be in a deployed package
File convFile = new File("src/main/resources/static/upload/"+file.getOriginalFilename());
store using relative path
File convFile = new File("/static/upload/"+file.getOriginalFilename());
and also add the resource location mapping in spring config for your image upload folder .
<mvc:resources mapping="/upload/**" location="/static/upload/" />

Does anyone encounter unuseful rootpath in resteasy

I'm using RESTEasy to write a example of WebService, and set the root resource path.But I find that even no root path in the url, I still can get the right resource.
Main function Code:
NettyJaxrsServer netty = new NettyJaxrsServer();
ResteasyDeployment deploy = new ResteasyDeployment();
List<Object> resources = new ArrayList<Object>();
resources.add(new UserService());
deploy.setResources(resources);
netty.setDeployment(deploy);
netty.setPort(8180);
netty.setRootResourcePath("/hello/");
netty.setSecurityDomain(null);
netty.start();
Service Code:
#Path("user")
#Produces(MediaType.APPLICATION_JSON)
public class UserService {
For the code, url /user can work normal, no need to add root path of /hello. I checked the source code; it adds the root path by itself.
source code:
public static String getEncodedPathInfo(String path, String contextPath)
{
if(contextPath != null && !"".equals(contextPath) && path.startsWith(contextPath))
path = path.substring(contextPath.length());
return path;
}
My question is why RESTEasy do this? I can't understand.

Categories

Resources