HttpServletRequest can not be cast to MultipartHttpServletRequest - java

I am trying to upload Excel file and print the content of each cell in console. Here is my code ..
JSP :
<c:url value="/my-account/readExcel" var="readExcel" />
<form:form action="${readExcel}" method="post" commandName="excelFileUploadForm" enctype="multipart/form-data">
<form:input id="fineName" path="fileName" type="file" />
<input type="submit" value="Uplaod" />
</form:form>
ExcelFileUploadForm:
public class ExcelFileUploadForm
{
private MultipartFile fileName;
public MultipartFile getFileName()
{
return fileName;
}
public void setFileName(final MultipartFile fileName)
{
this.fileName = fileName;
}
}
Controller :
#RequestMapping(value = "/readExcel", method = RequestMethod.POST)
#RequireHardLogIn
public String readExcel(final HttpServletRequest request, final HttpServletResponse response) throws CMSItemNotFoundException,
IOException
{
final MultipartHttpServletRequest mpr = (MultipartHttpServletRequest) request;
final CommonsMultipartFile file = (CommonsMultipartFile) mpr.getFile("fileName");
read(file);
return "redirect:/my-account";
}
public void read(final CommonsMultipartFile inputFile) throws IOException
{
Workbook w;
try
{
w = Workbook.getWorkbook(inputFile.getInputStream());
// Get the first sheet
final Sheet sheet = w.getSheet(0);
// Loop over first 10 column and lines
for (int j = 0; j < sheet.getColumns(); j++)
{
for (int i = 0; i < sheet.getRows(); i++)
{
final Cell cell = sheet.getCell(j, i);
final CellType type = cell.getType();
if (type == CellType.LABEL)
{
System.out.println("I got a label " + cell.getContents());
}
if (type == CellType.NUMBER)
{
System.out.println("I got a number " + cell.getContents());
}
}
}
}
catch (final BiffException e)
{
e.printStackTrace();
}
}
When I am uploading file through browse button and click on upload. It is giving Casting error
HTTP Status 500 - Request processing failed; nested exception is java.lang.ClassCastException: org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper cannot be cast to org.springframework.web.multipart.MultipartHttpServletRequest
I can't figure out where I am doing wrong. Please help.

Please add Multipart Resolver in your spring config (app config) like below:
<bean id="multiPartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

Related

how to display dynamic images came from dB and showing them in jsp?

I need to display images retrieved from DB into my JSP page, help!
//here is my jsp code line:
<img src="<c:url value="/downloadimage">
<c:param name="id" value="${obj.id}"/>
</c:url>" alt="cant show image!" width="200px" height="200px"/>
//here is my controller method:
#GetMapping("/downloadimage")
public void downloadimage(#RequestParam("id") int id,HttpServletRequest request, HttpServletResponse response) {
byte[] imageBytes = autherService.getImageAsBytes(id);
try {
if(imageBytes != null) {
response.setContentType(
servletContext.getMimeType("name.jpg"));
response.setContentLength(imageBytes.length);
response.getOutputStream().write(imageBytes);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//here is DAO impl class code :
#Override
public byte[] getImageAsBytes(int id) {
String sql = "SELECT image FROM picture_tbl WHERE id = ?";
Object[] args = { id };
Picture picture = jdbcTemplate.queryForObject(sql,args, new PictureRowMapper());
return picture.getImageAsBytes();
}

How to create a list of uploaded files in Spring Boot?

I want to create a list of uploaded files that are stored in a directory on my hard drive.
My Controller:
#Controller
class MyFileUploadController {
#RequestMapping(value = "/uploadOneFile", method = RequestMethod.GET)
public String uploadOneFileHandler(Model model) {
MyUploadForm myUploadForm = new MyUploadForm();
model.addAttribute("myUploadForm", myUploadForm);
return "uploadOneFile";
}
#RequestMapping(value = "/uploadOneFile", method = RequestMethod.POST)
public String uploadOneFileHandlerPOST(HttpServletRequest request, //
Model model, //
#ModelAttribute("myUploadForm") MyUploadForm myUploadForm) {
return this.doUpload(request, model, myUploadForm);
}
#RequestMapping(value = "/uploadMultiFile", method = RequestMethod.GET)
public String uploadMultiFileHandler(Model model) {
MyUploadForm myUploadForm = new MyUploadForm();
model.addAttribute("myUploadForm", myUploadForm);
return "uploadMultiFile";
}
#RequestMapping(value = "/uploadMultiFile", method = RequestMethod.POST)
public String uploadMultiFileHandlerPOST(HttpServletRequest request, //
Model model, //
#ModelAttribute("myUploadForm") MyUploadForm myUploadForm) {
return this.doUpload(request, model, myUploadForm);
}
private String doUpload(HttpServletRequest request, Model model, //
MyUploadForm myUploadForm) {
String description = myUploadForm.getDescription();
System.out.println("Description: " + description);
String uploadRootPath = request.getServletContext().getRealPath("upload");
System.out.println("uploadRootPath=" + uploadRootPath);
File uploadRootDir = new File("(directory)");
if (!uploadRootDir.exists()) {
uploadRootDir.mkdirs();
}
MultipartFile[] fileDatas = myUploadForm.getFileDatas();
List<File> uploadedFiles = new ArrayList<File>();
List<String> failedFiles = new ArrayList<String>();
for (MultipartFile fileData : fileDatas) {
String name = fileData.getOriginalFilename();
System.out.println("Client File Name = " + name);
if (name != null && name.length() > 0) {
try {
File serverFile = new File(uploadRootDir.getAbsolutePath() + File.separator + name);
BufferedOutputStream stream = new BufferedOutputStream(new
FileOutputStream(serverFile));
stream.write(fileData.getBytes());
stream.close();
uploadedFiles.add(serverFile);
System.out.println("Write file: " + serverFile);
} catch (Exception e) {
System.out.println("Error Write file: " + name);
failedFiles.add(name);
}
}
}
model.addAttribute("description", description);
model.addAttribute("uploadedFiles", uploadedFiles);
model.addAttribute("failedFiles", failedFiles);
return "uploadResult";
}
}
MyUploadForm
public class MyUploadForm {
private String description;
private MultipartFile[] fileDatas;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public MultipartFile[] getFileDatas() {
return fileDatas;
}
public void setFileDatas(MultipartFile[] fileDatas) {
this.fileDatas = fileDatas;
}
}
The User can upload his files on the uploadOneFile.html.
uploadOneFile.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:c="http://java.sun.com/xml/ns/javaee">
<head>
<meta charset="UTF-8">
<title>Upload One File</title>
</head>
<body>
<th:block th:include="/_menu"></th:block>
<h3>Upload single file:</h3>
<form th:object="${myUploadForm}" method="POST"
action="" enctype="multipart/form-data">
Beschreibung:
<br>
<input th:field="*{description}" style="width:300px;"/>
<br/><br/>
File to upload: <input th:field="*{fileDatas}" type="file"/>
<br/>
<input type="submit" value="Upload">
</form>
</body>
</html>
The uploaded files should then be displayed on the index page. Aswell it should be possible to download the files with just clicking on them.
I'm a beginner in Spring Boot so can you help me? If you need more informations let it me know.
You can create a table on that page (html layout you can choose as per design etc..)
Main logic can be:-
Get list of file's from the directory.
Have the names of files stored in a SET or LIST or something of your choice.
Pass the previous list onto UI using some model via the index page controller.
Render the list of files.
Upon clicking the particular file, call the endpoint to download file by name.
Some Code of initial interest could be like below:-
File directoryPath = new File("D:\\PATH\\OF\\DIRECTORY");
FileFilter textFilefilter = new FileFilter(){
public boolean accept(File file) {
boolean isFile = file.isFile();
if (isFile) {
return true;
} else {
return false;
}
}
};
//List of all the files (only files)
File filesList[] = directoryPath.listFiles(textFilefilter);
System.out.println("List of the files in the specified directory:");
for(File file : filesList) {
System.out.println("File-name: "+file.getName());
System.out.println("File-path: "+file.getAbsolutePath());
System.out.println("Size: "+file.getTotalSpace());
System.out.println(" ");
}

java.lang.arrayindexoutofboundsexception jsoup

I'm trying to pull all images from a website and
analyze each one using AWS image recognition API. It works for some websites, however some websites return an error saying `500 server error java.lang.arrayindexoutofboundsexception index:281 size 281.
Basically I'm scraping images using jsoup and then creating an object to store the name and image URL for each image. After that, I call the API and check each image in the ArrayList. For some reason it only works for some websites.
Can someone please explain what I'm doing wrong and how to prevent this error?
#WebServlet(name = "HelloAppEngine", urlPatterns = {
"/hello"
})
public class HelloAppEngine extends HttpServlet {
static ArrayList < ResponseData > testImages = new ArrayList < > ();
static AmazonRekognition rekognitionClient = AmazonRekognitionClientBuilder.defaultClient();
public static void getimages() throws MalformedURLException, IOException {
System.out.println("getImages called" + testImages);
int index = 0;
for (ResponseData data: testImages) {
System.err.println("open stream for:" + data.getUrl());
ByteBuffer imageBytes = null;
try (InputStream inputStream = new URL(data.getUrl()).openStream()) {
System.out.println(inputStream);
imageBytes = ByteBuffer.wrap(IOUtils.toByteArray(inputStream));
System.out.println(imageBytes);
} catch (IOException e1) {
System.err.println(e1.getMessage());
}
//
DetectLabelsRequest request = new DetectLabelsRequest().withImage(new Image().withBytes(imageBytes)); //.withMaxLabels(10).withMinConfidence(77F);
try {
DetectLabelsResult result = rekognitionClient.detectLabels(request);
List < Label > labels = result.getLabels();
//System.out.println(labels);
//System.out.println("Detected labels for " + photo+""+labels);
for (Label label: labels) {
//loop through all labels of object
//create new responsedata object for each image
//where im getting error
if (testImages.get(index) != null) {
ResponseData d = testImages.get(index);
d.setName(label.getName());
testImages.set(index, d);
//increment for making new image url and name
index++;
System.out.println(label.getName() + ": " + label.getConfidence().toString());
}
}
//
} catch (AmazonRekognitionException e) {
System.err.println(e.getMessage());
}
}
}
private static final long serialVersionUID = 1 L;
protected static final Gson GSON = new GsonBuilder().create();
// This is just a test array
ArrayList < String > list = new ArrayList < String > ();
#Override
protected final void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/json");
String servlet = req.getServletPath();
System.setProperty("http.proxyHost", "192.168.5.1");
System.setProperty("http.proxyPort", "1080");
log("servlet:" + servlet);
if (servlet.equalsIgnoreCase("/main")) {
log("if body start");
String urlString = java.net.URLDecoder.decode(req.getParameter("url"), "UTF-8");
// Connect to website. This can be replaced with your file loading
// implementation
Document doc = Jsoup.connect(urlString).get();
// Get all img tags
Elements img = doc.getElementsByTag("img");
Elements media = doc.select("[src]");
int counter = 0;
// Loop through img tags
for (Element src: media) {
if (src.tagName().equals("img")) {
counter++;
//create reposnsedata object for each image url
ResponseData data = new ResponseData();
//set object url to image url
data.setUrl(src.attr("abs:src"));
//set data name from aws
data.setName(" ");
testImages.add(data);
// getimages();
}
if (src.tagName().equals("link[href~=.*\\.(ico|png)]")) {
System.out.println("image is logo");
}
if (src.tagName().equals("meta[itemprop=image]")) {
System.out.println("image is logosss");
}
}
}
//log("list" + testImages);
getimages();
//
// getimages();
System.err.println(GSON.toJson(testImages));
resp.getWriter().println(GSON.toJson(testImages));
}
#Override
protected final void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
You're trying to get 282nd image (index=281) from testImages but there's only 281 (index=280). You're getting each image for each label and it's possible there's more labels than images.
Try displaying the amount of both of them:
System.out.println("testImages.size() is: " + testImages.size());
System.out.println("labels.size() is: " + labels.size());
To avoid getting more images than labels try replacing this condition:
if (testImages.get(index) != null) {
with
if (index < testImages.size() && testImages.get(index) != null) {

Google Cloud Storage upload a file using java

I'm creating a web app using Java servlets and JSPs and I want to create an upload form in JSP for my clients to be able to upload and download stuff. I'm using Cloud Storage and my default bucket to upload stuff.
I followed Google's tutorial on Reading and Writing to Google Cloud Storage.
This is my Servlet:
public class Create extends HttpServlet {
public static final boolean SERVE_USING_BLOBSTORE_API = false;
private final GcsService gcsService = GcsServiceFactory.createGcsService(new RetryParams.Builder()
.initialRetryDelayMillis(10)
.retryMaxAttempts(10)
.totalRetryPeriodMillis(15000)
.build());
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
GcsFilename fileName = getFileName(req);
if (SERVE_USING_BLOBSTORE_API) {
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
BlobKey blobKey = blobstoreService.createGsBlobKey(
"/gs/" + fileName.getBucketName() + "/" + fileName.getObjectName());
blobstoreService.serve(blobKey, resp);
} else {
GcsInputChannel readChannel = gcsService.openPrefetchingReadChannel(fileName, 0, BUFFER_SIZE);
copy(Channels.newInputStream(readChannel), resp.getOutputStream());
}
}
#Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
GcsFileOptions instance = GcsFileOptions.getDefaultInstance();
GcsFilename fileName = getFileName(req);
GcsOutputChannel outputChannel;
outputChannel = gcsService.createOrReplace(fileName, instance);
copy(req.getInputStream(), Channels.newOutputStream(outputChannel));
}
private GcsFilename getFileName(HttpServletRequest req) {
String[] splits = req.getRequestURI().split("/", 4);
if (!splits[0].equals("") || !splits[1].equals("gcs")) {
throw new IllegalArgumentException("The URL is not formed as expected. " +
"Expecting /gcs/<bucket>/<object>");
}
return new GcsFilename(splits[2], splits[3]);
}
private void copy(InputStream input, OutputStream output) throws IOException {
try {
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = input.read(buffer);
while (bytesRead != -1) {
output.write(buffer, 0, bytesRead);
bytesRead = input.read(buffer);
}
} finally {
input.close();
output.close();
}
}
}
I can upload and download successfully, but only text and not real files like images, pdfs, etc., which is my problem.
This tutorial is for reading and writing text but i want to upload real files. As you can see from my jsp the enctype is "text/plain":
<form action="/index.html" enctype="text/plain" method="get" name="putFile" id="putFile">
<div>
Bucket: <input type="text" name="bucket" />
File Name: <input type="text" name="fileName" />
<br /> File Contents: <br />
<textarea name="content" id="content" rows="3" cols="60"></textarea>
<br />
<input type="submit" onclick='uploadFile(this)' value="Upload Content" />
</div>
</form>
I tried to change it to "multipart/form-data" and put a
<input name="content" id="content" type="file">
but this does not upload the real file only the fake path of the file.
And I want to know how to upload real files, any help would be appreciated.
Here is one example on how to upload blobs to Cloud Storage:
First you initialize the storage with these lines:
private static Storage storage = null;
// [START init]
static {
storage = StorageOptions.getDefaultInstance().getService();
}
// [END init]
You may change the code to accept different file extensions according to your needs on the getImageUrl method in the line String[] allowedExt = {"jpg", "jpeg", "png", "gif"};
/**
* Extracts the file payload from an HttpServletRequest, checks that the file extension
* is supported and uploads the file to Google Cloud Storage.
*/
public String getImageUrl(HttpServletRequest req, HttpServletResponse resp,
final String bucket) throws IOException, ServletException {
Part filePart = req.getPart("file");
final String fileName = filePart.getSubmittedFileName();
String imageUrl = req.getParameter("imageUrl");
// Check extension of file
if (fileName != null && !fileName.isEmpty() && fileName.contains(".")) {
final String extension = fileName.substring(fileName.lastIndexOf('.') + 1);
String[] allowedExt = {"jpg", "jpeg", "png", "gif"};
for (String s : allowedExt) {
if (extension.equals(s)) {
return this.uploadFile(filePart, bucket);
}
}
throw new ServletException("file must be an image");
}
return imageUrl;
}
Here a timestamp is appended in the filename which can be a good idea if you want to make the filename unique.
/**
* Uploads a file to Google Cloud Storage to the bucket specified in the BUCKET_NAME
* environment variable, appending a timestamp to end of the uploaded filename.
*/
#SuppressWarnings("deprecation")
public String uploadFile(Part filePart, final String bucketName) throws IOException {
DateTimeFormatter dtf = DateTimeFormat.forPattern("-YYYY-MM-dd-HHmmssSSS");
DateTime dt = DateTime.now(DateTimeZone.UTC);
String dtString = dt.toString(dtf);
final String fileName = filePart.getSubmittedFileName() + dtString;
// the inputstream is closed by default, so we don't need to close it here
BlobInfo blobInfo =
storage.create(
BlobInfo
.newBuilder(bucketName, fileName)
// Modify access list to allow all users with link to read file
.setAcl(new ArrayList<>(Arrays.asList(Acl.of(User.ofAllUsers(), Role.READER))))
.build(),
filePart.getInputStream());
// return the public download link
return blobInfo.getMediaLink();
}
In this documentation you'll find more details: https://cloud.google.com/java/getting-started/using-cloud-storage#uploading_blobs_to_cloud_storage
The complete code for this example is in github: https://github.com/GoogleCloudPlatform/getting-started-java/blob/master/bookshelf/3-binary-data/src/main/java/com/example/getstarted/util/CloudStorageHelper.java
I found a solution.
This is my JSP:
<form action="/create" enctype="multipart/form-data" method="post" name="putFile" id="putFile">
<div>
File Name: <input type="text" name="fileName" />
<br /> File Contents: <br />
<input type="submit" value="Upload Content" />
</div>
</form>
When i submit the form, it goes into this Servlet:
#Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
Part filePart = req.getPart("content"); /*Get file from jsp*/
/*Get file name of file from jsp*/
String name = Paths.get(filePart.getSubmittedFileName()).getFileName().toString();
GcsFileOptions instance = GcsFileOptions.getDefaultInstance();
GcsFilename fileName = new GcsFilename(BUCKET_NAME, name);
GcsOutputChannel outputChannel;
outputChannel = gcsService.createOrReplace(fileName, instance);
/*Pass the file to copy function, wich uploads the file to cloud*/
copy(filePart.getInputStream(), Channels.newOutputStream(outputChannel));
req.getRequestDispatcher("download.jsp").forward(req, resp);
}
private GcsFilename getFileName(HttpServletRequest req) {
String[] splits = req.getRequestURI().split("/", 4);
if (!splits[0].equals("") || !splits[1].equals("gcs")) {
throw new IllegalArgumentException("The URL is not formed as expected. " +
"Expecting /gcs/<bucket>/<object>");
}
return new GcsFilename(splits[2], splits[3]);
}
private void copy(InputStream input, OutputStream output) throws IOException {
try {
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = input.read(buffer);
while (bytesRead != -1) {
output.write(buffer, 0, bytesRead);
bytesRead = input.read(buffer);
}
} finally {
input.close();
output.close();
}
}

How to get a excel file from request?

I am uploading an excel file from one jsp page. below is the code.
<form action="Upload.jsp" enctype="MULTIPART/FORM-DATA" method=post >
<input type="file" name="filename" />
<input type="submit" value="Upload" />
</form>
But how to get the excel file in the next page(Upload.jsp)?
I was using but getting error in the second line.
InputStream file = request.getInputStream();
POIFSFileSystem myFileSystem = new POIFSFileSystem(file );
Then how to get the excel file from the request?
You are getting a Multipart/form-data on the request from which you need to extract the Part containing your file bytes.
The simplest to do this is to use Apache Commons Fileupload
http://commons.apache.org/fileupload/
Create a FileUploader
import org.apache.commons.fileupload.disk.*;
import org.apache.commons.fileupload.servlet.;
import java.io.;
public class FileUploader
{
private static ServletFileUpload uploader;
private FileUploader()
{
}
public static synchronized ServletFileUpload getservletFileUploader(String tempDir, int maxSizeInMB)
{
if(uploader == null)
{
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(1024 * 1024);
factory.setRepository(new File(tempDir));
uploader = new ServletFileUpload(factory);
uploader.setFileSizeMax(maxSizeInMB * 1024 * 1024);
}
return uploader;
}
}
Then use it when processing the request
protected MultiPartFormData handleMultiPartRequest(HttpServletRequest request)
throws FileSizeLimitExceededException
{
if(!isMultipartRequest(request))
return null;
ServletFileUpload upload = FileUploader.getservletFileUploader(tempDir, 50);
MultiPartFormData data = new MultiPartFormData();
try
{
List<FileItem> items = upload.parseRequest(request);
for (FileItem item : items)
{
if(item.isFormField())
{
data.getParameters().put(item.getFieldName(), item.getString());
}
else
{
String filename = item.getName();
//Internet explorer and firefox will send the file name differently
//Internet explorer will send the entire path to the file name including
//the backslash characters etc ... we should strip it down
//THIS IS HACKY
if(filename.indexOf("\\") != -1)
{
int index = filename.lastIndexOf("\\");
filename = filename.substring(index + 1);
}
if(filename == null || filename.equals(""))
{
//do nothing
}
else
{
String randomFileName = (new RandomGUID()).toString() + getFileExtension(filename);
File uploadFile = new File(uploadDir + File.separator + randomFileName);
item.write(uploadFile);
}
}
}
}
catch(FileSizeLimitExceededException e)
{
throw e;
}
catch(Exception e)
{
e.printStackTrace();
}
return data;
}
For your reference ... MultiPartForm data looks like
import java.util.Hashtable;
import java.util.ArrayList;
public class MultiPartFormData {
private ArrayList<Integer> fids;
private Hashtable<String, String> parameters;
public MultiPartFormData()
{
this.fids = new ArrayList<Integer>();
this.parameters = new Hashtable<String, String>();
}
public ArrayList<Integer> getFids() {
return fids;
}
public void setFids(ArrayList<Integer> fids) {
this.fids = fids;
}
public Hashtable<String, String> getParameters() {
return parameters;
}
public void setParameters(Hashtable<String, String> parameters) {
this.parameters = parameters;
}
}
Well guys, thanks for all the reply. But I have resolved the problem with below process.
Inside JSP:
<form action="/upload.do" enctype="MULTIPART/FORM-DATA" method=post >
<input type="file" name="file" id="file" size=25/>
<input type="submit" value="Upload" />
</form>
Created a form bean: inside that
private FormFile file;
public void setFile(FormFile file) {
this.file = file;
}
public FormFile getFile() {
return file;
}
In action class upload:
FileUploadForm uploadForm = (FileUploadForm) form;
FormFile file = uploadForm.getFile();
InputStream stream = file.getInputStream();
POIFSFileSystem fsFileSystem = new POIFSFileSystem(stream);
//
rest of code for reading the excel
//
Now its working fine.

Categories