How to get Cookies from ServletContextListener? - java

i am new in Servlet and JSP and i want to grab all the cookies once my web app is running so i am using ServletContextListener to deploy what inside it once my web app is run !, so how can i get all cookies within it ?
i am trying to do the following :
public class listener implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
HttpServletRequest request ;
Cookie s[]=request.getCookies();
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
}}

Probably you don't need all the cookies [ie cookies of all users], but you need cookies of particular request. You can get them inside HttpServlet's doGet() or doPost() methods, depending on the request type:
public class TestServlet extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
//...
}
}

Related

Adding separate custom Servlet in Vaadin 23 - Spring 2.7.1

This question was already asked, however since then all answers (that I could found) are no longer valid.
Essentially I want to implement a website with Vaadin (V23), that communicates with a WebApp via POST requests that is running on another server (physically). To do it, I want to create separate Servlet that would handle the communication (receiving side) with another Server. Let's say, this is not implemneted version:
#WebServlet(urlPatterns = "/communication", name = "QuizServlet", asyncSupported = true)
public class QuizServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.sendError(400, "Not implemented");
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.sendError(400, "Not implemented");
}
}
The problem is however, that I always get redirected to default dispatcher Servlet, and it seems, regardless of what I do:
SpringVaadinServlet was deprecated and no longer exists, extending VaadinServlet does not work.
Changing mappings in properties (vaadin.url-mapping=) also does not work, I just get redirected to this new mapping in all cases.
Trying to do servlets on separate ports yields same redirection on all ports, even if explicitly registering my custom Servlet on the Connector, with separate Sevice (WebMvcConfigurer Tomcat configuration). Answer from this post, also too old.
Registering servlet directly also does not do anything (by implementing WebApplicationInitializer).
There for the question, how to make use of two different servlets with new Vaadin 23 and Spring Boot 2.7.1?
I have found some kind of a solution to my problem. Namely on startup of my BootAplication, I am also starting the second separate Tomcat server that uses my custom Servlet :
#Service
public class QuizServer {
private final Log log = LogFactory.getLog(QuizServer.class);
#PostConstruct
public void startServer() throws IOException, LifecycleException {
start();
}
private void start() throws IOException, LifecycleException {
Tomcat tomcat = new Tomcat();
String contextPath = "/";
String appBase = new File(".").getAbsolutePath();
Context ctx = tomcat.addContext(contextPath, appBase);
Tomcat.addServlet(ctx, "quizServlet", new QuizServlet());
ctx.addServletMappingDecoded("/*", "quizServlet");
tomcat.setPort(8085);
tomcat.start();
tomcat.getConnector();
log.info("Quiz server started");
}
}
#WebServlet(urlPatterns = "/*", name = "quizServlet", asyncSupported = true)
public class QuizServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("Test");
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.sendError(400, "Not implemented");
}
}
It is a bit crude though, since ideally, it shouldn't require a separate server.

Alternative to requestDestroyed in ServletRequestListener

I have multiple servlets in my web app. And I want to perform a specific action each time a request comes to MyServlet (only) and not when request is for any other servlet. Overriding destroy isn't going to solve this.
If I write a custom ServletRequestListener, that action will be performed for all requests, if I put that action in requestDestroyed method, irrespective of which servlet in my web app is being called.
So, does writing requestDestroyed method as a part of servlet itself like below solves this problem ? Or is there any other/better way?
public class MyServlet implements HttpServlet {
public void init(ServletConfig config) throws ServletException {
//init stuff
}
public void service(ServletRequest req, ServletResponse res)
throws ServletException {
try {
//do some stuff
} finally {
requestDestroyed(request);
}
}
private void requestDestroyed(HttpServletRequest request) {
//some clean up stuff only for this particular servlet
}
}

Create a cookie using HttpServletRequest?

I've created a RenderingPlugin, for use in WebSphere Portal, which is invoked serverside before sending markup to client. The plugin loops through all cookies and if 'test' is not found, I'd like to set that cookie.
I know this is possible with a HttpServletResponse but the RenderingPlugin doesn't have access to that object. It only has a HttpServletRequest.
Is there another way to do this?
public class Request implements com.ibm.workplace.wcm.api.plugin.RenderingPlugin {
#Override
public boolean render(RenderingPluginModel rpm) throws RenderingPluginException {
boolean found = false;
HttpServletRequest servletRequest = (HttpServletRequest) rpm.getRequest();
Cookie[] cookie = servletRequest.getCookies();
// loop through cookies
for (int i = 0; i < cookie.length; i++) {
// if test found
if (cookie[i].getName().equals("test")) {
found = true;
}
}
if (!found){
// set cookie here
}
}
}
Did you try using javascript code to set the cookie ?
<script>
document.cookie = "test=1;path=/";
</script>
you send this as part of the content you give to the Writer rpm.getWriter() and it will be executed by the browser.
I had a problem to simulate a cookie, that is only sending in production, in my test environment.
I solve with HttpServletRequestWrapper in a filter.
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
Cookie cookie = new Cookie("Key", "Value");
chain.doFilter(new CustomRequest((HttpServletRequest) request, cookie), response);
}
}
class CustomRequest extends HttpServletRequestWrapper {
private final Cookie cookie;
public CustomRequest(HttpServletRequest request, Cookie cookie) {
super(request);
this.cookie = cookie;
}
#Override
public Cookie[] getCookies() {
//This is a example, get all cookies here and put your with a new Array
return new Cookie[] {cookie};
}
}
This filter is only started in test environment. My class WebConfig take care of this:
#HandlesTypes(WebApplicationInitializer.class)
public class WebConfig implements WebApplicationInitializer

POST not supported in custom Servlet as #Bean in Spring Boot

I'm trying to integrate a 3rd party servlet into my Spring Boot application and when I try to submit a POST to the servlet, I see the following in the logs:
PageNotFound: Request method 'POST' not supported
I've made a simple test that show this. I started using an auto generated Spring Boot project. Then I created the following Servlet:
public class TestServlet extends HttpServlet {
private static final Logger log = LoggerFactory.getLogger(TestServlet.class);
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp); //To change body of generated methods, choose Tools | Templates.
log.info("doPost was called!!");
}
}
Then I my created Configuration like so:
#Configuration
public class ServletConfig {
#Bean //exposes the TestServlet at /test
public Servlet test() {
return new TestServlet();
}
}
Then I run the application within Tomcat7. I see in the logs:
ServletRegistrationBean: Mapping servlet: 'test' to [/test/]
Then I try to hit the endpoint with cUrl like so:
curl -v http://localhost:8080/test -data-binary '{"test":true}'
or
curl -XPOST -H'Content-type: application/json' http://localhost:8080/test -d '{"test":true}'
I've tried adding a #RequestMapping, but that didn't work either. Can anyone help me figure out how to support another Servlet inside my Spring Boot application?
You can find the sample application here: https://github.com/andrewserff/servlet-demo
Thanks!
From my previous experiences you have to call the servlet with a slash at the end (like http://localhost:8080/test/). If you don't put the slash at the end, the request is routed to the servlet mapped to /, which is by default the DispatcherServlet from Spring (your error message comes from that servlet).
The TestServlet#doPost() implementation calls the super.doPost() - which always sends a 40x error (either 405 or 400 depending on the HTTP Protocol used).
Here's the implementation:
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_post_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
A Servlet can be registered using two ways:
registering the Servlet as a Bean (your approach - which should be fine) or
using a ServletRegistrationBean:
#Configuration
public class ServletConfig {
#Bean
public ServletRegistrationBean servletRegistrationBean(){
return new ServletRegistrationBean(new TestServlet(), "/test/*");
}
}
The slightly changed Servlet:
public class TestServlet extends HttpServlet {
private static final Logger log = LoggerFactory.getLogger(TestServlet.class);
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doPost(req, resp);
log.info("doPost was called!!");
}
}

HTTP method GET is not supported by this URL

i am having trouble with my code as i am accessing the logout servlet from a jsp page's hyperlink.
Jsp page link:
href="/logout"
logout Servlet:
public class logOut extends HttpServlet{
public void doGET(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
resp.setContentType("text/html");
System.out.println("log out servlet");
HttpSession session = req.getSession(false);
if (session != null) {
session.invalidate();
}
resp.sendRedirect("/signin.jsp");
}
}
but i am having the following error :
HTTP ERROR 405
Problem accessing /logout. Reason:
HTTP method GET is not supported by this URL
please help me.....
It is called doGet, not doGET.
The #Override annotation would have told you that.
Your method needs to be called
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { ... }
in order to be recognized - the uppercase letters make it fail.

Categories

Resources