Why does jersey have no error log when the status is 500? - jersey-2.0

This is my web.xml:
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>
org.glassfish.jersey.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>rest</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.filter.LoggingFilter</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
And this is my resource class:
#Path("/main")
public class MainResource {
#XmlRootElement
public class Planet {
public int id;
public String name;
public double radius;
}
#GET
#Produces(MediaType.APPLICATION_XML)
public Planet getPlanet() {
final Planet planet = new Planet();
planet.id = 1;
planet.name = "Earth";
planet.radius = 1.0;
return planet;
}
}
And when I run the tomcat server, the log is like this:
09-Jan-2015 13:19:10.501 INFO [http-apr-8080-exec-8] org.glassfish.jersey.filter.LoggingFilter.log 1 * Server has received a request on thread http-apr-8080-exec-8
1 > GET http://localhost:8080/rest/main
1 > accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
1 > accept-encoding: gzip, deflate, sdch
1 > accept-language: en,zh-CN;q=0.8,zh;q=0.6
1 > connection: keep-alive
1 > cookie: JSESSIONID=69F79D567E7ECA27A129C477B91C7758
1 > host: localhost:8080
1 > user-agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
09-Jan-2015 13:19:10.597 INFO [http-apr-8080-exec-8] org.glassfish.jersey.filter.LoggingFilter.log 1 * Server responded with a response on thread http-apr-8080-exec-8
1 < 200
1 < Content-Type: application/xml
09-Jan-2015 13:19:10.794 INFO [http-apr-8080-exec-8] org.glassfish.jersey.filter.LoggingFilter.log 2 * Server responded with a response on thread http-apr-8080-exec-8
2 < 500
I wonder why it shows 500 error, but I cannot find any error log about the exception stack.
Please help me.

I fixed my issue and I answer my own question now.
First, how can I enable the exception trace logging?
#Provider
public class ExceptionMapper implements javax.ws.rs.ext.ExceptionMapper<Exception> {
#Override
public Response toResponse(Exception exception) {
exception.printStackTrace();
return Response.status(500).build();
}
}
Yes, we should implement an ExceptionMapper on my own.
Second, what's the error of my code?
The class Planet should be static.

Related

How to define several ports under single endpoint in CXF?

we're migrating our SOAP application from AXIS2 to CXF and we have following service definition in the wsdl:
<wsdl:service name="MyService">
<wsdl:documentation>My Service
</wsdl:documentation>
<wsdl:port name="MyServiceHttpSoap11Endpoint" binding="ns:MyServiceSoap11Binding">
<soap:address location="http://localhost:8080/axis2/services/MyService" />
</wsdl:port>
<wsdl:port name="MyServiceHttpSoap12Endpoint" binding="ns:MyServiceSoap12Binding">
<soap12:address location="http://localhost:8080/axis2/services/MyService" />
</wsdl:port>
<wsdl:port name="MyServiceHttpEndpoint" binding="ns:MyServiceHttpBinding">
<wsdl:documentation>documentation ***</wsdl:documentation>
<http:address location="http://localhost:8080/axis2/services/MyService" />
</wsdl:port>
</wsdl:service>
In old AXIS2 implementation I was able to access wsdl at http://hostname:port/MyService/services/MyService?wsdl
which had 3 different endpoints for each SOAP version:
/MyService/services/MyService.MyServiceHttpSoap11Endpoint/
/MyService/services/MyService.MyServiceHttpSoap12Endpoint/
/MyService/services/MyService.MyServiceHttpEndpoint/
But how could I achieve same locations with CXF (without Spring)?
I want to have single wsdl url and 3 different locations for each SOAP version.
I know that SOAP 1.2 is backward compatible in CXF, so it's enough to define just 1.2 endpoint to cover SOAP 1.1 and 1.2. But how to use different names for them? And how could I define 3rd port (MyService.MyServiceHttpEndpoint)?
For non-Spring CXF implementation I extended CXFNonSpringServlet class to publish my service:
public class SimpleCXFNonSpringServlet extends CXFNonSpringServlet {
private static final long serialVersionUID = 1L;
#Override
public void loadBus(ServletConfig servletConfig) {
super.loadBus(servletConfig);
Bus bus = getBus();
BusFactory.setDefaultBus(bus);
Endpoint endpoint = Endpoint.create(new EndpointFactory().createMyServiceEndpoint());
endpoint.publish("/MyService");
}
}
Endpoint factory class:
public class EndpointFactory {
public MyServiceHttpSoap12Endpoint createMyServiceEndpoint() {
return new MyServiceHttpSoap12Endpoint(new MyServiceImpl());
}
}
implementor class:
#WebService(
serviceName = "MyService",
portName = "MyServiceHttpSoap12Endpoint",
targetNamespace = "http://company.com",
wsdlLocation = "file:/C:/projects/MyService_CXF/MyService/WebContent/WEB-INF/services/MyService/META-INF/MyService.wsdl",
endpointInterface = "com.company.MyServicePortType")
public class MyServiceHttpSoap12Endpoint implements MyServicePortType {
private static final Logger LOG = Logger.getLogger(MyServiceHttpSoap12Endpoint.class.getName());
private MyServiceAPI myServiceAPI;
public MyServiceHttpSoap12Endpoint(MyServiceAPI myServiceAPI) {
this.myServiceAPI = myServiceAPI;
}
#Override
public ResultObject getObject(Parms pams) throws MyService_Exception {
LOG.info("Executing operation getObject");
// ... implementation ...
}
}
Web.xml:
<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>
com.company.SimpleCXFNonSpringServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>

how do I get a root path redirect to not respond to all requests in eclipse jetty?

I have a jetty servlet set of pages all set up and working.
to get to the landing page, you have to enter the full url http://127.0.0.1/console/console.jsp
everything is fine for my context "console".
I wanted to add a handler for the root url, so I could just put in a host and it would redirect to the above url.
I got that working, except it seems that every request comes through my root path handler as well and it messes up all the other requests to the real jsp pages.
How do I keep it from doing that, or what do I do differently?
my web.xml...
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<description></description>
<servlet-name>console</servlet-name>
<servlet-class>net.console.Consoleservlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>console</servlet-name>
<url-pattern>/console</url-pattern>
</servlet-mapping>
<servlet>
<description></description>
<servlet-name>redirect</servlet-name>
<servlet-class>net.console.Redirectservlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>redirect</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
slimmed down version of my redirect servlet...
public class Redirectservlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet
{
static final long serialVersionUID = 1L;
public Redirectservlet()
{
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
try
{
String redirect_path = "http://127.0.0.1/console/console.jsp";
response.sendRedirect(redirect_path);
}
catch (Exception e)
{
}
}
Try using welcome-files instead of your RedirectServlet, in your WEB-INF/web.xml...
<web-app ...>
<welcome-file-list>
<welcome-file>console/console.jsp</welcome-file>
</welcome-file-list>
... other entries
</web-app>
If that doesn't work, consider making that a RedirectFilter instead, and only sending a redirect if the request.getRequestURI() is only in a list of exact request URI string matches that should redirect.

AngularJS RESTful JSON requests with ngResource and Restangular

i have some problems with angularJS and REST requests / responses. Since three weeks i playing with AngularJS and now i would like do some cool stuff.
First i created a simple jersey REST service, that returns a simple list.
#Path("/hello")
public class Hello {
#GET
#Produces(MediaType.APPLICATION_JSON)
public List<Medication> sayJsonHello() {
List<Object1> objs = new ArrayList<Object1>();
objs.add(new Object1("1", "HUHU"));
objs.add(new Object1("2", "HUHU 2"));
return objs;
}
}
as you can see, there is no big magic.
Here my web.xml file, to configure Jersey:
<?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>Jersey REST Example</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>examples</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.config.feature.DisableWADL</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
After some tests, the service will return a simple JSON list:
[
{
"id": "1",
"name": "HUHU"
},
{
"id": "2",
"name": "HUHU 2"
}
]
I deploying the webservice into a Tomcat7 instance. Now i would like to get this data into my webapplication. After reading some tutorials and example i starting to create few implementations.
After starting create my first service, i and this code-snipped into my app.js:
app.config(['$httpProvider', function ($httpProvider) {
delete $httpProvider.defaults.headers.common["X-Requested-With"];
}]);
this will remove X-Request-With request-header from the header defauls.
1. Request via Service and ngResource
angular.module('helloService', ['ngResource']).
factory('hService', function ($resource) {
return $resource('http://localhost\\:8180/rest/hello',
{callback: 'JSON_CALLBACK'}, {
get: {method: 'GET', headers: [
{'Content-Type': 'application/json'},
{'Accept': 'application/json'}
]}
});
});
MyController:
function MyController($scope, hService) {
hService.get(function(result){
alert(" Result of helloService");
}, function error(response){
alert(" Error during helloService "+response.status);
});
}
if i try to load data, the get functin will always return an error and the status is always 0.
2. Trying with Restangular
After get how to use Restangular i starting to configured Restangular:
app.config(function (RestangularProvider) {
RestangularProvider.setBaseUrl('http://localhost\\:8180/rest');
});
and also add the RestangularProvider to my angular.module:
var app = angular.module("html5App", ['helloService', 'restangular', 'ngResource']);
MyController:
function MyRestangularCtr($scope, Restangular){
var all = Restangular.all('hello');
$scope.allObjects = all.getList();
all.getList().then(function (hellos) {
console.log("Result "+ hellos);
}, function errorCallback(response) {
alert("Oops error from server :( status" + response.status);
console.log("status: "+response);
});
}
Here the same: No Data, Status 0. I have no idea, why i dont get any data from my service. Additional i getting sometimes this error: "Error: $digest already in progress". Im not sure, where the problem is. If the jersey service i wrong or bad or my beginner JavaScript is wrong.
First Solution
Client Side
The Angular request should look like this:
$scope.myData = $resource('http://localhost\\:8180/rest/:action',
{action: 'hello', callback:'JSON_CALLBACK'},
{get: {method: 'JSONP'}});
$scope.datas = $scope.myData.get();
The method need to JSONP (GET will still not working ( no repsonse data because CORPS?)
Service Side
Important here is, that the server also response with a JSONP fomat and can handle callback requests.
#GET
#Produces("application/x-javascript")
public JSONWithPadding sayJsonHello(#QueryParam("callback") String callback) {
MyObjectList obList= new MyObjectList ();
obList.getObjs().add(new MyObject(1, "HUHU"));
obList.getObjs().add(new MyObject(2, "HUHU 2"));
return new JSONWithPadding(obList, callback);
}
Still unclear
Is there any way to return normal json object from server to client?
Shouldn't be the first parameter of you controller be $scope? Maybe this is the issue?
function MyController($scope, hService) {

Change HTTP response code in CXF SOAP Fault

I have this error
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Message part {http://soap.ws.server.wst.fit.cvut.cz/}createOrders was not recognized. (Does it exist in service WSDL?)</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
which is completely fine. But the problem is that CXF is returning Internal Server Error (HTTP 500). I would expect it to return 400 Bad Request because a wrong request is causing this. How can I change that?
DETAILS
The wrong request which produces the error above - there should be <soap:createOrder/> instead of <soap:createOrders/>.
POST http://localhost:8080/wst-server-1.0.0/services/soap/order
POST data:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://soap.ws.server.wst.fit.cvut.cz/">
<soapenv:Header/>
<soapenv:Body>
<soap:createOrders/>
</soapenv:Body>
</soapenv:Envelope>
[no cookies]
Request Headers:
Content-Length: 238
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
I know maybe this is too late for the answer but another way to handle HTTP status code is using CXF interceptors.
you can add an interceptor in your server CXF configure
public class ServiceConfigurer implements CxfConfigurer {
#Override
public void configureServer(Server server) {
server.getEndpoint().getOutFaultInterceptors().add(new ChangingStatusCodeInterceptor();
}
}
and in your interceptor, you can change this
public class SaveInfluxDataInterceptor extends WSS4JOutInterceptor {
#Override
public void handleMessage(SoapMessage soapMessage) {
((Fault)exchange.get(Exception.class)).setStatusCode(202); // this is because of soap12OutFaultInterceptor look to this fault
// or you can use this
// exchange.getOutFaultMessage().put(Message.RESPONSE_CODE, 202);
}
}
I used Camel with CXF. maybe this solution should change in yours.

GWT, jcifs, and multiple prompting for login

We have a gwt app that uses jcifs to pull the user name from our NT domain. Here is a clip of our web.xml:
<filter>
<filter-name>NtlmHttpFilter</filter-name>
<filter-class>com.xxx.gwt.server.MyNTLMFilter</filter-class>
<init-param>
<param-name>jcifs.netbios.wins</param-name>
<param-value>192.168.109.20</param-value>
</init-param>
<init-param>
<param-name>jcifs.smb.client.domain</param-name>
<param-value>its</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>NtlmHttpFilter</filter-name>
<url-pattern>/trunkui/greet</url-pattern>
</filter-mapping>
<!-- Servlets -->
<servlet>
<servlet-name>greetServlet</servlet-name>
<servlet-class>com.xxx.gwt.server.GreetingServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>greetServlet</servlet-name>
<url-pattern>/trunkui/greet</url-pattern>
</servlet-mapping>
So currently when the user goes to our site they get about 2 or 3 repeated prompts asking them to log onto the domain even though they already are (you have to be on the domain to get to our app). I would like to at least reduce the prompting to only happen once. So I was going to make a dummy servlet off of "/trunkui/dummy" and let that get called only when I ask for the name. The remote servlet has this method that we call asynchronously:
public String getUser() {
String userAgent = "";
try {
userAgent = getThreadLocalRequest().getUserPrincipal().getName();
int slashIdx = -1;
if ((slashIdx = userAgent.indexOf('\\')) >= 0)
userAgent = userAgent.substring(slashIdx + 1);
} catch (Exception npe) {
npe.printStackTrace();
}
return userAgent;
}
So I wanted to do some sort of call to the dummy servlet to do the domain prompting, but I am unsure on how to do this from the gwt remote service. Or if there is a better way to do this?
I figured it out. I built the dummy servlet and then used a RequestBuilder on the client side to do a get on that servlet. That servlet then gets the userprincipal. Here is the client side:
RequestBuilder getNameRB = new RequestBuilder(RequestBuilder.GET, "naming");
getNameRB.setCallback( new RequestCallback() {
#Override
public void onResponseReceived(Request request, Response response) {
loadUserName(response.getText());
}
#Override
public void onError(Request request, Throwable exception) {
Window.alert("Unable to authenticate user\n"+exception.getMessage());
Window.Location.replace("http://ccc");
}
});
try {
getNameRB.send();
} catch (RequestException e) {
Window.alert(e.getMessage());
}