I'm facing an issue when I deploy my application on server side (on local machine everything works fine). In my application, a user can use multiupload for uploading files. Here is my controller:
#Controller
public class FileUploadController {
#Autowired
private StoryService storyService;
#Autowired
private PhotoService photoService;
#RequestMapping("/uploader")
public String home() {
// will be resolved to /views/fileUploader.jsp
return "admin/fileUploader";
}
#RequestMapping(value = "/admin/story/upload", method = RequestMethod.POST)
public #ResponseBody
String upload(MultipartHttpServletRequest request,
HttpServletResponse response, HttpServletRequest req) throws IOException {
//get story id
Integer story_id = Integer.valueOf(req.getParameter("story_id"));
Story story = storyService.findById(story_id);
// Getting uploaded files from the request object
Map<String, MultipartFile> fileMap = request.getFileMap();
// Iterate through the map
for (MultipartFile multipartFile : fileMap.values()) {
// Save the file to local disk
String name = Long.toString(System.currentTimeMillis());
//original size
saveFileToLocalDisk(multipartFile, name + ".jpg");
//medium size
Thumbnails.of(convertMultifileToFile(multipartFile)).size(1800, 2400)
.toFile(new File(getDestinationLocation() + "medium_" + name));
//thumbnail size
Thumbnails.of(convertMultifileToFile(multipartFile)).size(600, 800)
.toFile(new File(getDestinationLocation() + "thumb_" + name));
//Save to db
savePhoto(multipartFile, name, story);
}
return "redirect:/admin";
}
private void saveFileToLocalDisk(MultipartFile multipartFile, String name)
throws IOException, FileNotFoundException {
FileCopyUtils.copy(multipartFile.getBytes(), new FileOutputStream(getDestinationLocation() +
name));
}
private String getOutputFilename(MultipartFile multipartFile) {
return getDestinationLocation() + multipartFile.getOriginalFilename();
}
private Photo savePhoto(MultipartFile multipartFile, String name, Story story)
throws IOException {
Photo photo = new Photo();
if (story != null) {
photo.setName(name);
photo.setStory(story);
photoService.addPhoto(photo);
}
return photo;
}
private String getDestinationLocation() {
return "/var/www/static/images/";
}
public File convertMultifileToFile(MultipartFile file) throws IOException
{
File convFile = new File(file.getOriginalFilename());
convFile.createNewFile();
FileOutputStream fos = new FileOutputStream(convFile);
fos.write(file.getBytes());
fos.close();
return convFile;
}
}
When I try to upload images on the server, I'm getting following exception:
SEVERE: Servlet.service() for servlet [mvc-dispatcher] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NumberFormatException: For input string: ""] with root cause
java.lang.NumberFormatException: For input string: ""
Can't figure out what it means and how to solve it. By the way, I've noticed that when I upload files which are 100-200 KB everything is ok, when files are 4-5 MB I get exception.
Thanks in advance!
It appears that "story_id" is not always set; correlation with the file size may or may not be a coincidence.
You should protect your code from client-side errors like this by treating the "story_id" parameter as optional. This is a good idea for all request parameters, because it prevents your server side from crashing on improperly formed requests:
String storyIdStr = req.getParameter("story_id");
if (storyIdStr == null || storyIdStr.length() == 0) {
// Deal with the error
}
Integer story_id = null;
try {
story_id = Integer.valueOf(storyIdStr);
} catch (NumberFormatException nfe) {
// Deal with the error
}
Integer.valueOf(req.getParameter("story_id")); will give you this exception if req.getParameter("story_id") returns an empty String, since an empty String can't be parsed as an Integer.
Related
Good afternoon.
I can't get the browser to download the file from the server. I took the code from a previous project and it doesn't work. Please explain why.
On the server, files are collected in a zip archive. It is necessary to download the archive. I am using this:
My controller
#SneakyThrows
#GetMapping("/report/UploadDocuments")
#ResponseBody
public ResponseEntity<InputStreamResource> uploadDocuments(HttpServletResponse response,
#RequestParam("check") String check){
deleteAllFilesFolder(Directories.DYRECTORY_EXPORT);
ArrayList<Long> idDocuments = Converter.arrayStringInLong(check);
List<PaymentOrderArchive> documents = paymentOrderArchiveService.findAllById(idDocuments);
for (PaymentOrderArchive p : documents){
UploadingFiles.dowloadFileInDirectory(p);
}
//"method" create zip-file and return path
String s = method(documents);
//Problem here
UploadingFiles up = new UploadingFiles();
return up.downloadFile1(servletContext);
}
My method for dowload
public ResponseEntity<InputStreamResource> downloadFile1(ServletContext servletContext) throws IOException {
MediaType mediaType = MediaTypeUtils.getMediaTypeForFileName(servletContext, Directories.NAME_ZIP);
File file = new File(Directories.DYRECTORY_EXPORT + Directories.NAME_ZIP);
InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
return ResponseEntity.ok()
// Content-Disposition
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + Directories.NAME_ZIP)
// Content-Type
.contentType(mediaType)
// Contet-Length
.body(resource);
}
public class MediaTypeUtils {
public static MediaType getMediaTypeForFileName(ServletContext servletContext, String
fileName) {
String mineType = servletContext.getMimeType(fileName);
try {
MediaType mediaType = MediaType.parseMediaType(mineType);
return mediaType;
} catch (Exception e) {
return MediaType.APPLICATION_OCTET_STREAM;
}
}
Everything is working. The program does not give errors. But the file is not downloading. And I can't understand why.
When I use the #RequestBody annotation, it throws an exception. So I had to use #RequestParam, but it works only for 1 parameter, but it's inconvenient if I have more files. I need an annotation that solves it.
#PostMapping("/products/{id}/img")
public void setProductImgs(#PathVariable Long id, #RequestParam(name = "img") MultipartFile fd) throws IOException {
String dir = "C:\\Projects\\JavaProjects\\project\\src\\main\\resources\\static\\img\\product-" + id + "\\";
File directory = new File(dir);
if(directory.exists())
FileUtils.cleanDirectory(directory);
else
directory.mkdir();
String type = fd.getOriginalFilename().split("\\.")[1];
fd.transferTo(new File(dir + "0." + type));
}
I have a question that makes my head ache.
First, my project structure looks like below.
I made a controller, which returns image(*.png) file to the appropriate request.
The code of controller is written below.
#Controller
public class ImageController {
#GetMapping(value = "/ImageStore.do", produces = MediaType.IMAGE_PNG_VALUE)
public #ResponseBody byte[] getStoreImage(HttpServletRequest request) throws IOException {
String image_name = request.getParameter("image_name");
Resource resource = null;
try {
resource = new ClassPathResource("/images/stores/" + image_name);
if(resource == null) {
throw new NullPointerException();
}
} catch(NullPointerException e) {
resource = new ClassPathResource("/images/stores/noimage.png");
}
InputStream inputStream = resource.getInputStream();
return IOUtils.toByteArray(inputStream);
}
}
Q1. I added try-catch phrase to send noimage.png if the request parameter is wrong, or if the filename of request parameter image_name does not exist. But it doesn't seem to work, and it gives me log saying
class path resource [images/stores/noima.png] cannot be opened because it does not exist
(If you need to know the full stack trace, I will comment below.)
Q2. I have 2 image files, hello.png and noimage.png in the folder /resources/images/stores/. I can read noimage.png correctly, but if I make request localhost:8080/ImageStore.do?image_name=hello.png, then it makes an error, making the same log in Q1.
There's no reason to think that the constructor would result in a null value.
The exception you are getting is likely from the getInputStream method, which is documented to throw
FileNotFoundException - if the underlying resource doesn't exist
IOException - if the content stream could not be opened
A slight adjustment might help
#Controller
public class ImageController {
#GetMapping(value = "/ImageStore.do", produces = MediaType.IMAGE_PNG_VALUE)
public #ResponseBody byte[] getStoreImage(HttpServletRequest request) throws IOException {
InputStream is = null;
try {
String image_name = request.getParameter("image_name");
is = new ClassPathResource("/images/stores/" + image_name).getInputStream();
} catch(FileNotFoundException e) {
is = new ClassPathResource("/images/stores/noimage.png").getInputStream();
}
return IOUtils.toByteArray(is);
}
}
You should include the stack trace, and exception message, which might assist understanding your second query, but I would check that the file really does exist, with the exact name you're using.
I am trying to create a file in hdfs using webhdfs. Kerberos is used for security on cluster, so I use KerberosRestTemplate.
In my controller I have 2 methods
#RequestMapping("/showFileContent")
public ResponseEntity<String> showContent() throws URISyntaxException {
return new ResponseEntity<>(taxonService.getTaxonJSON(), HttpStatus.OK);
}
#RequestMapping("/createFile")
public ResponseEntity<URI> createFile() throws URISyntaxException {
return new ResponseEntity<>(taxonService.createFile(), HttpStatus.OK);
}
And in my service class I have
public String getTaxonJSON() throws URISyntaxException {
URI uri = new URI(path + "?op=OPEN");
String json = restTemplate.getForObject(uri, String.class);
return json;
}
public URI createFile() throws URISyntaxException {
URI uri = new URI(path + "?op=CREATE");
return restTemplate.postForLocation(uri, String.class);
}
I can see file content just fine using /showFileContent, but every time I try /createFile, I get Error running rest call; nested exception is org.springframework.web.client.HttpServerErrorException: 500 Internal Server Error. I remove the file before calling create.
What is the reason for the error?
I managed to write to a file, not create one. This is enough for my needs and might help someone else, so I'll post it here.
public boolean writeFile(File file) throws URISyntaxException {
URI uri = new URI(path + "?op=CREATE" + "&overwrite=true&data=true");
ResponseEntity e =kerberosRestTemplate.exchange(uri, HttpMethod.PUT, new HttpEntity<Resource>(new FileSystemResource(file)), Map.class);
return e.getStatusCodeValue() == 201;
}
We have one screen/page in our application where we are showing different columns for different products. These all records in the columns are fetched from database.
Also, We have two export buttons at the bottom of the screen which is meant for showing all those records in the PDF and XLS format.
These functionalities are working fine except under one condition. We have one column name in the screen whose values are fetched from database. when any record under name column has & in it, the export functionality stopped working.
For example :-
for name "BOWOG BEHEER B.V.", the export is working fine for both pdf and xls.
But for the name "BOWOG & BEHEER B.V.", it stopped working. While clicking on export button, pdf and xls is showing as blank page.
Could anyone please help ?
Below is the piece of codes :- (not full code)
public class CVRExportServlet extends HttpServlet {
private final SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy");
/** context. */
private ResourceContext context = null;
private Map createParametersFromRequest(final HttpServletRequest request) {
// copy all request parameters
final Map parameters = new HashMap();
final Enumeration names = request.getParameterNames();
while (names.hasMoreElements()) {
final String name = (String) names.nextElement();
final String[] values = request.getParameterValues(name);
if (values.length > 1) {
parameters.put(name, values);
} else {
parameters.put(name, values[0]);
}
}
// parse request uri to get type and format
final String requestURI = request.getRequestURI();
String type = StringUtils.left(requestURI, requestURI.lastIndexOf('.'));
type = StringUtils.substring(type, requestURI.lastIndexOf('/') + 1);
final String format = StringUtils.substring(requestURI, requestURI.lastIndexOf('.') + 1);
parameters.put(Constants.EXPORT_TYPE_PARAMETER, type);
parameters.put(Constants.EXPORT_FORMAT_PARAMETER, format);
// determine themeUrl
final String requestUrl = request.getRequestURL().toString();
final int index = requestUrl.indexOf(request.getContextPath());
String server = "";
if (index > -1) {
server = requestUrl.substring(0, index);
}
private void fillParameters(final HttpServletRequest request, final HttpServletResponse response, final Map parameters)
throws ApplicationException {
parameters.put("props", ResourceBundle.getBundle("messages"));
// Create search request using the search form
final SearchForm form = (SearchForm) request.getSession().getAttribute(
(String) request.getSession().getAttribute(CvrConstants.SESS_ATTR_CVR_SEARCH_FORM_NAME));
final SearchRequest searchRequest = form.getSearchRequest();
searchRequest.setPageNumber(1);
searchRequest.setRowsPerPage(10000);
parameters.put("searchRequest", searchRequest);
}
public void service(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException, IOException {
final long startTime = System.currentTimeMillis();
// create parameters from request
final Map parameters = this.createParametersFromRequest(request);
parameters.put(ResourceContext.class.getName(), this.context);
try {
this.fillParameters(request, response, parameters);
final SearchRequest searchRequest = (SearchRequest) parameters.get("searchRequest");
if (searchRequest == null || searchRequest.getCounterPartyList() == null
|| searchRequest.getCounterPartyList().isEmpty()) {
throw new ExportException("Exception occurred while handling export: empty counterparty list");
} else {
if (searchRequest.getCounterPartyList().size() == 1) {
this.handleSingleReportExport(response, parameters);
} else {
this.handleMutlipleReportExport(response, parameters);
}
}
} catch (final Exception e) {
this.handleException(e, request, response);
}
}
private void handleSingleReportExport(final HttpServletResponse response, final Map parameters) throws Exception {
final XmlExportService exportService = this.getXmlExportService();
final ApplicationContext context = this.getApplicationContext();
final XmlTransformationService xmlTransformationService = (XmlTransformationService) context.getBean("transformationService");
// perform export
exportService.export(parameters);
// perform transformation
final ExportResult exportResult = xmlTransformationService.transform(parameters);
// write result to stream
response.setContentType(exportResult.getContentType());
response.setContentLength(exportResult.getContentLength());
if (parameters.get("format").equals("csv")) {
response.setContentType("text/csv");
response.setHeader("Content-disposition", "attachment; filename=export.csv");
} else if (parameters.get("format").equals("pdf")) {
response.setContentType("application/pdf");
response.setHeader("Content-disposition", "inline; filename=export.pdf");
}
final ServletOutputStream out = response.getOutputStream();
out.write(exportResult.getBytes());
out.flush();
out.close();
}
private void handleMutlipleReportExport(final HttpServletResponse response, final Map parameters) throws Exception {
final SearchRequest searchRequest = (SearchRequest) parameters.get("searchRequest");
response.setContentType("application/force-download");
response.setHeader("Content-Encoding" , "x-compress");
response.setHeader("Content-Disposition", "attachment; filename=export_" + parameters.get("format") + ".zip");
final XmlExportService exportService = this.getXmlExportService();
final ApplicationContext context = this.getApplicationContext();
final XmlTransformationService xmlTransformationService = (XmlTransformationService) context.getBean("transformationService");
// start the zip process
final ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
// create a file for each counterparty and add it to the zip file
for (final String counterPartyId : searchRequest.getCounterPartyList()) {
// make sure to reset the counterparty to the current one in the loop
searchRequest.setCounterPartyList(Arrays.asList(new String[] {counterPartyId}));
// perform export
exportService.export(parameters);
// perform transformation
final ExportResult exportResult = xmlTransformationService.transform(parameters);
// add the file to the zip
final String fileName = counterPartyId + "_" + sdf.format(searchRequest.getRevaluationDate()) + "." + parameters.get("format");
zos.putNextEntry(new ZipEntry(fileName));
zos.write(exportResult.getBytes());
zos.closeEntry();
}
// finish the zip process
zos.flush();
zos.close();
}
I have some idea now. actually the issue is there at vm (velocity template). The "name" column is fetched from vm file and code is something like this :-
$!{result.counterpartyName}
This is in for each loop for multiple records. Could anyone please suggest how can i ignore special characters in the vm file itself. so that we will be able to export correctly even if "name" column has "&" or "-" etc special characters.
It seems based on your code that you are using an XML transformation service.
I'd say it's probably your data in your parameters containing dangling & sign. To be valid XML ready for transformation, & should be &. However, based on the code given it is not possible to say where the XML data is coming from. You say it's coming from the database, so my guess is that the problem should be dealt with by modifying the data in the database.
Edit:
It seems I was partly right, but the database doesn't contain the XML - if I got this correctly, data is coming from database as raw tabular data, but is formatted to XML using velocity templates. If that's it, then XML escaping should be used in velocity template like this.