Jersey 2.2: output xml OK, but fails on json - json

I've run into a weird problem.
I use Jersey 2.2 to do my restful web services (with jersey-media-moxy).
If I produce my output as application/xml, it runs fine.
But if produce my output as application/json, I get "Internal Server Error 500".
My dependency settings in ivy.xml are:
<dependency org="org.glassfish.jersey.core" name="jersey-server" rev="2.2"/>
<dependency org="org.glassfish.jersey.containers" name="jersey-container-servlet-core" rev="2.2"/>
<dependency org="org.glassfish.jersey.media" name="jersey-media-moxy" rev="2.2"/>
My service class is:
#Path("/projects/{companykey: [0-9]*}")
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public class ProjectResource {
private static Logger logger = Logger.getLogger(ProjectResource.class);
private final Application app = Application.getInstance();
#GET
public List<ProjectBase> getProjectBases(
#PathParam("companykey") String companyKeyStr) {
...
}
#GET
#Path("/{projectkey: [0-9]*}")
public ProjectBase getProjectBase(
#PathParam("companykey") String companyKeyStr,
#PathParam("projectkey") String projectKeyStr) {
int companyKey = Integer.valueOf(companyKeyStr);
int projObjKey = Integer.valueOf(projectKeyStr);
logger.debug(MessageFormat.format("get project {1} of company {0}",
companyKey, projObjKey));
ProjectBase project = null;
try {
project = app.getProjectIF().getProjectBase(companyKey, projObjKey);
if (project == null) throw new WebApplicationException(404);
return project;
} catch (ServerException se) {
logger.warn("get project fails ! " + se);
throw new WebApplicationException(500);
}
}
...
}
//class end
If I ask for the xml output (visit http://biz.loc.net:8080/tm/rest/projects/100/104), I get:
<projectBase>
<_checkTopicAccess>false</_checkTopicAccess>
<_checkTaskAccess>false</_checkTaskAccess>
....
If I ask for the json output, I get:
HTTP Status 500 - Internal Server Error
type Status report
message Internal Server Error
description The server encountered an internal error (Internal Server Error) that prevented it from fulfilling this request.
I do not find any error messages in my app's log file or Tomcat's log file, so I have no
idea what is going on.
Does anyone know any possible reason for this problem? Really appreciate ...

Can you show the entity code? Are you missing an empty constructor?

Thanks for your help, the following code snippet is my entity clas:
#XmlRootElement
public class ProjectBase implements UdaEnabled, SdaEnabled, FormBean {
private int projObjKey;
private String projName;
//...
private Timestamp createdAt;
//...
//...
#XmlElement(name = "createdAt")
#XmlJavaTypeAdapter(TimestampAdapter.class)
public Timestamp getCreatedAt() {
return createdAt;
}
// non-args Constructor
public ProjectBase() {
init();
}
}
It does has an empty constructor, although these's a init() inside.
As I said, I think it is weird because producing xml is OK.

Related

Read local json file and show the data in UI for blazor server

I have one blazor. Net 5 web application.I have added one json file. Need to call that json file to razor page and show the data in UI for blazor server.
#page "/"
#inject HttpClient Http
#if (employees == null)
{
<p>Loading...</p>
}
else
{
#foreach (var employee in employees)
{
<p>Employee ID: #employee.Id</p>
}
}
#code {
private Employee[] employees;
protected override async Task OnInitializedAsync()
{
employees = await Http.GetFromJsonAsync<Employee[]>("employee.json");
}
public class Employee
{
public string Id { get; set; }
}
}
Getting the following error for the above code snippet -
Invalid operation exception: cannot provide a value for property 'http' on type
There is no registered service for type System.Net.Http.HttpClient
Kindly help with example. It is a huge blocker.
You are using dependency injection for an instance of HttpClient:
#inject HttpClient Http
and the error message is indicating that no HttpClient service has been registered. You need to register an HttpClient service: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-6.0
Or you could use IHttpClientFactory and call CreateClient();

Converting CSV file to JSON and send it to ActiveMQ queue

My aim is to read a CSV file, convert it to JSON and send the generated JSON one by one to ActiveMQ queue. My Code below:
final BindyCsvDataFormat bindy=new BindyCsvDataFormat(camelproject.EquityFeeds.class);
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
CamelContext _ctx = new DefaultCamelContext();
_ctx.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
_ctx.addRoutes(new RouteBuilder() {
public void configure() throws Exception {
from("file:src/main/resources?fileName=data-sample.csv")
.unmarshal(bindy)
.marshal()
.json(JsonLibrary.Jackson).log("${body}")
.to("file:src/main/resources/?fileName=emp.json");
}
});
EquityFeeds is my POJO class in the above code.
Issues:
No Output is produced. "emp.json" file does not get generated at the given location.
Also how do I split the generated JSON into individual JSON's and send it to ActiveMQ queue like what I did for XML as below:
.split(body().tokenizeXML("equityFeeds", null)).streaming().to("jms:queue:xml.upstream.queue");
EquityFeeds (POJO):
#CsvRecord(separator = ",",skipFirstLine = true)
public class EquityFeeds {
#DataField(pos = 1)
private String externalTransactionId;
#DataField(pos = 2)
private String clientId;
#DataField(pos = 3)
private String securityId;
#DataField(pos = 4)
private String transactionType;
#DataField(pos = 5)
private Date transactionDate;
#DataField(pos = 6)
private float marketValue;
#DataField(pos = 7)
private String priorityFlag;
// getters and setters...
}
Please kindly help. Please tell me where I am going wrong. Need help desperately. Stuck in this issue and not able to move forward. Any help would be highly appreciated. I have really tried hard, searched Google and tried various options but nothing is working.
Please Note: I commented the .marshal() and .json() to check if the .unmarshal() is working but the unmarshal is also not working as "emp.json" is not getting created.
If nothing happens at all when starting the route then it is most likely due to the relative path you passed to the file component. Probably the execution directory of your Java process is not where you think it is and the file is not found. To simplify things I suggest you start with an absolute path. Once everything else is working figure out the correct relative path (your base should be the value of the user.dir system property).
Re your question about splitting the contents: This is answered in the documentation.
This works for me (Camel 3.1):
public class CsvRouteBuilder extends EndpointRouteBuilder {
#Override
public void configure() {
DataFormat bindy = new BindyCsvDataFormat(BindyModel.class);
from(file("/tmp?fileName=simpsons.csv"))
.unmarshal(bindy)
.split(body())
.log("Unmarshalled model: ${body}")
.marshal().json()
.log("Marshalled to JSON: ${body}")
// Unique file name for the JSON output
.setHeader(Exchange.FILE_NAME, () -> UUID.randomUUID().toString() + ".json")
.to(file("/tmp"));
}
}
// Use lombok to generate all the boilerplate stuff
#ToString
#Getter
#Setter
#NoArgsConstructor
// Bindy record definition
#CsvRecord(separator = ";", skipFirstLine = true, crlf = "UNIX")
public static class BindyModel {
#DataField(pos = 1)
private String firstName;
#DataField(pos = 2)
private String middleName;
#DataField(pos = 3)
private String lastName;
}
Given this input in /tmp/simpsons.csv
firstname;middlename;lastname
Homer;Jay;Simpson
Marge;Jacqueline;Simpson
the log output looks like this
Unmarshalled model: RestRouteBuilder.BindyModel(firstName=Homer, middleName=Jay, lastName=Simpson)
Marshalled to JSON: {"firstName":"Homer","middleName":"Jay","lastName":"Simpson"}
Unmarshalled model: RestRouteBuilder.BindyModel(firstName=Marge, middleName=Jacqueline, lastName=Simpson)
Marshalled to JSON: {"firstName":"Marge","middleName":"Jacqueline","lastName":"Simpson"}
and two json files are written in /tmp.

JAX-RS Exception Mapper not working in Grizzly container

Working on a Jersey web application with a team, as the project got bigger and bigger, we decided to switch from Tomcat to Grizzly to allow deploying parts of the project on different port numbers. What I've found out now, that the custom exception handling we have fails to work now, instead I always get the grizzly html page.
Example exception:
public class DataNotFoundException extends RuntimeException{
private static final long serialVersionUID = -1622261264080480479L;
public DataNotFoundException(String message) {
super(message);
System.out.println("exception constructor called"); //this prints
}
}
Mapper:
#Provider
public class DataNotFoundExceptionMapper implements ExceptionMapper<DataNotFoundException>{
public DataNotFoundExceptionMapper() {
System.out.println("mapper constructor called"); //doesnt print
}
#Override
public Response toResponse(DataNotFoundException ex) {
System.out.println("toResponse called"); //doesnt print
ErrorMessage errorMessage = new ErrorMessage(ex.getMessage(), 404, "No documentation yet.");
return Response.status(Status.NOT_FOUND)
.entity(errorMessage)
.build();
//ErrorMessage is a simple POJO with 2 string and 1 int field
}
}
I'm not sure where is the problem source, if needed I can provide more information/code. What's the problem, what can I try?
EDIT:
Main.class:
public class Main {
/**
* Main method.
* #param args
* #throws Exception
*/
public static void main(String[] args) throws Exception {
...
List<ServerInfo> serverList = new ArrayList<ServerInfo>();
serverList.add(new ServerInfo(
"api",8450,
new ResourceConfig().registerClasses(
the.package.was.here.ApiResource.class)
));
for(ServerInfo server : serverList) {
server.start();
}
System.out.println("Press enter to exit...");
System.in.read();
for(ServerInfo server : serverList) {
server.stop();
}
}
}
EDIT2:
based on this question I've tried using this ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, "true"property, which only helped a little. I still get the html grizzly page when the exception happens, but now I see my exception (+stack trace) in the body of the page.
You're only registering one resource class for the entire application
new ResourceConfig().registerClasses(
eu.arrowhead.core.api.ApiResource.class
)
The mapper needs to be registered also
new ResourceConfig().registerClasses(
eu.arrowhead.core.api.ApiResource.class,
YourMapper.class)
)
You can also use package scanning, which will pick up all classes and automatically register them, if they are annotated with #Path or #Provider
new ResourceConfig().packages("the.packages.to.scan")

#ManagedBean issues getting relational data

I have this weird problem that throws not really useful errors. I'm trying to display data from Entity Bean in Primefaces table. I have two projects, one for front end, other one for backend. Thing is, the Entity Bean has #OneToMany and #ManyToOne relation, and they seem to cause the problems, because if I null them no errors happen, but I need that data so it's not a solution.
BACKEND:
Key parts of entity:
#Entity
#Table(name = "business_process_tasks")
public class BusinessProcessTasks implements java.io.Serializable {
....
#ManyToOne(fetch=FetchType.EAGER)
#JoinColumn(name="process")
public Process getProcess() {
return process;
}
public void setProcess(Process process) {
this.process = process;
}
#OneToMany(mappedBy = "processTask")
public List<BusinessProcessTasksMeta> getMeta() {
return meta;
}
public void setMeta(List<BusinessProcessTasksMeta> meta) {
this.meta = meta;
}
}
Key parts of EJB:
#Override
public List<BusinessProcessTasks> getList(int processId) {
EntityManager em = emf.createEntityManager();
String q = "SELECT t from " + BusinessProcessTasks.class.getName() + " t where process="+processId;
Query query = em.createQuery(q);
List<BusinessProcessTasks> items = query.getResultList();
for(int i = 0;i<items.size();i++){
BusinessProcessTasks t = (BusinessProcessTasks) items.get(i);
//IF I SET THESE TO NULL NO ERRORS SHOW
t.setProcess(null);
t.setMeta(null);
}
em.close();
return items;
}
FRONTEND:
Key parts of #ManagedBean:
#ManagedBean(name = "processTasksTableBean")
#ViewScoped
public class ProcessTasksTableBean {
.....
#PostConstruct
void initialiseSession() {
System.out.println("Bean running");
FacesContext.getCurrentInstance().getExternalContext().getSession(true);
//GETTING ID FROM URL
HttpServletRequest request = (HttpServletRequest) FacesContext
.getCurrentInstance().getExternalContext().getRequest();
pageProcessId = Integer.parseInt(request.getParameter("id"));
processTasksBeanRemote = doLookup();
//ONLY PLACE IN PROJECT WHERE ERROR IS REFERENCED IN CONSOLE IS HERE
processTasksList = processTasksBeanRemote.getList(pageProcessId);
}
.....
}
Eclipse console - log is very long, if required I will post it all, now just key parts:
09:34:58,377 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (http-localhost-127.0.0.1-8189-3) Error Rendering View[/ProcessTasks.xhtml]: java.lang.IllegalStateException: JBAS011048: Failed to construct component instance
Caused by: java.lang.RuntimeException: ClassNotFoundException marshaling EJB parameters
Caused by: java.lang.ClassNotFoundException: org.hibernate.collection.internal.PersistentBag from [Module "deployment.bpmweb.war:main" from Service Module Loader]
09:34:58,403 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/bpmweb].[Faces Servlet]] (http-localhost-127.0.0.1-8189-3) Servlet.service() for servlet Faces Servlet threw exception: java.lang.ClassNotFoundException: org.hibernate.collection.internal.PersistentBag from [Module "deployment.bpmweb.war:main" from Service Module Loader]
Issue resolved, I downloaded latest Hibernate core from http://mvnrepository.com/artifact/org.hibernate/hibernate-core/4.3.4.Final and all seems fine. Quite wierd, since I add my Jboss runtime libs to each project through build path.

Queries leading to data modification are not allowed grails

In my current application i have a service which uses a saxparser to read some xml. In saxparser i try to store a new objectto the database but i get the following error:
ERROR util.JDBCExceptionReporter - Connection is read-only. Queries leading to data modification are not allowed
My Service looks like so:
#Transactional
class SchedulingService {
def printIets() {
LessonParser par = new LessonParser()
print "de service macheert ier e trut"
par.parse(["src/data/tweede/"])
}
}
The parser:
class LessonParser {
public void parse(baseFileLocations){
....
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
LessonHandler handler = new LessonHandler()
saxParser.parse(is, handler);
...
}
}
And finally the handler where the attempt to save something to the database is made
class LessonHandler extends DefaultHandler{
#Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equalsIgnoreCase("TTSession")) {
//voorlopig enkel hoorcolleges
if (parse && this.courseType == CourseType.HC) {
Course course = new Course (name:this.name , info:this.info,courseType:this.courseType,creator:this.creator)
course.save()
}
}
}
}
The error occurs when i try to save a course in the above handler.
Also i'm using a mysql database
I had connected the service to a restful api, i forgot an #transactional definition there. Adding it did the trick
Thanks for sharing.
the service got a "#Transactional(readOnly = true)" definition. So all the methods will be read only.
If you want to do some modification, you need to add "#Transactional" before the method.