Spring-MVC 3.0 Controller error: HTTP Status 400 - spring-mvc

since my application is on the Spring-MVC 3.0 framework, what is the problem of below controller that getting the "Http Status 400" error?
package com.maskkk.controller;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
#Controller
public class FileDownloadController
{
#RequestMapping(value="/spring/download")
public void downloadPDFResource( HttpServletRequest request,
HttpServletResponse response,
#PathVariable("fileName") String fileName
)
{
//If user is not authorized - he should be thrown out from here itself
//Authorized user will download the file
//String dataDirectory = request.getServletContext().getRealPath("/WEB-
INF/downloads/pdf/");
String dataDirectory =
request.getServletContext().getRealPath("fileupload");
Path file = Paths.get(dataDirectory, fileName);
if (Files.exists(file))
{
response.setContentType("application/pdf");
response.addHeader("Content-Disposition", "attachment;
filename="+fileName);
try
{
Files.copy(file, response.getOutputStream());
response.getOutputStream().flush();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
And my web.xml is below:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<welcome-file-list>
<welcome-file>dashboard.jsp</welcome-file>
<welcome-file>form.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- log4j2-begin -->
<listener>
<listener-
class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-
class>
</listener>
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-
class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<!-- log4j2-end -->
<!-- 编码处理过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-
class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-
class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<!-- 这里的servlet-name和上面的要一致. -->
<servlet-name>spring</servlet-name>
<!-- 这里就是url的匹配规则, / 就是匹配所有 -->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
The above controller is for downloading the file from the web site. And this controller is not active when I type the "http://localhost:8888/Upload/spring/download.do" on the url and press enter.
So, what is the problem?
Any suggestions would be very appreciated!

You specify a path variable in your Spring MVC code with #PathVariable("fileName") String fileName and you should resolve this when you call your endpoint. The structure of your endpoint should look the following /../spring/download/{fileName} where the {fileName} replaces a variable in your URL. A valid URL could look like the following: http://localhost:8888/Upload/spring/download/yourFileName. Change the endpoint method to the following if you need this path variable:
#RequestMapping(value="/Upload/spring/download/{fileName}")
public void downloadPDFResource( HttpServletRequest request, HttpServletResponse response, #PathVariable("fileName") String fileName) {
// do your logic
}

Related

HTTP Status 405 – Method Not Allowed in Apache Tomcat Server [duplicate]

This question already has answers here:
HTTP Status 405 - HTTP method is not supported by this URL
(2 answers)
Closed 1 year ago.
I am encountering HTTP Status 405 – Method Not Allowed error in my Java Backend.
I am using Apache Tomcat Server
Type Status Report
Message HTTP method GET is not supported by this URL
Description The method received in the request-line is known by the origin server but not supported by the target resource.
Here is the screenshot:
My Web.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>Backend</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>http://localhost:3000</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>BatchDisplay</servlet-name>
<servlet-class>com.hello.BatchDisplay</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BatchDisplay</servlet-name>
<url-pattern>/BatchDisplay.do</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>AddServlet</servlet-name>
<servlet-class>com.hello.AddServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AddServlet</servlet-name>
<url-pattern>/AddServlet.do</url-pattern>
</servlet-mapping>
</web-app>
When I am executing Post request from Postman, I am getting this error.
My Java backend code:
package com.hello;
import java.io.*;
import java.sql.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class AddServelet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request,HttpServletRequest response) throws ServletException
{
try {
String custNumber=request.getParameter("cust_number");
String nameCustomer=request.getParameter("name_customer");
String invoiceID=request.getParameter("invoice_id");
Double TotalOpenAmount=Double.parseDouble(request.getParameter("total_open_amount"));
String dueinDATE=request.getParameter("due_in_date");
String Notes=request.getParameter("notes");
System.out.print("Acquiring Connection");
Connection connection = DriverManager.getConnection("com.mysql.jdbc.Driver", "root", "abcd");
System.out.print("Connected Successfully");
String sql="INSERT INTO invoice
invoice_details(cust_number,name_customer,invoice_id,total_open_amount,due_in_date,notes)
VALUES (?,?,?,?,?,?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, nameCustomer);
statement.setString(2, custNumber);
statement.setString(3, invoiceID);
statement.setDouble(4, TotalOpenAmount);
statement.setString(5, dueinDATE);
statement.setString(6, Notes);
statement.executeUpdate();
}
catch(SQLException e){
e.printStackTrace();
}
finally
{
}
}
}
I really don't know why is it giving such an error.
Please suggest me a way to debug it.
You need to override doGet method if u wanna call by GET method;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String custNumber=request.getParameter("cust_number");
String nameCustomer=request.getParameter("name_customer");
String invoiceID=request.getParameter("invoice_id");
Double TotalOpenAmount=Double.parseDouble(request.getParameter("total_open_amount"));
String dueinDATE=request.getParameter("due_in_date");
String Notes=request.getParameter("notes");
System.out.print("Acquiring Connection");
Connection connection = DriverManager.getConnection("com.mysql.jdbc.Driver", "root", "abcd");
System.out.print("Connected Successfully");
String sql="INSERT INTO invoice
invoice_details(cust_number,name_customer,invoice_id,total_open_amount,due_in_date,notes)
VALUES (?,?,?,?,?,?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, nameCustomer);
statement.setString(2, custNumber);
statement.setString(3, invoiceID);
statement.setDouble(4, TotalOpenAmount);
statement.setString(5, dueinDATE);
statement.setString(6, Notes);
statement.executeUpdate();
}
catch(SQLException e){
e.printStackTrace();
}
finally
{
}
}
When you need to use GET method: override doGet(HttpServletRequest request, HttpServletResponse response), POST- doPost(HttpServletRequest request, HttpServletResponse response), both - doGet and doPost

Eclipse: ServletConfig object returns NULL on calling getServletConfig()

this is my code . Please help me solve this problem . I m new to servlet and i m trying my best to solve it but i m unable .
public class InsertData extends GenericServlet{
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
PrintWriter pw = null ;
ServletConfig conf = getServletConfig(); // This is giving null everytime i m checked it in webpage
String str = cont.getInitParameter("username");
pw = response.getWriter();
pw.println("<html><body><b>conf</b></body><html>");
}
}
and this is my web.xml file :
<web-app>
<servlet>
<servlet-name>s1</servlet-name>
<servlet-class>InsertData</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>mydb</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>s1</servlet-name>
<url-pattern>/InsertData</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>home.html</welcome-file>
</welcome-file-list>
</web-app>

Filter specific HTTP verbs in spring mvc

I'm getting a lot of errors in my spring MVC app caused by some clients requesting HTTP PROPFIND:
16:59:39,402 ERROR [foo.bar.controllers.ExceptionHandlingController] (default task-12) Uncaught Error: org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'PROPFIND' not supported
How can I filter this requests so that they don't generate an error in each controller ?
Thanks!
You can use Spring's HandlerInterceptor as below to allow & process the required requests.
RequestMethodInterceptor class:
package com.myproject.RequestMethodInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RequestMethodInterceptor implements HandlerInterceptor {
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
//Added PROPFIND method, add any other types NOT allowed
if(request.getMethod().equals("PROPFIND") ) {
//Log or Ignore upon your requirement & return false
return false;
} else {
return true;
}
}
}
XML Configuration:
<mvc:interceptors>
<bean class="com.myproject.RequestMethodInterceptor" />
</mvc:interceptors>
You have to configure the spring org.springframework.web.servlet.DispatcherServlet in managing OPTIONS
In the web.xml you should add something like this
<servlet>
<servlet-name>springServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

Servlet mapping: url pattern problems

I'm trying to set up a servlet mapping so that urls in the form "/getFile/{fileId}" will be mapped by my DispatcherServlet "dispatcher".
If I set up my web.xml as below only "/getFile" will be mapped, I can't append the fileId or it breaks.
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/getFile</url-pattern>
</servlet-mapping>
So I would have thought that I should use
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/getFile/*</url-pattern>
</servlet-mapping>
But this doesn't work at all.
The method I'm trying to call is
#RequestMapping(value = "/getFile/{documentId}", method = RequestMethod.GET)
public void getFile(#PathVariable int documentId, HttpServletResponse response) throws Exception {
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
UserDB userDB = UserDBService.getUser(user.getUsername());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Document document = DocumentService.getDocument(documentId);
String extension = document.getExtension();
try {
String path = ApplicationPropertiesConstants.SAFESITE_DOCUMENTS_DIRECTORY + userDB.getSite().getId() + "\\" + documentId + "." + extension;
InputStream is = new FileInputStream(path);
response.setHeader("Cache-Control", "no-store");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/png");
org.apache.commons.io.IOUtils.copy(is, response.getOutputStream());
response.flushBuffer();
} catch (IllegalArgumentException e) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
Any idea what I'm doing wrong?
Edit: it's not a duplicate as below because I do not have a servlet mapping of just "/". Thus there is no default fall back mapping.
My full mapping.
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/getFile/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.json</url-pattern>
</servlet-mapping>
Right so I fixed it by using the url
/getFile/getFile/{documentId}
on my client side.

servlet or ejb singleton to initialize web app

I need to initialize state of web application.
I can use initialization servlet with load-on-startup = 0.
Or I can use singleton ejb service.
What is better to use and why?
i think load-on-startup is better than ejb.
i have used load on start up in my web application.
<servlet>
<servlet-class>com.agileinfotech.bsviewer.servlet.InitServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>InitServlet</servlet-name>
<url-pattern>/InitServlet</url-pattern>
</servlet-mapping>
There is a special "thing" for initialization of web app - ServletContextListener.
it is used like this:
package example;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ServletContextExample implements ServletContextListener{
ServletContext context;
public void contextInitialized(ServletContextEvent contextEvent) {
... some init work
}
public void contextDestroyed(ServletContextEvent contextEvent) {
... some destroy work
}
}
And in web.xml
<listener>
<listener-class>
example.ServletContextExample
</listener-class>
</listener>

Resources