Forwarding requests in servlets - java

so I'm trying to create a servlet which will handle all requests for the WSDL at the endpoint, and then send the WSDL (Right now its just a file on the disk, later, I'm planning to change that file somewhat based on the permissions of the client). The way I'm trying to implement this is by creating a WSDLHandlerServlet class that's mapped to /* in web.xml. The way I understand it - all requests should be intercepted by this.
Once passed to the servlet it checks basically if the URI with query string is - "/TestProject/pace/soap?wsdl" and if so sends back the WSDL. This part works fine when I open "localhost:8180/TestProject/pace/soap?wsdl" in the browser and it displays the correct WSDL.
If the request has no query string, then I forward it to the cxf servlet which is linked to my web service implementor.
However when I send a request from a client (SOAP request), I get -
Exception in thread "main" com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 200: OK
Also it is clearly not reaching the implementing class since if it did, there would be a log. I suspect I have most probably messed up the servlet mappings.
This is the WSDLHandler Servlet-
package servlets;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class WSDLHandlerServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// This is just a test.. anything without a query string will be sent to
// cxf servlet... and any long request ending with ?wsdl will yield the
// wsdl.. need to work on the design...never mind now it is time to
// begin!!
String query = new String();
query = request.getQueryString();
/*
* File abc = new File("/home/aneeshb/testing.txt"); FileWriter fw = new
* FileWriter(abc);
*
*
* if(!query.isEmpty()){ fw.write(query); fw.close();}
*/String requestURI = request.getRequestURI();
File abc = new File("/home/aneeshb/testing.txt");
FileWriter fw = new FileWriter(abc);
fw.write(requestURI);
fw.append("1234");
fw.append(query);
fw.flush();
if (query==null) {
fw.append("2");
fw.flush();
RequestDispatcher dispatch = request.getRequestDispatcher("/pace");
fw.append("2");
fw.flush();
dispatch.forward(request, response);
fw.append("2");
fw.flush();
}
else if (requestURI.equals("/TestProject/pace/soap")
&& query.equals("wsdl")) {
fw.append("This is in part1 ");
fw.flush();
response.setCharacterEncoding("UTF-8");
response.setContentType("text/xml");
PrintWriter respWrite = response.getWriter();
File wsdlFile = new File(
"/home/aneeshb/Workspaces/Project1/TestProject/WebContent/WEB-INF/wsdl/stock.wsdl");
FileReader wsdlRead = new FileReader(wsdlFile);
BufferedReader wsdlBuffRead = new BufferedReader(wsdlRead);
int temp = 0;
while ((temp = wsdlBuffRead.read()) != -1) {
respWrite.write(temp);
}
respWrite.flush();
wsdlBuffRead.close();
}
else {
throw new IndexOutOfBoundsException();
}
}
}
My web.xml -
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-insance"
version="2.5"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>cxf</display-name>
<servlet>
<description>Apache CXF Endpoint</description>
<display-name>cxf</display-name>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<description>WSDL Handler</description>
<display-name>wsdlh</display-name>
<servlet-name>wsdlh</servlet-name>
<servlet-class>servlets.WSDLHandlerServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/pace</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>wsdlh</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
</web-app>
And just for good measure-the cxf servlet config file-
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:soap="http://cxf.apache.org/bindings/soap" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd" xmlns:tns="http://impl/">
<jaxws:server id="jaxwsService" serviceClass="impl.GatewayImplementor" address="/soap" >
<jaxws:serviceBean>
<bean class="impl.GatewayImplementor"/>
</jaxws:serviceBean>
</jaxws:server>
</beans>
Thanks, any help with what I am doing wrong or ideas on alternate solutions would be great!

Related

How to set Priority Order of displaying context param parameters on server?

I am trying to get the parameters names in a Servlet Context object from context param elements in an order given in the web.xml file. But on running code on the server, displayed parameter order is not the same as to mention in the web.xml file.
DemoServlet.java
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DemoServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter pw=response.getWriter();
ServletContext context=getServletContext();
//we are getting all the initialization parameter from the web.xml file
Enumeration<String> e=context.getInitParameterNames();
while(e.hasMoreElements()) {
String s=e.nextElement();
pw.println("<br>"+context.getInitParameter(s));
}
pw.close();
}
}
web.xml
<?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>Servlet6ServletContextInterface2</display-name>
<servlet>
<servlet-name>demo</servlet-name>
<servlet-class>DemoServlet</servlet-class>
</servlet>
<context-param>
<param-name>DriverName</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</context-param>
<context-param>
<param-name>Username</param-name>
<param-value>Pranay Singh</param-value>
</context-param>
<context-param>
<param-name>Password</param-name>
<param-value>abc123</param-value>
</context-param>
<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>/context</url-pattern>
</servlet-mapping>
</web-app>
Expected Results:
com.mysql.jdbc.Driver Pranay Singh abc123
Actual Results:
Pranay Singh com.mysql.jdbc.Driver abc123
The params are intended to be accessed by their name, so the orders are not guaranteed.
If you really need them in a specific order, you can hard-code the param names (in your own order) into a collection:
List<String> paramNames = Arrays.asList("DriverName", "Username", "Password");
for(String paramName: paramNames) {
pw.println("<br>" + context.getInitParameter(paramName));
}
Or if you want to keep the params dynamic without hard-coding anything, you can at least sort them.
Enumeration<String> e = context.getInitParameterNames();
List<String> paramNames = Collections.list(e);
Collections.sort(paramNames);
for(String paramName: paramNames) {
pw.println("<br>" + context.getInitParameter(paramName));
}

JAVA JSON Restfull WebService No 'Access-Control-Allow-Origin' header is present on the requested resource [duplicate]

This question already has answers here:
How to handle CORS using JAX-RS with Jersey
(5 answers)
Closed 6 years ago.
I have a JAVA RESTful webservice which will return JSON string and it was written in Java. My problem is when I send request to that webservice with below URL
http://localhost:8080/WebServiceXYZ/Users/insert
it's giving me the below error message
XMLHttpRequest cannot load http://localhost:8080/WebServiceXYZ/Users/insert/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access. The response had HTTP status code 500.
Here is my Code
package com.lb.jersey;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.json.JSONException;
import org.json.JSONObject;
#Path("/Users")
public class RegistrationService
{
#POST
#Produces(MediaType.APPLICATION_JSON)
#Path("/insert")
public String InsertCredentials (String json) throws JSONException
{
java.util.Date dt = new java.util.Date();
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String currentTime = sdf.format(dt);
String phone = null;
JSONObject returnJson = new JSONObject();
try
{
JSONObject obj = new JSONObject(json);
JSONObject result1 = obj.getJSONObject("Credentials");
phone = result1.getString("phone");
DBConnection conn = new DBConnection();
int checkUserID = conn.GetUserIDByPhone(phone);
if(checkUserID <= 0)
{
DBConnection.InsertorUpdateUsers(phone, currentTime);
}
int userID = conn.GetUserIDByPhone(phone);
int otp = (int) Math.round(Math.random()*1000);
DBConnection.InsertorUpdateCredentials(userID, otp, currentTime);
JSONObject createObj = new JSONObject();
createObj.put("phone", phone);
createObj.put("otp", otp);
createObj.put("reqDateTime", currentTime);
returnJson.put("Credentials", createObj);
System.out.println(returnJson);
}
catch (Exception e)
{
}
return returnJson.toString();
}
}
My web.xml code
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>WebServiceXYZ</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.server.impl.container.servlet.ServletAdaptor</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.lb.jersey</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
I already read many articles but no progress, so please let me know, How can I handle this issue?
this is assuming you are using jetty as your server. hope it helps...
add the following code to your web.xml
<filter>
<filter-name>cross-origin</filter-name>
<filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
<init-param>
<param-name>allowedOrigins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>allowedMethods</param-name>
<param-value>GET,POST,DELETE,PUT,HEAD</param-value>
</init-param>
<init-param>
<param-name>allowedHeaders</param-name>
<param-value>origin, content-type, accept</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>cross-origin</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
and the following dependency in your pom.xml
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
<version>8.0.0.M0</version>
</dependency>
the link to configure tomcat is link... here is another link2 modify accordingly :)
You can try setting the header for the HttpServletResponse
import javax.servlet.http.HttpServletResponse;
#Path("/Users")
public class RegistrationService
{
#Context
private HttpServletResponse servletResponse;
private void allowCrossDomainAccess() {
if (servletResponse != null){
servletResponse.setHeader("Access-Control-Allow-Origin", "*");
}
}
#POST
#Produces(MediaType.APPLICATION_JSON)
#Path("/insert")
public String InsertCredentials (String json) throws JSONException
{
allowCrossDomainAccess();
// your code here
}
}

Filter servlet not working with glassfish in netbeans

This is my web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<filter>
<display-name>MyFilter</display-name>
<filter-name>MyFilter</filter-name>
<filter-class>AB_DB.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/MyFilter</url-pattern>
</filter-mapping>
<servlet>
<description></description>
<display-name>Profile</display-name>
<servlet-name>Profile</servlet-name>
<servlet-class>AB_DB.Profile</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Profile</servlet-name>
<url-pattern>/Profile</url-pattern>
</servlet-mapping>
</web-app>
This is the filter servlet I've tried
package AB_DB;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class MyFilter implements Filter {
public MyFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
String requri = ((HttpServletRequest) request).getRequestURI().substring(((HttpServletRequest) request).getContextPath().length() + 1);
System.out.println(requri);
//if request uri starts with user/ then system will forward the request to Profile servlet
if (requri.startsWith("user/")) {
//get userid from request uri
String id = requri.substring(5);
System.out.println(id);
//set attribute "user" with userid value
request.setAttribute("user", id);
//forward the request to Profile servlet
request.getRequestDispatcher("/Profile")
.forward(request, response);
} else {
chain.doFilter(request, response);
}
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
However in the GlassFish 4 server log, there is no errors at all when running the project. The URI isnt even being printed out with 'System.out.println(id);' so I assume that the filter isnt even being injected.
Can anyone see any issues with my code? The sevlet Profile isn't being ran
You have mapped oyur filter to /MyFilter
<url-pattern>/MyFilter</url-pattern>
and that doesn't match with URL you are requesting
/user/Surname1993
so your filter won't get invoked

Can't compile servlet file.

I was testing a demo servlet file But, the servlet doesn't seem to respond. I'm not able to understand the problem.
When I click submit on the HTML form the URL is
localhost:8080/Beer-V1/SelectBeer.do
But, shouldn't it be /BeerSelect? Because of #WebServlet("/BeerSelect") ???
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web- app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" metadata-complete="false"
version="3.0">
<servlet>
<servlet-name>CH3 Beer</servlet-name>
<servlet-class>com.example.web.BeerSelect</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CH3 Beer</servlet-name>
<url-pattern>/SelectBeer.do</url-pattern>
</servlet-mapping>
</web-app>
BeerSelect.java
package com.example.web;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet("/BeerSelect")
public class BeerSelect extends HttpServlet {
private static final long serialVersionUID = 1L;
public BeerSelect() {
super();
}
#Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("Beer Selection Advice<br>");
String c = request.getParameter("color");
out.println("<br> Got Beer Color " + c);
}
}
When I click submit on the HTML form the URL is localhost:8080/Beer-V1/SelectBeer.do
But, shouldn't it be /BeerSelect? Because of #WebServlet("/BeerSelect") ???
web-container associates a "context-path" for each of the web-application deployed and in your case, I believe it is "Beer-V1".
You have overridden the mapping in web.xml as below and hence you are seeing *.do
<servlet-mapping>
<servlet-name>CH3 Beer</servlet-name>
<url-pattern>/SelectBeer.do</url-pattern>
</servlet-mapping>
The xml DD overrides the annotations.

Counting the number of users in web App in servlet

I have modified my application to find out the number of users logged in a web application below is my piece of code..
the listener class
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class SessionCounter implements HttpSessionListener
{
private static int count;
public static int getActiveSessions() {
return count;
}
public SessionCounter()
{
}
//The "sessionCount" attribute which has been set in the servletContext should not be modified in any other part of the application.
//Since we are using serveltContext in both the methods to modify the same variable, we have synchronized it for consistency.
public void sessionCreated(HttpSessionEvent e)
{
count++;
ServletContext sContext = e.getSession().getServletContext();
synchronized (sContext)
{
sContext.setAttribute("sessionCount", new Integer(count));
}
}
public void sessionDestroyed(HttpSessionEvent e)
{
count--;
ServletContext sContext = e.getSession().getServletContext();
synchronized (sContext)
{
sContext.setAttribute("sessionCount", new Integer(count));
}
}
}
and the main servlet is ..
package com.saral;
import java.io.IOException;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class First
*/
//#WebServlet("/First")
public class MyServlet extends HttpServlet
{
private static final long serialVersionUID = 1L;
static final Logger logger = Logger.getLogger(MyServlet.class);
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PropertyConfigurator.configure("log4j.properties");
logger.info("before---->");
// TODO Auto-generated method stub
String name=request.getParameter("txtName");
response.setContentType("text/html");
PrintWriter out=response.getWriter();
out.println("Hello,"+name);
out.println("<br> this output is generated by a simple servlet.");
out.println("Total Number of users logged in--->"+SessionCounter.getActiveSessions());
out.close();
}
}
and the web.xml is ...
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>FirstDemo</display-name>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.saral.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/helloServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>home.html</welcome-file>
</welcome-file-list>
<listener>
<listener-class>com.saral.SessionCounter</listener-class>
</listener>
</web-app>
but I am getting the total number of users logged in as 0 , which is not perfect, please advise where I am wrong and how can I overcome from this.
When a client request come to the Tomcat server and you don't call request.getSession(), then the Tomcat server stil creates a session automatically. After that, the method sessionCreated(...) in your SessionCounter class is called.
The method sessionDestroyed(...) will be called when a session is destroyed. That occurs when you call session.invalidate(). If you close a tab on browser or close a browser, the session is still alive on your tomcat server.
I think so. You can use some diffrent listeners to archive your goal: HttpSessionAttributeListener, HttpSessionBindingListener,...

Categories

Resources